Commit c2df4e9d authored by Alexander Barkov's avatar Alexander Barkov

MDEV-16186 Concatenation operator || returns wrong results in sql_mode=ORACLE

parent 66360506
...@@ -46,3 +46,73 @@ t1 CREATE TABLE `t1` ( ...@@ -46,3 +46,73 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`i`) PRIMARY KEY (`i`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-16186 Concatenation operator || returns wrong results in sql_mode=ORACLE
#
SET sql_mode=ANSI;
SELECT -1<<1||1 AS a FROM DUAL;
a
18446744073709549568
SELECT -1||0<<1 AS a FROM DUAL;
a
18446744073709551596
EXPLAIN EXTENDED SELECT -1<<1||1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select -1 << concat(1,1) AS "a"
EXPLAIN EXTENDED SELECT -1||0<<1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select concat(-1,0) << 1 AS "a"
SELECT -1+1||1 AS a FROM DUAL;
a
10
SELECT -1||0+1 AS a FROM DUAL;
a
-9
EXPLAIN EXTENDED SELECT -1+1||1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select -1 + concat(1,1) AS "a"
EXPLAIN EXTENDED SELECT -1||0+1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select concat(-1,0) + 1 AS "a"
SELECT 1*1||-1 AS a FROM DUAL;
a
1
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: '1-1'
SELECT 1||1*-1 AS a FROM DUAL;
a
-11
EXPLAIN EXTENDED SELECT 1*1||-1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select 1 * concat(1,-1) AS "a"
EXPLAIN EXTENDED SELECT 1||1*-1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select concat(1,1) * -1 AS "a"
SELECT -1^1||1 AS a FROM DUAL;
a
18446744073709551604
SELECT -1||0^1 AS a FROM DUAL;
a
18446744073709551607
EXPLAIN EXTENDED SELECT -1^1||1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select -1 ^ concat(1,1) AS "a"
EXPLAIN EXTENDED SELECT -1||0^1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select concat(-1,0) ^ 1 AS "a"
...@@ -39,3 +39,36 @@ SHOW CREATE TABLE t1; ...@@ -39,3 +39,36 @@ SHOW CREATE TABLE t1;
DROP TABLE t1; DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
--echo #
--echo # MDEV-16186 Concatenation operator || returns wrong results in sql_mode=ORACLE
--echo #
SET sql_mode=ANSI;
# Concatenation operator || is stronger than numeric dyadic operators ^ * + <<
SELECT -1<<1||1 AS a FROM DUAL;
SELECT -1||0<<1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1<<1||1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1||0<<1 AS a FROM DUAL;
SELECT -1+1||1 AS a FROM DUAL;
SELECT -1||0+1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1+1||1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1||0+1 AS a FROM DUAL;
SELECT 1*1||-1 AS a FROM DUAL;
SELECT 1||1*-1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT 1*1||-1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT 1||1*-1 AS a FROM DUAL;
SELECT -1^1||1 AS a FROM DUAL;
SELECT -1||0^1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1^1||1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1||0^1 AS a FROM DUAL;
...@@ -255,3 +255,70 @@ SELECT * FROM v1; ...@@ -255,3 +255,70 @@ SELECT * FROM v1;
test test
1 1
DROP VIEW v1; DROP VIEW v1;
#
# MDEV-16186 Concatenation operator || returns wrong results in sql_mode=ORACLE
#
SELECT -1<<1||1 AS a FROM DUAL;
a
18446744073709549568
SELECT -1||0<<1 AS a FROM DUAL;
a
18446744073709551596
EXPLAIN EXTENDED SELECT -1<<1||1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select -1 << concat_operator_oracle(1,1) AS "a"
EXPLAIN EXTENDED SELECT -1||0<<1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select concat_operator_oracle(-1,0) << 1 AS "a"
SELECT -1+1||1 AS a FROM DUAL;
a
01
SELECT -1||0+1 AS a FROM DUAL;
a
-9
EXPLAIN EXTENDED SELECT -1+1||1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select concat_operator_oracle(-1 + 1,1) AS "a"
EXPLAIN EXTENDED SELECT -1||0+1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select concat_operator_oracle(-1,0) + 1 AS "a"
SELECT 1*1||-1 AS a FROM DUAL;
a
1-1
SELECT 1||1*-1 AS a FROM DUAL;
a
1-1
EXPLAIN EXTENDED SELECT 1*1||-1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select concat_operator_oracle(1 * 1,-1) AS "a"
EXPLAIN EXTENDED SELECT 1||1*-1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select concat_operator_oracle(1,1 * -1) AS "a"
SELECT -1^1||1 AS a FROM DUAL;
a
184467440737095516141
SELECT -1||0^1 AS a FROM DUAL;
a
-11
EXPLAIN EXTENDED SELECT -1^1||1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select concat_operator_oracle(-1 ^ 1,1) AS "a"
EXPLAIN EXTENDED SELECT -1||0^1 AS a FROM DUAL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select concat_operator_oracle(-1,0 ^ 1) AS "a"
...@@ -114,3 +114,35 @@ SET sql_mode=ORACLE; ...@@ -114,3 +114,35 @@ SET sql_mode=ORACLE;
SHOW CREATE VIEW v1; SHOW CREATE VIEW v1;
SELECT * FROM v1; SELECT * FROM v1;
DROP VIEW v1; DROP VIEW v1;
--echo #
--echo # MDEV-16186 Concatenation operator || returns wrong results in sql_mode=ORACLE
--echo #
# Concatenation operator || has the same precedence with +
# (stronger than << and weaker than * ^)
SELECT -1<<1||1 AS a FROM DUAL;
SELECT -1||0<<1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1<<1||1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1||0<<1 AS a FROM DUAL;
SELECT -1+1||1 AS a FROM DUAL;
SELECT -1||0+1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1+1||1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1||0+1 AS a FROM DUAL;
SELECT 1*1||-1 AS a FROM DUAL;
SELECT 1||1*-1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT 1*1||-1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT 1||1*-1 AS a FROM DUAL;
SELECT -1^1||1 AS a FROM DUAL;
SELECT -1||0^1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1^1||1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1||0^1 AS a FROM DUAL;
...@@ -722,7 +722,7 @@ static SYMBOL symbols[] = { ...@@ -722,7 +722,7 @@ static SYMBOL symbols[] = {
{ "YEAR", SYM(YEAR_SYM)}, { "YEAR", SYM(YEAR_SYM)},
{ "YEAR_MONTH", SYM(YEAR_MONTH_SYM)}, { "YEAR_MONTH", SYM(YEAR_MONTH_SYM)},
{ "ZEROFILL", SYM(ZEROFILL)}, { "ZEROFILL", SYM(ZEROFILL)},
{ "||", SYM(OR_OR_SYM)} { "||", SYM(OR2_SYM)}
}; };
......
...@@ -839,9 +839,12 @@ int Lex_input_stream::find_keyword(Lex_ident_cli_st *kwd, ...@@ -839,9 +839,12 @@ int Lex_input_stream::find_keyword(Lex_ident_cli_st *kwd,
if ((symbol->tok == NOT_SYM) && if ((symbol->tok == NOT_SYM) &&
(m_thd->variables.sql_mode & MODE_HIGH_NOT_PRECEDENCE)) (m_thd->variables.sql_mode & MODE_HIGH_NOT_PRECEDENCE))
return NOT2_SYM; return NOT2_SYM;
if ((symbol->tok == OR_OR_SYM) && if ((symbol->tok == OR2_SYM) &&
!(m_thd->variables.sql_mode & MODE_PIPES_AS_CONCAT)) (m_thd->variables.sql_mode & MODE_PIPES_AS_CONCAT))
return OR2_SYM; {
return (m_thd->variables.sql_mode & MODE_ORACLE) ?
ORACLE_CONCAT_SYM : MYSQL_CONCAT_SYM;
}
return symbol->tok; return symbol->tok;
} }
......
...@@ -892,10 +892,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -892,10 +892,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd } %parse-param { THD *thd }
%lex-param { THD *thd } %lex-param { THD *thd }
/* /*
Currently there are 127 shift/reduce conflicts. Currently there are 122 shift/reduce conflicts.
We should not introduce new conflicts any more. We should not introduce new conflicts any more.
*/ */
%expect 127 %expect 122
/* /*
Comments for TOKENS. Comments for TOKENS.
...@@ -1073,6 +1073,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1073,6 +1073,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token MIN_SYM /* SQL-2003-N */ %token MIN_SYM /* SQL-2003-N */
%token MODIFIES_SYM /* SQL-2003-R */ %token MODIFIES_SYM /* SQL-2003-R */
%token MOD_SYM /* SQL-2003-N */ %token MOD_SYM /* SQL-2003-N */
%token MYSQL_CONCAT_SYM /* OPERATOR */
%token NATURAL /* SQL-2003-R */ %token NATURAL /* SQL-2003-R */
%token NCHAR_STRING %token NCHAR_STRING
%token NE /* OPERATOR */ %token NE /* OPERATOR */
...@@ -1089,9 +1090,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1089,9 +1090,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token ON /* SQL-2003-R */ %token ON /* SQL-2003-R */
%token OPTIMIZE %token OPTIMIZE
%token OPTIONALLY %token OPTIONALLY
%token ORACLE_CONCAT_SYM /* INTERNAL */
%token OR2_SYM %token OR2_SYM
%token ORDER_SYM /* SQL-2003-R */ %token ORDER_SYM /* SQL-2003-R */
%token OR_OR_SYM /* OPERATOR */
%token OR_SYM /* SQL-2003-R */ %token OR_SYM /* SQL-2003-R */
%token OUTER %token OUTER
%token OUTFILE %token OUTFILE
...@@ -1654,7 +1655,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1654,7 +1655,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
/* A dummy token to force the priority of table_ref production in a join. */ /* A dummy token to force the priority of table_ref production in a join. */
%left TABLE_REF_PRIORITY %left TABLE_REF_PRIORITY
%left SET_VAR %left SET_VAR
%left OR_OR_SYM OR_SYM OR2_SYM %left OR_SYM OR2_SYM
%left XOR %left XOR
%left AND_SYM AND_AND_SYM %left AND_SYM AND_AND_SYM
%left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE %left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE
...@@ -1662,9 +1663,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1662,9 +1663,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%left '|' %left '|'
%left '&' %left '&'
%left SHIFT_LEFT SHIFT_RIGHT %left SHIFT_LEFT SHIFT_RIGHT
%left '-' '+' %left '-' '+' ORACLE_CONCAT_SYM
%left '*' '/' '%' DIV_SYM MOD_SYM %left '*' '/' '%' DIV_SYM MOD_SYM
%left '^' %left '^'
%left MYSQL_CONCAT_SYM
%left NEG '~' %left NEG '~'
%right NOT_SYM NOT2_SYM %right NOT_SYM NOT2_SYM
%right BINARY COLLATE_SYM %right BINARY COLLATE_SYM
...@@ -1803,6 +1805,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1803,6 +1805,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
variable variable_aux bool_pri variable variable_aux bool_pri
predicate bit_expr parenthesized_expr predicate bit_expr parenthesized_expr
table_wild simple_expr column_default_non_parenthesized_expr udf_expr table_wild simple_expr column_default_non_parenthesized_expr udf_expr
primary_expr string_factor_expr mysql_concatenation_expr
select_sublist_qualified_asterisk select_sublist_qualified_asterisk
expr_or_default set_expr_or_default expr_or_default set_expr_or_default
geometry_function signed_literal expr_or_literal geometry_function signed_literal expr_or_literal
...@@ -2056,8 +2059,9 @@ END_OF_INPUT ...@@ -2056,8 +2059,9 @@ END_OF_INPUT
%type <NONE> %type <NONE>
'-' '+' '*' '/' '%' '(' ')' '-' '+' '*' '/' '%' '(' ')'
',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM BETWEEN_SYM CASE_SYM
THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM
MYSQL_CONCAT_SYM ORACLE_CONCAT_SYM
%type <with_clause> opt_with_clause with_clause %type <with_clause> opt_with_clause with_clause
...@@ -9697,14 +9701,14 @@ predicate: ...@@ -9697,14 +9701,14 @@ predicate:
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| bit_expr LIKE simple_expr opt_escape | bit_expr LIKE mysql_concatenation_expr opt_escape
{ {
$$= new (thd->mem_root) Item_func_like(thd, $1, $3, $4, $$= new (thd->mem_root) Item_func_like(thd, $1, $3, $4,
Lex->escape_used); Lex->escape_used);
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| bit_expr not LIKE simple_expr opt_escape | bit_expr not LIKE mysql_concatenation_expr opt_escape
{ {
Item *item= new (thd->mem_root) Item_func_like(thd, $1, $4, $5, Item *item= new (thd->mem_root) Item_func_like(thd, $1, $4, $5,
Lex->escape_used); Lex->escape_used);
...@@ -9755,6 +9759,13 @@ bit_expr: ...@@ -9755,6 +9759,13 @@ bit_expr:
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| bit_expr ORACLE_CONCAT_SYM bit_expr
{
$$= new (thd->mem_root) Item_func_concat_operator_oracle(thd,
$1, $3);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
| bit_expr '+' bit_expr %prec '+' | bit_expr '+' bit_expr %prec '+'
{ {
$$= new (thd->mem_root) Item_func_plus(thd, $1, $3); $$= new (thd->mem_root) Item_func_plus(thd, $1, $3);
...@@ -9834,7 +9845,7 @@ bit_expr: ...@@ -9834,7 +9845,7 @@ bit_expr:
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| simple_expr | mysql_concatenation_expr %prec '^'
; ;
or: or:
...@@ -10113,26 +10124,28 @@ column_default_non_parenthesized_expr: ...@@ -10113,26 +10124,28 @@ column_default_non_parenthesized_expr:
} }
; ;
simple_expr: primary_expr:
column_default_non_parenthesized_expr column_default_non_parenthesized_expr
| simple_expr COLLATE_SYM collation_name %prec NEG | '(' parenthesized_expr ')' { $$= $2; }
;
string_factor_expr:
primary_expr
| string_factor_expr COLLATE_SYM collation_name
{ {
if (unlikely(!($$= new (thd->mem_root) Item_func_set_collation(thd, $1, $3)))) if (unlikely(!($$= new (thd->mem_root) Item_func_set_collation(thd, $1, $3))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| '(' parenthesized_expr ')' { $$= $2; } ;
| BINARY simple_expr %prec NEG
simple_expr:
string_factor_expr %prec NEG
| BINARY simple_expr
{ {
Type_cast_attributes at(&my_charset_bin); Type_cast_attributes at(&my_charset_bin);
if (unlikely(!($$= type_handler_long_blob.create_typecast_item(thd, $2, at)))) if (unlikely(!($$= type_handler_long_blob.create_typecast_item(thd, $2, at))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| simple_expr OR_OR_SYM simple_expr
{
$$= new (thd->mem_root) Item_func_concat(thd, $1, $3);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
| '+' simple_expr %prec NEG | '+' simple_expr %prec NEG
{ {
$$= $2; $$= $2;
...@@ -10157,6 +10170,16 @@ simple_expr: ...@@ -10157,6 +10170,16 @@ simple_expr:
} }
; ;
mysql_concatenation_expr:
simple_expr
| mysql_concatenation_expr MYSQL_CONCAT_SYM simple_expr
{
$$= new (thd->mem_root) Item_func_concat(thd, $1, $3);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
;
function_call_keyword_timestamp: function_call_keyword_timestamp:
TIMESTAMP '(' expr ')' TIMESTAMP '(' expr ')'
{ {
......
...@@ -278,10 +278,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -278,10 +278,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd } %parse-param { THD *thd }
%lex-param { THD *thd } %lex-param { THD *thd }
/* /*
Currently there are 104 shift/reduce conflicts. Currently there are 99 shift/reduce conflicts.
We should not introduce new conflicts any more. We should not introduce new conflicts any more.
*/ */
%expect 104 %expect 99
/* /*
Comments for TOKENS. Comments for TOKENS.
...@@ -459,6 +459,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -459,6 +459,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token MIN_SYM /* SQL-2003-N */ %token MIN_SYM /* SQL-2003-N */
%token MODIFIES_SYM /* SQL-2003-R */ %token MODIFIES_SYM /* SQL-2003-R */
%token MOD_SYM /* SQL-2003-N */ %token MOD_SYM /* SQL-2003-N */
%token MYSQL_CONCAT_SYM /* OPERATOR */
%token NATURAL /* SQL-2003-R */ %token NATURAL /* SQL-2003-R */
%token NCHAR_STRING %token NCHAR_STRING
%token NE /* OPERATOR */ %token NE /* OPERATOR */
...@@ -475,9 +476,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -475,9 +476,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token ON /* SQL-2003-R */ %token ON /* SQL-2003-R */
%token OPTIMIZE %token OPTIMIZE
%token OPTIONALLY %token OPTIONALLY
%token ORACLE_CONCAT_SYM /* INTERNAL */
%token OR2_SYM %token OR2_SYM
%token ORDER_SYM /* SQL-2003-R */ %token ORDER_SYM /* SQL-2003-R */
%token OR_OR_SYM /* OPERATOR */
%token OR_SYM /* SQL-2003-R */ %token OR_SYM /* SQL-2003-R */
%token OUTER %token OUTER
%token OUTFILE %token OUTFILE
...@@ -1040,7 +1041,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1040,7 +1041,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
/* A dummy token to force the priority of table_ref production in a join. */ /* A dummy token to force the priority of table_ref production in a join. */
%left TABLE_REF_PRIORITY %left TABLE_REF_PRIORITY
%left SET_VAR %left SET_VAR
%left OR_OR_SYM OR_SYM OR2_SYM %left OR_SYM OR2_SYM
%left XOR %left XOR
%left AND_SYM AND_AND_SYM %left AND_SYM AND_AND_SYM
%left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE %left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE
...@@ -1048,9 +1049,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1048,9 +1049,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%left '|' %left '|'
%left '&' %left '&'
%left SHIFT_LEFT SHIFT_RIGHT %left SHIFT_LEFT SHIFT_RIGHT
%left '-' '+' %left '-' '+' ORACLE_CONCAT_SYM
%left '*' '/' DIV_SYM MOD_SYM %left '*' '/' DIV_SYM MOD_SYM
%left '^' %left '^'
%left MYSQL_CONCAT_SYM
%left NEG '~' %left NEG '~'
%right NOT_SYM NOT2_SYM %right NOT_SYM NOT2_SYM
%right BINARY COLLATE_SYM %right BINARY COLLATE_SYM
...@@ -1196,6 +1198,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1196,6 +1198,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
variable variable_aux bool_pri variable variable_aux bool_pri
predicate bit_expr parenthesized_expr predicate bit_expr parenthesized_expr
table_wild simple_expr column_default_non_parenthesized_expr udf_expr table_wild simple_expr column_default_non_parenthesized_expr udf_expr
primary_expr string_factor_expr mysql_concatenation_expr
select_sublist_qualified_asterisk select_sublist_qualified_asterisk
expr_or_default set_expr_or_default expr_or_default set_expr_or_default
geometry_function signed_literal expr_or_literal geometry_function signed_literal expr_or_literal
...@@ -1469,8 +1472,9 @@ END_OF_INPUT ...@@ -1469,8 +1472,9 @@ END_OF_INPUT
%type <NONE> %type <NONE>
'-' '+' '*' '/' '%' '(' ')' '-' '+' '*' '/' '%' '(' ')'
',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM BETWEEN_SYM CASE_SYM
THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM
MYSQL_CONCAT_SYM ORACLE_CONCAT_SYM
%type <with_clause> opt_with_clause with_clause %type <with_clause> opt_with_clause with_clause
...@@ -9443,14 +9447,14 @@ predicate: ...@@ -9443,14 +9447,14 @@ predicate:
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| bit_expr LIKE simple_expr opt_escape | bit_expr LIKE mysql_concatenation_expr opt_escape
{ {
$$= new (thd->mem_root) Item_func_like(thd, $1, $3, $4, $$= new (thd->mem_root) Item_func_like(thd, $1, $3, $4,
Lex->escape_used); Lex->escape_used);
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| bit_expr not LIKE simple_expr opt_escape | bit_expr not LIKE mysql_concatenation_expr opt_escape
{ {
Item *item= new (thd->mem_root) Item_func_like(thd, $1, $4, $5, Item *item= new (thd->mem_root) Item_func_like(thd, $1, $4, $5,
Lex->escape_used); Lex->escape_used);
...@@ -9501,6 +9505,13 @@ bit_expr: ...@@ -9501,6 +9505,13 @@ bit_expr:
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| bit_expr ORACLE_CONCAT_SYM bit_expr
{
$$= new (thd->mem_root) Item_func_concat_operator_oracle(thd,
$1, $3);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
| bit_expr '+' bit_expr %prec '+' | bit_expr '+' bit_expr %prec '+'
{ {
$$= new (thd->mem_root) Item_func_plus(thd, $1, $3); $$= new (thd->mem_root) Item_func_plus(thd, $1, $3);
...@@ -9574,7 +9585,7 @@ bit_expr: ...@@ -9574,7 +9585,7 @@ bit_expr:
if (unlikely($$ == NULL)) if (unlikely($$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| simple_expr | mysql_concatenation_expr %prec '^'
; ;
or: or:
...@@ -9909,28 +9920,29 @@ column_default_non_parenthesized_expr: ...@@ -9909,28 +9920,29 @@ column_default_non_parenthesized_expr:
} }
; ;
simple_expr: primary_expr:
column_default_non_parenthesized_expr column_default_non_parenthesized_expr
| explicit_cursor_attr | explicit_cursor_attr
| simple_expr COLLATE_SYM collation_name %prec NEG | '(' parenthesized_expr ')' { $$= $2; }
;
string_factor_expr:
primary_expr
| string_factor_expr COLLATE_SYM collation_name
{ {
if (unlikely(!($$= new (thd->mem_root) Item_func_set_collation(thd, $1, $3)))) if (unlikely(!($$= new (thd->mem_root) Item_func_set_collation(thd, $1, $3))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| '(' parenthesized_expr ')' { $$= $2; } ;
| BINARY simple_expr %prec NEG
simple_expr:
string_factor_expr %prec NEG
| BINARY simple_expr
{ {
Type_cast_attributes at(&my_charset_bin); Type_cast_attributes at(&my_charset_bin);
if (unlikely(!($$= type_handler_long_blob.create_typecast_item(thd, $2, at)))) if (unlikely(!($$= type_handler_long_blob.create_typecast_item(thd, $2, at))))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
| simple_expr OR_OR_SYM simple_expr
{
$$= new (thd->mem_root) Item_func_concat_operator_oracle(thd,
$1, $3);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
| '+' simple_expr %prec NEG | '+' simple_expr %prec NEG
{ {
$$= $2; $$= $2;
...@@ -9955,6 +9967,17 @@ simple_expr: ...@@ -9955,6 +9967,17 @@ simple_expr:
} }
; ;
mysql_concatenation_expr:
simple_expr
| mysql_concatenation_expr MYSQL_CONCAT_SYM simple_expr
{
$$= new (thd->mem_root) Item_func_concat(thd, $1, $3);
if (unlikely($$ == NULL))
MYSQL_YYABORT;
}
;
/* /*
Function call syntax using official SQL 2003 keywords. Function call syntax using official SQL 2003 keywords.
Because the function name is an official token, Because the function name is an official token,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment