Skip to content

Commit

Permalink
MDEV-16186 Concatenation operator || returns wrong results in sql_mod…
Browse files Browse the repository at this point in the history
…e=ORACLE
  • Loading branch information
abarkov committed May 16, 2018
1 parent 6636050 commit c2df4e9
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 43 deletions.
70 changes: 70 additions & 0 deletions mysql-test/main/ansi.result
Expand Up @@ -46,3 +46,73 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`i`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
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"
33 changes: 33 additions & 0 deletions mysql-test/main/ansi.test
Expand Up @@ -39,3 +39,36 @@ SHOW CREATE TABLE t1;
DROP TABLE t1;

# 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;
67 changes: 67 additions & 0 deletions mysql-test/suite/compat/oracle/r/func_concat.result
Expand Up @@ -255,3 +255,70 @@ SELECT * FROM v1;
test
1
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"
32 changes: 32 additions & 0 deletions mysql-test/suite/compat/oracle/t/func_concat.test
Expand Up @@ -114,3 +114,35 @@ SET sql_mode=ORACLE;
SHOW CREATE VIEW v1;
SELECT * FROM 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;
2 changes: 1 addition & 1 deletion sql/lex.h
Expand Up @@ -722,7 +722,7 @@ static SYMBOL symbols[] = {
{ "YEAR", SYM(YEAR_SYM)},
{ "YEAR_MONTH", SYM(YEAR_MONTH_SYM)},
{ "ZEROFILL", SYM(ZEROFILL)},
{ "||", SYM(OR_OR_SYM)}
{ "||", SYM(OR2_SYM)}
};


Expand Down
9 changes: 6 additions & 3 deletions sql/sql_lex.cc
Expand Up @@ -839,9 +839,12 @@ int Lex_input_stream::find_keyword(Lex_ident_cli_st *kwd,
if ((symbol->tok == NOT_SYM) &&
(m_thd->variables.sql_mode & MODE_HIGH_NOT_PRECEDENCE))
return NOT2_SYM;
if ((symbol->tok == OR_OR_SYM) &&
!(m_thd->variables.sql_mode & MODE_PIPES_AS_CONCAT))
return OR2_SYM;
if ((symbol->tok == OR2_SYM) &&
(m_thd->variables.sql_mode & MODE_PIPES_AS_CONCAT))
{
return (m_thd->variables.sql_mode & MODE_ORACLE) ?
ORACLE_CONCAT_SYM : MYSQL_CONCAT_SYM;
}

return symbol->tok;
}
Expand Down

0 comments on commit c2df4e9

Please sign in to comment.