diff options
author | unknown <malff/marcsql@weblab.(none)> | 2007-09-04 14:38:26 -0600 |
---|---|---|
committer | unknown <malff/marcsql@weblab.(none)> | 2007-09-04 14:38:26 -0600 |
commit | 3a94137ce00681c1abe92ad5590a3604ef90a07d (patch) | |
tree | ce61ac78cd97b8f62c48e42f8db16b9a148f7d86 | |
parent | 7cafddc3454e60a95ef1f7059d3b5954a1e4d1b6 (diff) | |
parent | 0f70a032c2b5ae22f92f70b125775447a220fa5e (diff) | |
download | mariadb-git-3a94137ce00681c1abe92ad5590a3604ef90a07d.tar.gz |
Merge weblab.(none):/home/marcsql/TREE/mysql-5.0-base
into weblab.(none):/home/marcsql/TREE/mysql-5.0-rt-merge
mysql-test/r/sp.result:
Auto merged
mysql-test/t/mysql.test:
Auto merged
mysql-test/t/sp.test:
Auto merged
-rwxr-xr-x | BUILD/SETUP.sh | 25 | ||||
-rwxr-xr-x | BUILD/compile-amd64-gcov | 17 | ||||
-rwxr-xr-x | BUILD/compile-amd64-gprof | 9 | ||||
-rwxr-xr-x | BUILD/compile-pentium-gcov | 13 | ||||
-rwxr-xr-x | BUILD/compile-pentium-gprof | 4 | ||||
-rwxr-xr-x | BUILD/compile-pentium64-gcov | 17 | ||||
-rwxr-xr-x | BUILD/compile-pentium64-gprof | 9 | ||||
-rw-r--r-- | client/mysql.cc | 54 | ||||
-rw-r--r-- | mysql-test/r/comments.result | 15 | ||||
-rw-r--r-- | mysql-test/r/handler.result | 13 | ||||
-rw-r--r-- | mysql-test/r/innodb-deadlock.result | 11 | ||||
-rw-r--r-- | mysql-test/r/mysql.result | 2 | ||||
-rw-r--r-- | mysql-test/r/parser_precedence.result | 747 | ||||
-rw-r--r-- | mysql-test/r/sp.result | 52 | ||||
-rw-r--r-- | mysql-test/t/comments.test | 33 | ||||
-rw-r--r-- | mysql-test/t/handler.test | 19 | ||||
-rw-r--r-- | mysql-test/t/innodb-deadlock.test | 27 | ||||
-rw-r--r-- | mysql-test/t/mysql.test | 5 | ||||
-rw-r--r-- | mysql-test/t/parser_precedence.test | 333 | ||||
-rw-r--r-- | mysql-test/t/sp.test | 54 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 18 | ||||
-rw-r--r-- | sql/lock.cc | 2 | ||||
-rw-r--r-- | sql/sql_cache.cc | 31 | ||||
-rw-r--r-- | sql/sql_handler.cc | 6 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 37 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 247 |
27 files changed, 1661 insertions, 141 deletions
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 10324c22e56..532ea4eb0f1 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -138,3 +138,28 @@ then echo "$CC" | grep "ccache" > /dev/null || CC="ccache $CC" echo "$CXX" | grep "ccache" > /dev/null || CXX="ccache $CXX" fi + +# gcov + +# The -fprofile-arcs and -ftest-coverage options cause GCC to instrument the +# code with profiling information used by gcov. +# The -DDISABLE_TAO_ASM is needed to avoid build failures in Yassl. +# The -DHAVE_gcov enables code to write out coverage info even when crashing. + +gcov_compile_flags="-fprofile-arcs -ftest-coverage" +gcov_compile_flags="$gcov_compile_flags -DDISABLE_TAO_ASM" +gcov_compile_flags="$gcov_compile_flags -DMYSQL_SERVER_SUFFIX=-gcov -DHAVE_gcov" + +# GCC4 needs -fprofile-arcs -ftest-coverage on the linker command line (as well +# as on the compiler command line), and this requires setting LDFLAGS for BDB. + +gcov_link_flags="-fprofile-arcs -ftest-coverage" + +gcov_configs="--disable-shared" + +# gprof + +gprof_compile_flags="-O2 -pg -g" + +gprof_link_flags="--disable-shared $static_link" + diff --git a/BUILD/compile-amd64-gcov b/BUILD/compile-amd64-gcov new file mode 100755 index 00000000000..239a4aed0fb --- /dev/null +++ b/BUILD/compile-amd64-gcov @@ -0,0 +1,17 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" + +# Need to disable ccache, or we loose the gcov-needed compiler output files. +CCACHE_DISABLE=1 +export CCACHE_DISABLE + +export LDFLAGS="$gcov_link_flags" + +extra_flags="$amd64_cflags $debug_cflags $max_cflags $gcov_compile_flags" +c_warnings="$c_warnings $debug_extra_warnings" +cxx_warnings="$cxx_warnings $debug_extra_warnings" +extra_configs="$amd64_configs $debug_configs $gcov_configs $max_configs" + +. "$path/FINISH.sh" diff --git a/BUILD/compile-amd64-gprof b/BUILD/compile-amd64-gprof new file mode 100755 index 00000000000..6cfb8a4302c --- /dev/null +++ b/BUILD/compile-amd64-gprof @@ -0,0 +1,9 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" + +extra_flags="$amd64_cflags $gprof_compile_flags" +extra_configs="$amd64_configs $debug_configs $gprof_link_flags" + +. "$path/FINISH.sh" diff --git a/BUILD/compile-pentium-gcov b/BUILD/compile-pentium-gcov index 0d561d5b147..d4878dc591e 100755 --- a/BUILD/compile-pentium-gcov +++ b/BUILD/compile-pentium-gcov @@ -7,18 +7,11 @@ path=`dirname $0` CCACHE_DISABLE=1 export CCACHE_DISABLE -# GCC4 needs -fprofile-arcs -ftest-coverage on the linker command line (as well -# as on the compiler command line), and this requires setting LDFLAGS for BDB. -export LDFLAGS="-fprofile-arcs -ftest-coverage" +export LDFLAGS="$gcov_link_flags" -# The -fprofile-arcs and -ftest-coverage options cause GCC to instrument the -# code with profiling information used by gcov. -# The -DDISABLE_TAO_ASM is needed to avoid build failures in Yassl. -# The -DHAVE_gcov enables code to write out coverage info even when crashing. -extra_flags="$pentium_cflags -fprofile-arcs -ftest-coverage -DDISABLE_TAO_ASM $debug_cflags $max_cflags -DMYSQL_SERVER_SUFFIX=-gcov -DHAVE_gcov" +extra_flags="$pentium_cflags $debug_cflags $max_cflags $gcov_compile_flags" c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" -extra_configs="$pentium_configs $debug_configs --disable-shared $static_link" -extra_configs="$extra_configs $max_configs" +extra_configs="$pentium_configs $debug_configs $gcov_configs $max_configs" . "$path/FINISH.sh" diff --git a/BUILD/compile-pentium-gprof b/BUILD/compile-pentium-gprof index aa74de0b1b2..4aebc1d2e02 100755 --- a/BUILD/compile-pentium-gprof +++ b/BUILD/compile-pentium-gprof @@ -3,7 +3,7 @@ path=`dirname $0` . "$path/SETUP.sh" -extra_flags="$pentium_cflags -O2 -pg -g" -extra_configs="$pentium_configs $debug_configs --disable-shared $static_link" +extra_flags="$pentium_cflags $gprof_compile_flags" +extra_configs="$pentium_configs $debug_configs $gprof_link_flags" . "$path/FINISH.sh" diff --git a/BUILD/compile-pentium64-gcov b/BUILD/compile-pentium64-gcov new file mode 100755 index 00000000000..5a99b7f8796 --- /dev/null +++ b/BUILD/compile-pentium64-gcov @@ -0,0 +1,17 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" + +# Need to disable ccache, or we loose the gcov-needed compiler output files. +CCACHE_DISABLE=1 +export CCACHE_DISABLE + +export LDFLAGS="$gcov_link_flags" + +extra_flags="$pentium64_cflags $debug_cflags $max_cflags $gcov_compile_flags" +c_warnings="$c_warnings $debug_extra_warnings" +cxx_warnings="$cxx_warnings $debug_extra_warnings" +extra_configs="$pentium64_configs $debug_configs $gcov_configs $max_configs" + +. "$path/FINISH.sh" diff --git a/BUILD/compile-pentium64-gprof b/BUILD/compile-pentium64-gprof new file mode 100755 index 00000000000..f64dee6d196 --- /dev/null +++ b/BUILD/compile-pentium64-gprof @@ -0,0 +1,9 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" + +extra_flags="$pentium64_cflags $gprof_compile_flags" +extra_configs="$pentium64_configs $debug_configs $gprof_link_flags" + +. "$path/FINISH.sh" diff --git a/client/mysql.cc b/client/mysql.cc index 277b56328a6..8e1b6c2a9b4 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1245,6 +1245,7 @@ static bool add_line(String &buffer,char *line,char *in_string, char buff[80], *pos, *out; COMMANDS *com; bool need_space= 0; + bool ss_comment= 0; DBUG_ENTER("add_line"); if (!line[0] && buffer.is_empty()) @@ -1293,22 +1294,36 @@ static bool add_line(String &buffer,char *line,char *in_string, } if ((com=find_command(NullS,(char) inchar))) { - const String tmp(line,(uint) (out-line), charset_info); - buffer.append(tmp); - if ((*com->func)(&buffer,pos-1) > 0) - DBUG_RETURN(1); // Quit - if (com->takes_params) - { - for (pos++ ; - *pos && (*pos != *delimiter || - !is_prefix(pos + 1, delimiter + 1)) ; pos++) - ; // Remove parameters - if (!*pos) - pos--; - else - pos+= delimiter_length - 1; // Point at last delim char - } - out=line; + const String tmp(line,(uint) (out-line), charset_info); + buffer.append(tmp); + if ((*com->func)(&buffer,pos-1) > 0) + DBUG_RETURN(1); // Quit + if (com->takes_params) + { + if (ss_comment) + { + /* + If a client-side macro appears inside a server-side comment, + discard all characters in the comment after the macro (that is, + until the end of the comment rather than the next delimiter) + */ + for (pos++; *pos && (*pos != '*' || *(pos + 1) != '/'); pos++) + ; + pos--; + } + else + { + for (pos++ ; + *pos && (*pos != *delimiter || + !is_prefix(pos + 1, delimiter + 1)) ; pos++) + ; // Remove parameters + if (!*pos) + pos--; + else + pos+= delimiter_length - 1; // Point at last delim char + } + } + out=line; } else { @@ -1368,7 +1383,7 @@ static bool add_line(String &buffer,char *line,char *in_string, out=line; } } - else if (*ml_comment && inchar == '*' && *(pos + 1) == '/') + else if (*ml_comment && !ss_comment && inchar == '*' && *(pos + 1) == '/') { pos++; *ml_comment= 0; @@ -1376,6 +1391,11 @@ static bool add_line(String &buffer,char *line,char *in_string, } else { // Add found char to buffer + if (!*in_string && inchar == '/' && *(pos + 1) == '*' && + *(pos + 2) == '!') + ss_comment= 1; + else if (!*in_string && ss_comment && inchar == '*' && *(pos + 1) == '/') + ss_comment= 0; if (inchar == *in_string) *in_string= 0; else if (!*ml_comment && !*in_string && diff --git a/mysql-test/r/comments.result b/mysql-test/r/comments.result index a9106ce0538..1040c3fc8e9 100644 --- a/mysql-test/r/comments.result +++ b/mysql-test/r/comments.result @@ -26,3 +26,18 @@ select 1 # The rest of the row will be ignored 1 1 /* line with only comment */; +drop table if exists table_28779; +create table table_28779 (a int); +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';"; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*' AND b = 'bar'' at line 1 +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';*"; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*' AND b = 'bar';*' at line 1 +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;"; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;*"; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ';*' at line 1 +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';"; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*!98765' AND b = 'bar'' at line 1 +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';*"; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*!98765' AND b = 'bar';*' at line 1 +drop table table_28779; diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index 5e123df9103..dc3750e16ea 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -489,3 +489,16 @@ handler t1 open; ERROR HY000: Table storage engine for 't1' doesn't have this option --> client 1 drop table t1; +drop table if exists t1; +create table t1 (a int); +handler t1 open as t1_alias; +handler t1_alias read a next; +ERROR HY000: Key 'a' doesn't exist in table 't1_alias' +handler t1_alias READ a next where inexistent > 0; +ERROR 42S22: Unknown column 'inexistent' in 'field list' +handler t1_alias read a next; +ERROR HY000: Key 'a' doesn't exist in table 't1_alias' +handler t1_alias READ a next where inexistent > 0; +ERROR 42S22: Unknown column 'inexistent' in 'field list' +handler t1_alias close; +drop table t1; diff --git a/mysql-test/r/innodb-deadlock.result b/mysql-test/r/innodb-deadlock.result index 2ca82101fb4..b6a3373e8c6 100644 --- a/mysql-test/r/innodb-deadlock.result +++ b/mysql-test/r/innodb-deadlock.result @@ -94,3 +94,14 @@ id x 300 300 commit; drop table t1, t2; +End of 4.1 tests +set storage_engine=innodb; +drop table if exists a; +drop table if exists A; +create table A (c int); +insert into A (c) values (0); +create table a as select * from A; +drop table A; +drop table if exists a; +set storage_engine=default; +End of 5.0 tests. diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 843f2c7285a..74b5c42e59b 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -176,4 +176,6 @@ ERROR at line 1: DELIMITER cannot contain a backslash character ERROR at line 1: DELIMITER cannot contain a backslash character 1 1 +1 +1 End of 5.0 tests diff --git a/mysql-test/r/parser_precedence.result b/mysql-test/r/parser_precedence.result new file mode 100644 index 00000000000..cf301ec677b --- /dev/null +++ b/mysql-test/r/parser_precedence.result @@ -0,0 +1,747 @@ +drop table if exists t1_30237_bool; +create table t1_30237_bool(A boolean, B boolean, C boolean); +insert into t1_30237_bool values +(FALSE, FALSE, FALSE), +(FALSE, FALSE, NULL), +(FALSE, FALSE, TRUE), +(FALSE, NULL, FALSE), +(FALSE, NULL, NULL), +(FALSE, NULL, TRUE), +(FALSE, TRUE, FALSE), +(FALSE, TRUE, NULL), +(FALSE, TRUE, TRUE), +(NULL, FALSE, FALSE), +(NULL, FALSE, NULL), +(NULL, FALSE, TRUE), +(NULL, NULL, FALSE), +(NULL, NULL, NULL), +(NULL, NULL, TRUE), +(NULL, TRUE, FALSE), +(NULL, TRUE, NULL), +(NULL, TRUE, TRUE), +(TRUE, FALSE, FALSE), +(TRUE, FALSE, NULL), +(TRUE, FALSE, TRUE), +(TRUE, NULL, FALSE), +(TRUE, NULL, NULL), +(TRUE, NULL, TRUE), +(TRUE, TRUE, FALSE), +(TRUE, TRUE, NULL), +(TRUE, TRUE, TRUE) ; +Testing OR, XOR, AND +select A, B, A OR B, A XOR B, A AND B +from t1_30237_bool where C is null order by A, B; +A B A OR B A XOR B A AND B +NULL NULL NULL NULL NULL +NULL 0 NULL NULL 0 +NULL 1 1 NULL NULL +0 NULL NULL NULL 0 +0 0 0 0 0 +0 1 1 1 0 +1 NULL 1 NULL NULL +1 0 1 1 0 +1 1 1 0 1 +Testing that OR is associative +select A, B, C, (A OR B) OR C, A OR (B OR C), A OR B OR C +from t1_30237_bool order by A, B, C; +A B C (A OR B) OR C A OR (B OR C) A OR B OR C +NULL NULL NULL NULL NULL NULL +NULL NULL 0 NULL NULL NULL +NULL NULL 1 1 1 1 +NULL 0 NULL NULL NULL NULL +NULL 0 0 NULL NULL NULL +NULL 0 1 1 1 1 +NULL 1 NULL 1 1 1 +NULL 1 0 1 1 1 +NULL 1 1 1 1 1 +0 NULL NULL NULL NULL NULL +0 NULL 0 NULL NULL NULL +0 NULL 1 1 1 1 +0 0 NULL NULL NULL NULL +0 0 0 0 0 0 +0 0 1 1 1 1 +0 1 NULL 1 1 1 +0 1 0 1 1 1 +0 1 1 1 1 1 +1 NULL NULL 1 1 1 +1 NULL 0 1 1 1 +1 NULL 1 1 1 1 +1 0 NULL 1 1 1 +1 0 0 1 1 1 +1 0 1 1 1 1 +1 1 NULL 1 1 1 +1 1 0 1 1 1 +1 1 1 1 1 1 +select count(*) from t1_30237_bool +where ((A OR B) OR C) != (A OR (B OR C)); +count(*) +0 +Testing that XOR is associative +select A, B, C, (A XOR B) XOR C, A XOR (B XOR C), A XOR B XOR C +from t1_30237_bool order by A, B, C; +A B C (A XOR B) XOR C A XOR (B XOR C) A XOR B XOR C +NULL NULL NULL NULL NULL NULL +NULL NULL 0 NULL NULL NULL +NULL NULL 1 NULL NULL NULL +NULL 0 NULL NULL NULL NULL +NULL 0 0 NULL NULL NULL +NULL 0 1 NULL NULL NULL +NULL 1 NULL NULL NULL NULL +NULL 1 0 NULL NULL NULL +NULL 1 1 NULL NULL NULL +0 NULL NULL NULL NULL NULL +0 NULL 0 NULL NULL NULL +0 NULL 1 NULL NULL NULL +0 0 NULL NULL NULL NULL +0 0 0 0 0 0 +0 0 1 1 1 1 +0 1 NULL NULL NULL NULL +0 1 0 1 1 1 +0 1 1 0 0 0 +1 NULL NULL NULL NULL NULL +1 NULL 0 NULL NULL NULL +1 NULL 1 NULL NULL NULL +1 0 NULL NULL NULL NULL +1 0 0 1 1 1 +1 0 1 0 0 0 +1 1 NULL NULL NULL NULL +1 1 0 0 0 0 +1 1 1 1 1 1 +select count(*) from t1_30237_bool +where ((A XOR B) XOR C) != (A XOR (B XOR C)); +count(*) +0 +Testing that AND is associative +select A, B, C, (A AND B) AND C, A AND (B AND C), A AND B AND C +from t1_30237_bool order by A, B, C; +A B C (A AND B) AND C A AND (B AND C) A AND B AND C +NULL NULL NULL NULL NULL NULL +NULL NULL 0 0 0 0 +NULL NULL 1 NULL NULL NULL +NULL 0 NULL 0 0 0 +NULL 0 0 0 0 0 +NULL 0 1 0 0 0 +NULL 1 NULL NULL NULL NULL +NULL 1 0 0 0 0 +NULL 1 1 NULL NULL NULL +0 NULL NULL 0 0 0 +0 NULL 0 0 0 0 +0 NULL 1 0 0 0 +0 0 NULL 0 0 0 +0 0 0 0 0 0 +0 0 1 0 0 0 +0 1 NULL 0 0 0 +0 1 0 0 0 0 +0 1 1 0 0 0 +1 NULL NULL NULL NULL NULL +1 NULL 0 0 0 0 +1 NULL 1 NULL NULL NULL +1 0 NULL 0 0 0 +1 0 0 0 0 0 +1 0 1 0 0 0 +1 1 NULL NULL NULL NULL +1 1 0 0 0 0 +1 1 1 1 1 1 +select count(*) from t1_30237_bool +where ((A AND B) AND C) != (A AND (B AND C)); +count(*) +0 +Testing that AND has precedence over OR +select A, B, C, (A OR B) AND C, A OR (B AND C), A OR B AND C +from t1_30237_bool order by A, B, C; +A B C (A OR B) AND C A OR (B AND C) A OR B AND C +NULL NULL NULL NULL NULL NULL +NULL NULL 0 0 NULL NULL +NULL NULL 1 NULL NULL NULL +NULL 0 NULL NULL NULL NULL +NULL 0 0 0 NULL NULL +NULL 0 1 NULL NULL NULL +NULL 1 NULL NULL NULL NULL +NULL 1 0 0 NULL NULL +NULL 1 1 1 1 1 +0 NULL NULL NULL NULL NULL +0 NULL 0 0 0 0 +0 NULL 1 NULL NULL NULL +0 0 NULL 0 0 0 +0 0 0 0 0 0 +0 0 1 0 0 0 +0 1 NULL NULL NULL NULL +0 1 0 0 0 0 +0 1 1 1 1 1 +1 NULL NULL NULL 1 1 +1 NULL 0 0 1 1 +1 NULL 1 1 1 1 +1 0 NULL NULL 1 1 +1 0 0 0 1 1 +1 0 1 1 1 1 +1 1 NULL NULL 1 1 +1 1 0 0 1 1 +1 1 1 1 1 1 +select count(*) from t1_30237_bool +where (A OR (B AND C)) != (A OR B AND C); +count(*) +0 +select A, B, C, (A AND B) OR C, A AND (B OR C), A AND B OR C +from t1_30237_bool order by A, B, C; +A B C (A AND B) OR C A AND (B OR C) A AND B OR C +NULL NULL NULL NULL NULL NULL +NULL NULL 0 NULL NULL NULL +NULL NULL 1 1 NULL 1 +NULL 0 NULL NULL NULL NULL +NULL 0 0 0 0 0 +NULL 0 1 1 NULL 1 +NULL 1 NULL NULL NULL NULL +NULL 1 0 NULL NULL NULL +NULL 1 1 1 NULL 1 +0 NULL NULL NULL 0 NULL +0 NULL 0 0 0 0 +0 NULL 1 1 0 1 +0 0 NULL NULL 0 NULL +0 0 0 0 0 0 +0 0 1 1 0 1 +0 1 NULL NULL 0 NULL +0 1 0 0 0 0 +0 1 1 1 0 1 +1 NULL NULL NULL NULL NULL +1 NULL 0 NULL NULL NULL +1 NULL 1 1 1 1 +1 0 NULL NULL NULL NULL +1 0 0 0 0 0 +1 0 1 1 1 1 +1 1 NULL 1 1 1 +1 1 0 1 1 1 +1 1 1 1 1 1 +select count(*) from t1_30237_bool +where ((A AND B) OR C) != (A AND B OR C); +count(*) +0 +Testing that AND has precedence over XOR +select A, B, C, (A XOR B) AND C, A XOR (B AND C), A XOR B AND C +from t1_30237_bool order by A, B, C; +A B C (A XOR B) AND C A XOR (B AND C) A XOR B AND C +NULL NULL NULL NULL NULL NULL +NULL NULL 0 0 NULL NULL +NULL NULL 1 NULL NULL NULL +NULL 0 NULL NULL NULL NULL +NULL 0 0 0 NULL NULL +NULL 0 1 NULL NULL NULL +NULL 1 NULL NULL NULL NULL +NULL 1 0 0 NULL NULL +NULL 1 1 NULL NULL NULL +0 NULL NULL NULL NULL NULL +0 NULL 0 0 0 0 +0 NULL 1 NULL NULL NULL +0 0 NULL 0 0 0 +0 0 0 0 0 0 +0 0 1 0 0 0 +0 1 NULL NULL NULL NULL +0 1 0 0 0 0 +0 1 1 1 1 1 +1 NULL NULL NULL NULL NULL +1 NULL 0 0 1 1 +1 NULL 1 NULL NULL NULL +1 0 NULL NULL 1 1 +1 0 0 0 1 1 +1 0 1 1 1 1 +1 1 NULL 0 NULL NULL +1 1 0 0 1 1 +1 1 1 0 0 0 +select count(*) from t1_30237_bool +where (A XOR (B AND C)) != (A XOR B AND C); +count(*) +0 +select A, B, C, (A AND B) XOR C, A AND (B XOR C), A AND B XOR C +from t1_30237_bool order by A, B, C; +A B C (A AND B) XOR C A AND (B XOR C) A AND B XOR C +NULL NULL NULL NULL NULL NULL +NULL NULL 0 NULL NULL NULL +NULL NULL 1 NULL NULL NULL +NULL 0 NULL NULL NULL NULL +NULL 0 0 0 0 0 +NULL 0 1 1 NULL 1 +NULL 1 NULL NULL NULL NULL +NULL 1 0 NULL NULL NULL +NULL 1 1 NULL 0 NULL +0 NULL NULL NULL 0 NULL +0 NULL 0 0 0 0 +0 NULL 1 1 0 1 +0 0 NULL NULL 0 NULL +0 0 0 0 0 0 +0 0 1 1 0 1 +0 1 NULL NULL 0 NULL +0 1 0 0 0 0 +0 1 1 1 0 1 +1 NULL NULL NULL NULL NULL +1 NULL 0 NULL NULL NULL +1 NULL 1 NULL NULL NULL +1 0 NULL NULL NULL NULL +1 0 0 0 0 0 +1 0 1 1 1 1 +1 1 NULL NULL NULL NULL +1 1 0 1 1 1 +1 1 1 0 0 0 +select count(*) from t1_30237_bool +where ((A AND B) XOR C) != (A AND B XOR C); +count(*) +0 +Testing that XOR has precedence over OR +select A, B, C, (A XOR B) OR C, A XOR (B OR C), A XOR B OR C +from t1_30237_bool order by A, B, C; +A B C (A XOR B) OR C A XOR (B OR C) A XOR B OR C +NULL NULL NULL NULL NULL NULL +NULL NULL 0 NULL NULL NULL +NULL NULL 1 1 NULL 1 +NULL 0 NULL NULL NULL NULL +NULL 0 0 NULL NULL NULL +NULL 0 1 1 NULL 1 +NULL 1 NULL NULL NULL NULL +NULL 1 0 NULL NULL NULL +NULL 1 1 1 NULL 1 +0 NULL NULL NULL NULL NULL +0 NULL 0 NULL NULL NULL +0 NULL 1 1 1 1 +0 0 NULL NULL NULL NULL +0 0 0 0 0 0 +0 0 1 1 1 1 +0 1 NULL 1 1 1 +0 1 0 1 1 1 +0 1 1 1 1 1 +1 NULL NULL NULL NULL NULL +1 NULL 0 NULL NULL NULL +1 NULL 1 1 0 1 +1 0 NULL 1 NULL 1 +1 0 0 1 1 1 +1 0 1 1 0 1 +1 1 NULL NULL 0 NULL +1 1 0 0 0 0 +1 1 1 1 0 1 +select count(*) from t1_30237_bool +where ((A XOR B) OR C) != (A XOR B OR C); +count(*) +0 +select A, B, C, (A OR B) XOR C, A OR (B XOR C), A OR B XOR C +from t1_30237_bool order by A, B, C; +A B C (A OR B) XOR C A OR (B XOR C) A OR B XOR C +NULL NULL NULL NULL NULL NULL +NULL NULL 0 NULL NULL NULL +NULL NULL 1 NULL NULL NULL +NULL 0 NULL NULL NULL NULL +NULL 0 0 NULL NULL NULL +NULL 0 1 NULL 1 1 +NULL 1 NULL NULL NULL NULL +NULL 1 0 1 1 1 +NULL 1 1 0 NULL NULL +0 NULL NULL NULL NULL NULL +0 NULL 0 NULL NULL NULL +0 NULL 1 NULL NULL NULL +0 0 NULL NULL NULL NULL +0 0 0 0 0 0 +0 0 1 1 1 1 +0 1 NULL NULL NULL NULL +0 1 0 1 1 1 +0 1 1 0 0 0 +1 NULL NULL NULL 1 1 +1 NULL 0 1 1 1 +1 NULL 1 0 1 1 +1 0 NULL NULL 1 1 +1 0 0 1 1 1 +1 0 1 0 1 1 +1 1 NULL NULL 1 1 +1 1 0 1 1 1 +1 1 1 0 1 1 +select count(*) from t1_30237_bool +where (A OR (B XOR C)) != (A OR B XOR C); +count(*) +0 +drop table t1_30237_bool; +Testing that NOT has precedence over OR +select (NOT FALSE) OR TRUE, NOT (FALSE OR TRUE), NOT FALSE OR TRUE; +(NOT FALSE) OR TRUE NOT (FALSE OR TRUE) NOT FALSE OR TRUE +1 0 1 +Testing that NOT has precedence over XOR +select (NOT FALSE) XOR FALSE, NOT (FALSE XOR FALSE), NOT FALSE XOR FALSE; +(NOT FALSE) XOR FALSE NOT (FALSE XOR FALSE) NOT FALSE XOR FALSE +1 1 1 +Testing that NOT has precedence over AND +select (NOT FALSE) AND FALSE, NOT (FALSE AND FALSE), NOT FALSE AND FALSE; +(NOT FALSE) AND FALSE NOT (FALSE AND FALSE) NOT FALSE AND FALSE +0 1 0 +Testing that NOT is associative +select NOT NOT TRUE, NOT NOT NOT FALSE; +NOT NOT TRUE NOT NOT NOT FALSE +1 1 +Testing that IS has precedence over NOT +select (NOT NULL) IS TRUE, NOT (NULL IS TRUE), NOT NULL IS TRUE; +(NOT NULL) IS TRUE NOT (NULL IS TRUE) NOT NULL IS TRUE +0 1 1 +select (NOT NULL) IS NOT TRUE, NOT (NULL IS NOT TRUE), NOT NULL IS NOT TRUE; +(NOT NULL) IS NOT TRUE NOT (NULL IS NOT TRUE) NOT NULL IS NOT TRUE +1 0 0 +select (NOT NULL) IS FALSE, NOT (NULL IS FALSE), NOT NULL IS FALSE; +(NOT NULL) IS FALSE NOT (NULL IS FALSE) NOT NULL IS FALSE +0 1 1 +select (NOT NULL) IS NOT FALSE, NOT (NULL IS NOT FALSE), NOT NULL IS NOT FALSE; +(NOT NULL) IS NOT FALSE NOT (NULL IS NOT FALSE) NOT NULL IS NOT FALSE +1 0 0 +select (NOT TRUE) IS UNKNOWN, NOT (TRUE IS UNKNOWN), NOT TRUE IS UNKNOWN; +(NOT TRUE) IS UNKNOWN NOT (TRUE IS UNKNOWN) NOT TRUE IS UNKNOWN +0 1 1 +select (NOT TRUE) IS NOT UNKNOWN, NOT (TRUE IS NOT UNKNOWN), NOT TRUE IS NOT UNKNOWN; +(NOT TRUE) IS NOT UNKNOWN NOT (TRUE IS NOT UNKNOWN) NOT TRUE IS NOT UNKNOWN +1 0 0 +select (NOT TRUE) IS NULL, NOT (TRUE IS NULL), NOT TRUE IS NULL; +(NOT TRUE) IS NULL NOT (TRUE IS NULL) NOT TRUE IS NULL +0 1 1 +select (NOT TRUE) IS NOT NULL, NOT (TRUE IS NOT NULL), NOT TRUE IS NOT NULL; +(NOT TRUE) IS NOT NULL NOT (TRUE IS NOT NULL) NOT TRUE IS NOT NULL +1 0 0 +Testing that IS [NOT] TRUE/FALSE/UNKNOWN predicates are not associative +select TRUE IS TRUE IS TRUE IS TRUE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IS TRUE IS TRUE' at line 1 +select FALSE IS NOT TRUE IS NOT TRUE IS NOT TRUE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IS NOT TRUE IS NOT TRUE' at line 1 +select NULL IS FALSE IS FALSE IS FALSE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IS FALSE IS FALSE' at line 1 +select TRUE IS NOT FALSE IS NOT FALSE IS NOT FALSE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IS NOT FALSE IS NOT FALSE' at line 1 +select FALSE IS UNKNOWN IS UNKNOWN IS UNKNOWN; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IS UNKNOWN IS UNKNOWN' at line 1 +select TRUE IS NOT UNKNOWN IS NOT UNKNOWN IS NOT UNKNOWN; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IS NOT UNKNOWN IS NOT UNKNOWN' at line 1 +Testing that IS [NOT] NULL predicates are associative +select FALSE IS NULL IS NULL IS NULL; +FALSE IS NULL IS NULL IS NULL +0 +select TRUE IS NOT NULL IS NOT NULL IS NOT NULL; +TRUE IS NOT NULL IS NOT NULL IS NOT NULL +1 +Testing that comparison operators are left associative +select 1 <=> 2 <=> 2, (1 <=> 2) <=> 2, 1 <=> (2 <=> 2); +1 <=> 2 <=> 2 (1 <=> 2) <=> 2 1 <=> (2 <=> 2) +0 0 1 +select 1 = 2 = 2, (1 = 2) = 2, 1 = (2 = 2); +1 = 2 = 2 (1 = 2) = 2 1 = (2 = 2) +0 0 1 +select 1 != 2 != 3, (1 != 2) != 3, 1 != (2 != 3); +1 != 2 != 3 (1 != 2) != 3 1 != (2 != 3) +1 1 0 +select 1 <> 2 <> 3, (1 <> 2) <> 3, 1 <> (2 <> 3); +1 <> 2 <> 3 (1 <> 2) <> 3 1 <> (2 <> 3) +1 1 0 +select 1 < 2 < 3, (1 < 2) < 3, 1 < (2 < 3); +1 < 2 < 3 (1 < 2) < 3 1 < (2 < 3) +1 1 0 +select 3 <= 2 <= 1, (3 <= 2) <= 1, 3 <= (2 <= 1); +3 <= 2 <= 1 (3 <= 2) <= 1 3 <= (2 <= 1) +1 1 0 +select 1 > 2 > 3, (1 > 2) > 3, 1 > (2 > 3); +1 > 2 > 3 (1 > 2) > 3 1 > (2 > 3) +0 0 1 +select 1 >= 2 >= 3, (1 >= 2) >= 3, 1 >= (2 >= 3); +1 >= 2 >= 3 (1 >= 2) >= 3 1 >= (2 >= 3) +0 0 1 +Testing that | is associative +select 0xF0 | 0x0F | 0x55, (0xF0 | 0x0F) | 0x55, 0xF0 | (0x0F | 0x55); +0xF0 | 0x0F | 0x55 (0xF0 | 0x0F) | 0x55 0xF0 | (0x0F | 0x55) +255 255 255 +Testing that & is associative +select 0xF5 & 0x5F & 0x55, (0xF5 & 0x5F) & 0x55, 0xF5 & (0x5F & 0x55); +0xF5 & 0x5F & 0x55 (0xF5 & 0x5F) & 0x55 0xF5 & (0x5F & 0x55) +85 85 85 +Testing that << is left associative +select 4 << 3 << 2, (4 << 3) << 2, 4 << (3 << 2); +4 << 3 << 2 (4 << 3) << 2 4 << (3 << 2) +128 128 16384 +Testing that >> is left associative +select 256 >> 3 >> 2, (256 >> 3) >> 2, 256 >> (3 >> 2); +256 >> 3 >> 2 (256 >> 3) >> 2 256 >> (3 >> 2) +8 8 256 +Testing that & has precedence over | +select 0xF0 & 0x0F | 0x55, (0xF0 & 0x0F) | 0x55, 0xF0 & (0x0F | 0x55); +0xF0 & 0x0F | 0x55 (0xF0 & 0x0F) | 0x55 0xF0 & (0x0F | 0x55) +85 85 80 +select 0x55 | 0xF0 & 0x0F, (0x55 | 0xF0) & 0x0F, 0x55 | (0xF0 & 0x0F); +0x55 | 0xF0 & 0x0F (0x55 | 0xF0) & 0x0F 0x55 | (0xF0 & 0x0F) +85 5 85 +Testing that << has precedence over | +select 0x0F << 4 | 0x0F, (0x0F << 4) | 0x0F, 0x0F << (4 | 0x0F); +0x0F << 4 | 0x0F (0x0F << 4) | 0x0F 0x0F << (4 | 0x0F) +255 255 491520 +select 0x0F | 0x0F << 4, (0x0F | 0x0F) << 4, 0x0F | (0x0F << 4); +0x0F | 0x0F << 4 (0x0F | 0x0F) << 4 0x0F | (0x0F << 4) +255 240 255 +Testing that >> has precedence over | +select 0xF0 >> 4 | 0xFF, (0xF0 >> 4) | 0xFF, 0xF0 >> (4 | 0xFF); +0xF0 >> 4 | 0xFF (0xF0 >> 4) | 0xFF 0xF0 >> (4 | 0xFF) +255 255 0 +select 0xFF | 0xF0 >> 4, (0xFF | 0xF0) >> 4, 0xFF | (0xF0 >> 4); +0xFF | 0xF0 >> 4 (0xFF | 0xF0) >> 4 0xFF | (0xF0 >> 4) +255 15 255 +Testing that << has precedence over & +select 0x0F << 4 & 0xF0, (0x0F << 4) & 0xF0, 0x0F << (4 & 0xF0); +0x0F << 4 & 0xF0 (0x0F << 4) & 0xF0 0x0F << (4 & 0xF0) +240 240 15 +select 0xF0 & 0x0F << 4, (0xF0 & 0x0F) << 4, 0xF0 & (0x0F << 4); +0xF0 & 0x0F << 4 (0xF0 & 0x0F) << 4 0xF0 & (0x0F << 4) +240 0 240 +Testing that >> has precedence over & +select 0xF0 >> 4 & 0x55, (0xF0 >> 4) & 0x55, 0xF0 >> (4 & 0x55); +0xF0 >> 4 & 0x55 (0xF0 >> 4) & 0x55 0xF0 >> (4 & 0x55) +5 5 15 +select 0x0F & 0xF0 >> 4, (0x0F & 0xF0) >> 4, 0x0F & (0xF0 >> 4); +0x0F & 0xF0 >> 4 (0x0F & 0xF0) >> 4 0x0F & (0xF0 >> 4) +15 0 15 +Testing that >> and << have the same precedence +select 0xFF >> 4 << 2, (0xFF >> 4) << 2, 0xFF >> (4 << 2); +0xFF >> 4 << 2 (0xFF >> 4) << 2 0xFF >> (4 << 2) +60 60 0 +select 0x0F << 4 >> 2, (0x0F << 4) >> 2, 0x0F << (4 >> 2); +0x0F << 4 >> 2 (0x0F << 4) >> 2 0x0F << (4 >> 2) +60 60 30 +Testing that binary + is associative +select 1 + 2 + 3, (1 + 2) + 3, 1 + (2 + 3); +1 + 2 + 3 (1 + 2) + 3 1 + (2 + 3) +6 6 6 +Testing that binary - is left associative +select 1 - 2 - 3, (1 - 2) - 3, 1 - (2 - 3); +1 - 2 - 3 (1 - 2) - 3 1 - (2 - 3) +-4 -4 2 +Testing that binary + and binary - have the same precedence +select 1 + 2 - 3, (1 + 2) - 3, 1 + (2 - 3); +1 + 2 - 3 (1 + 2) - 3 1 + (2 - 3) +0 0 0 +select 1 - 2 + 3, (1 - 2) + 3, 1 - (2 + 3); +1 - 2 + 3 (1 - 2) + 3 1 - (2 + 3) +2 2 -4 +Testing that binary + has precedence over | +select 0xF0 + 0x0F | 0x55, (0xF0 + 0x0F) | 0x55, 0xF0 + (0x0F | 0x55); +0xF0 + 0x0F | 0x55 (0xF0 + 0x0F) | 0x55 0xF0 + (0x0F | 0x55) +255 255 335 +select 0x55 | 0xF0 + 0x0F, (0x55 | 0xF0) + 0x0F, 0x55 | (0xF0 + 0x0F); +0x55 | 0xF0 + 0x0F (0x55 | 0xF0) + 0x0F 0x55 | (0xF0 + 0x0F) +255 260 255 +Testing that binary + has precedence over & +select 0xF0 + 0x0F & 0x55, (0xF0 + 0x0F) & 0x55, 0xF0 + (0x0F & 0x55); +0xF0 + 0x0F & 0x55 (0xF0 + 0x0F) & 0x55 0xF0 + (0x0F & 0x55) +85 85 245 +select 0x55 & 0xF0 + 0x0F, (0x55 & 0xF0) + 0x0F, 0x55 & (0xF0 + 0x0F); +0x55 & 0xF0 + 0x0F (0x55 & 0xF0) + 0x0F 0x55 & (0xF0 + 0x0F) +85 95 85 +Testing that binary + has precedence over << +select 2 + 3 << 4, (2 + 3) << 4, 2 + (3 << 4); +2 + 3 << 4 (2 + 3) << 4 2 + (3 << 4) +80 80 50 +select 3 << 4 + 2, (3 << 4) + 2, 3 << (4 + 2); +3 << 4 + 2 (3 << 4) + 2 3 << (4 + 2) +192 50 192 +Testing that binary + has precedence over >> +select 4 + 3 >> 2, (4 + 3) >> 2, 4 + (3 >> 2); +4 + 3 >> 2 (4 + 3) >> 2 4 + (3 >> 2) +1 1 4 +select 3 >> 2 + 1, (3 >> 2) + 1, 3 >> (2 + 1); +3 >> 2 + 1 (3 >> 2) + 1 3 >> (2 + 1) +0 1 0 +Testing that binary - has precedence over | +select 0xFF - 0x0F | 0x55, (0xFF - 0x0F) | 0x55, 0xFF - (0x0F | 0x55); +0xFF - 0x0F | 0x55 (0xFF - 0x0F) | 0x55 0xFF - (0x0F | 0x55) +245 245 160 +select 0x55 | 0xFF - 0xF0, (0x55 | 0xFF) - 0xF0, 0x55 | (0xFF - 0xF0); +0x55 | 0xFF - 0xF0 (0x55 | 0xFF) - 0xF0 0x55 | (0xFF - 0xF0) +95 15 95 +Testing that binary - has precedence over & +select 0xFF - 0xF0 & 0x55, (0xFF - 0xF0) & 0x55, 0xFF - (0xF0 & 0x55); +0xFF - 0xF0 & 0x55 (0xFF - 0xF0) & 0x55 0xFF - (0xF0 & 0x55) +5 5 175 +select 0x55 & 0xFF - 0xF0, (0x55 & 0xFF) - 0xF0, 0x55 & (0xFF - 0xF0); +0x55 & 0xFF - 0xF0 (0x55 & 0xFF) - 0xF0 0x55 & (0xFF - 0xF0) +5 -155 5 +Testing that binary - has precedence over << +select 16 - 3 << 2, (16 - 3) << 2, 16 - (3 << 2); +16 - 3 << 2 (16 - 3) << 2 16 - (3 << 2) +52 52 4 +select 4 << 3 - 2, (4 << 3) - 2, 4 << (3 - 2); +4 << 3 - 2 (4 << 3) - 2 4 << (3 - 2) +8 30 8 +Testing that binary - has precedence over >> +select 16 - 3 >> 2, (16 - 3) >> 2, 16 - (3 >> 2); +16 - 3 >> 2 (16 - 3) >> 2 16 - (3 >> 2) +3 3 16 +select 16 >> 3 - 2, (16 >> 3) - 2, 16 >> (3 - 2); +16 >> 3 - 2 (16 >> 3) - 2 16 >> (3 - 2) +8 0 8 +Testing that * is associative +select 2 * 3 * 4, (2 * 3) * 4, 2 * (3 * 4); +2 * 3 * 4 (2 * 3) * 4 2 * (3 * 4) +24 24 24 +Testing that * has precedence over | +select 2 * 0x40 | 0x0F, (2 * 0x40) | 0x0F, 2 * (0x40 | 0x0F); +2 * 0x40 | 0x0F (2 * 0x40) | 0x0F 2 * (0x40 | 0x0F) +143 143 158 +select 0x0F | 2 * 0x40, (0x0F | 2) * 0x40, 0x0F | (2 * 0x40); +0x0F | 2 * 0x40 (0x0F | 2) * 0x40 0x0F | (2 * 0x40) +143 960 143 +Testing that * has precedence over & +select 2 * 0x40 & 0x55, (2 * 0x40) & 0x55, 2 * (0x40 & 0x55); +2 * 0x40 & 0x55 (2 * 0x40) & 0x55 2 * (0x40 & 0x55) +0 0 128 +select 0xF0 & 2 * 0x40, (0xF0 & 2) * 0x40, 0xF0 & (2 * 0x40); +0xF0 & 2 * 0x40 (0xF0 & 2) * 0x40 0xF0 & (2 * 0x40) +128 0 128 +Testing that * has precedence over << +select 5 * 3 << 4, (5 * 3) << 4, 5 * (3 << 4); +5 * 3 << 4 (5 * 3) << 4 5 * (3 << 4) +240 240 240 +select 2 << 3 * 4, (2 << 3) * 4, 2 << (3 * 4); +2 << 3 * 4 (2 << 3) * 4 2 << (3 * 4) +8192 64 8192 +Testing that * has precedence over >> +select 3 * 4 >> 2, (3 * 4) >> 2, 3 * (4 >> 2); +3 * 4 >> 2 (3 * 4) >> 2 3 * (4 >> 2) +3 3 3 +select 4 >> 2 * 3, (4 >> 2) * 3, 4 >> (2 * 3); +4 >> 2 * 3 (4 >> 2) * 3 4 >> (2 * 3) +0 3 0 +Testing that * has precedence over binary + +select 2 * 3 + 4, (2 * 3) + 4, 2 * (3 + 4); +2 * 3 + 4 (2 * 3) + 4 2 * (3 + 4) +10 10 14 +select 2 + 3 * 4, (2 + 3) * 4, 2 + (3 * 4); +2 + 3 * 4 (2 + 3) * 4 2 + (3 * 4) +14 20 14 +Testing that * has precedence over binary - +select 4 * 3 - 2, (4 * 3) - 2, 4 * (3 - 2); +4 * 3 - 2 (4 * 3) - 2 4 * (3 - 2) +10 10 4 +select 4 - 3 * 2, (4 - 3) * 2, 4 - (3 * 2); +4 - 3 * 2 (4 - 3) * 2 4 - (3 * 2) +-2 2 -2 +Testing that / is left associative +select 15 / 5 / 3, (15 / 5) / 3, 15 / (5 / 3); +15 / 5 / 3 (15 / 5) / 3 15 / (5 / 3) +1.00000000 1.00000000 9.0000 +Testing that / has precedence over | +select 105 / 5 | 2, (105 / 5) | 2, 105 / (5 | 2); +105 / 5 | 2 (105 / 5) | 2 105 / (5 | 2) +23 23 15.0000 +select 105 | 2 / 5, (105 | 2) / 5, 105 | (2 / 5); +105 | 2 / 5 (105 | 2) / 5 105 | (2 / 5) +105 21.4000 105 +Testing that / has precedence over & +select 105 / 5 & 0x0F, (105 / 5) & 0x0F, 105 / (5 & 0x0F); +105 / 5 & 0x0F (105 / 5) & 0x0F 105 / (5 & 0x0F) +5 5 21.0000 +select 0x0F & 105 / 5, (0x0F & 105) / 5, 0x0F & (105 / 5); +0x0F & 105 / 5 (0x0F & 105) / 5 0x0F & (105 / 5) +5 1.8000 5 +Testing that / has precedence over << +select 0x80 / 4 << 2, (0x80 / 4) << 2, 0x80 / (4 << 2); +0x80 / 4 << 2 (0x80 / 4) << 2 0x80 / (4 << 2) +128 128 8.0000 +select 0x80 << 4 / 2, (0x80 << 4) / 2, 0x80 << (4 / 2); +0x80 << 4 / 2 (0x80 << 4) / 2 0x80 << (4 / 2) +512 1024.0000 512 +Testing that / has precedence over >> +select 0x80 / 4 >> 2, (0x80 / 4) >> 2, 0x80 / (4 >> 2); +0x80 / 4 >> 2 (0x80 / 4) >> 2 0x80 / (4 >> 2) +8 8 128.0000 +select 0x80 >> 4 / 2, (0x80 >> 4) / 2, 0x80 >> (4 / 2); +0x80 >> 4 / 2 (0x80 >> 4) / 2 0x80 >> (4 / 2) +32 4.0000 32 +Testing that / has precedence over binary + +select 0x80 / 2 + 2, (0x80 / 2) + 2, 0x80 / (2 + 2); +0x80 / 2 + 2 (0x80 / 2) + 2 0x80 / (2 + 2) +66.0000 66.0000 32.0000 +select 0x80 + 2 / 2, (0x80 + 2) / 2, 0x80 + (2 / 2); +0x80 + 2 / 2 (0x80 + 2) / 2 0x80 + (2 / 2) +129.0000 65.0000 129.0000 +Testing that / has precedence over binary - +select 0x80 / 4 - 2, (0x80 / 4) - 2, 0x80 / (4 - 2); +0x80 / 4 - 2 (0x80 / 4) - 2 0x80 / (4 - 2) +30.0000 30.0000 64.0000 +select 0x80 - 4 / 2, (0x80 - 4) / 2, 0x80 - (4 / 2); +0x80 - 4 / 2 (0x80 - 4) / 2 0x80 - (4 / 2) +126.0000 62.0000 126.0000 +Testing that ^ is associative +select 0xFF ^ 0xF0 ^ 0x0F, (0xFF ^ 0xF0) ^ 0x0F, 0xFF ^ (0xF0 ^ 0x0F); +0xFF ^ 0xF0 ^ 0x0F (0xFF ^ 0xF0) ^ 0x0F 0xFF ^ (0xF0 ^ 0x0F) +0 0 0 +select 0xFF ^ 0xF0 ^ 0x55, (0xFF ^ 0xF0) ^ 0x55, 0xFF ^ (0xF0 ^ 0x55); +0xFF ^ 0xF0 ^ 0x55 (0xFF ^ 0xF0) ^ 0x55 0xFF ^ (0xF0 ^ 0x55) +90 90 90 +Testing that ^ has precedence over | +select 0xFF ^ 0xF0 | 0x0F, (0xFF ^ 0xF0) | 0x0F, 0xFF ^ (0xF0 | 0x0F); +0xFF ^ 0xF0 | 0x0F (0xFF ^ 0xF0) | 0x0F 0xFF ^ (0xF0 | 0x0F) +15 15 0 +select 0xF0 | 0xFF ^ 0xF0, (0xF0 | 0xFF) ^ 0xF0, 0xF0 | (0xFF ^ 0xF0); +0xF0 | 0xFF ^ 0xF0 (0xF0 | 0xFF) ^ 0xF0 0xF0 | (0xFF ^ 0xF0) +255 15 255 +Testing that ^ has precedence over & +select 0xFF ^ 0xF0 & 0x0F, (0xFF ^ 0xF0) & 0x0F, 0xFF ^ (0xF0 & 0x0F); +0xFF ^ 0xF0 & 0x0F (0xFF ^ 0xF0) & 0x0F 0xFF ^ (0xF0 & 0x0F) +15 15 255 +select 0x0F & 0xFF ^ 0xF0, (0x0F & 0xFF) ^ 0xF0, 0x0F & (0xFF ^ 0xF0); +0x0F & 0xFF ^ 0xF0 (0x0F & 0xFF) ^ 0xF0 0x0F & (0xFF ^ 0xF0) +15 255 15 +Testing that ^ has precedence over << +select 0xFF ^ 0xF0 << 2, (0xFF ^ 0xF0) << 2, 0xFF ^ (0xF0 << 2); +0xFF ^ 0xF0 << 2 (0xFF ^ 0xF0) << 2 0xFF ^ (0xF0 << 2) +60 60 831 +select 0x0F << 2 ^ 0xFF, (0x0F << 2) ^ 0xFF, 0x0F << (2 ^ 0xFF); +0x0F << 2 ^ 0xFF (0x0F << 2) ^ 0xFF 0x0F << (2 ^ 0xFF) +0 195 0 +Testing that ^ has precedence over >> +select 0xFF ^ 0xF0 >> 2, (0xFF ^ 0xF0) >> 2, 0xFF ^ (0xF0 >> 2); +0xFF ^ 0xF0 >> 2 (0xFF ^ 0xF0) >> 2 0xFF ^ (0xF0 >> 2) +3 3 195 +select 0xFF >> 2 ^ 0xF0, (0xFF >> 2) ^ 0xF0, 0xFF >> (2 ^ 0xF0); +0xFF >> 2 ^ 0xF0 (0xFF >> 2) ^ 0xF0 0xFF >> (2 ^ 0xF0) +0 207 0 +Testing that ^ has precedence over binary + +select 0xFF ^ 0xF0 + 0x0F, (0xFF ^ 0xF0) + 0x0F, 0xFF ^ (0xF0 + 0x0F); +0xFF ^ 0xF0 + 0x0F (0xFF ^ 0xF0) + 0x0F 0xFF ^ (0xF0 + 0x0F) +30 30 0 +select 0x0F + 0xFF ^ 0xF0, (0x0F + 0xFF) ^ 0xF0, 0x0F + (0xFF ^ 0xF0); +0x0F + 0xFF ^ 0xF0 (0x0F + 0xFF) ^ 0xF0 0x0F + (0xFF ^ 0xF0) +30 510 30 +Testing that ^ has precedence over binary - +select 0xFF ^ 0xF0 - 1, (0xFF ^ 0xF0) - 1, 0xFF ^ (0xF0 - 1); +0xFF ^ 0xF0 - 1 (0xFF ^ 0xF0) - 1 0xFF ^ (0xF0 - 1) +14 14 16 +select 0x55 - 0x0F ^ 0x55, (0x55 - 0x0F) ^ 0x55, 0x55 - (0x0F ^ 0x55); +0x55 - 0x0F ^ 0x55 (0x55 - 0x0F) ^ 0x55 0x55 - (0x0F ^ 0x55) +-5 19 -5 +Testing that ^ has precedence over * +select 0xFF ^ 0xF0 * 2, (0xFF ^ 0xF0) * 2, 0xFF ^ (0xF0 * 2); +0xFF ^ 0xF0 * 2 (0xFF ^ 0xF0) * 2 0xFF ^ (0xF0 * 2) +30 30 287 +select 2 * 0xFF ^ 0xF0, (2 * 0xFF) ^ 0xF0, 2 * (0xFF ^ 0xF0); +2 * 0xFF ^ 0xF0 (2 * 0xFF) ^ 0xF0 2 * (0xFF ^ 0xF0) +30 270 30 +Testing that ^ has precedence over / +select 0xFF ^ 0xF0 / 2, (0xFF ^ 0xF0) / 2, 0xFF ^ (0xF0 / 2); +0xFF ^ 0xF0 / 2 (0xFF ^ 0xF0) / 2 0xFF ^ (0xF0 / 2) +7.5000 7.5000 135 +select 0xF2 / 2 ^ 0xF0, (0xF2 / 2) ^ 0xF0, 0xF2 / (2 ^ 0xF0); +0xF2 / 2 ^ 0xF0 (0xF2 / 2) ^ 0xF0 0xF2 / (2 ^ 0xF0) +1.0000 137 1.0000 +Testing that ^ has precedence over % +select 0xFF ^ 0xF0 % 0x20, (0xFF ^ 0xF0) % 0x20, 0xFF ^ (0xF0 % 0x20); +0xFF ^ 0xF0 % 0x20 (0xFF ^ 0xF0) % 0x20 0xFF ^ (0xF0 % 0x20) +15 15 239 +select 0xFF % 0x20 ^ 0xF0, (0xFF % 0x20) ^ 0xF0, 0xFF % (0x20 ^ 0xF0); +0xFF % 0x20 ^ 0xF0 (0xFF % 0x20) ^ 0xF0 0xFF % (0x20 ^ 0xF0) +47 239 47 +Testing that ^ has precedence over DIV +select 0xFF ^ 0xF0 DIV 2, (0xFF ^ 0xF0) DIV 2, 0xFF ^ (0xF0 DIV 2); +0xFF ^ 0xF0 DIV 2 (0xFF ^ 0xF0) DIV 2 0xFF ^ (0xF0 DIV 2) +7 7 135 +select 0xF2 DIV 2 ^ 0xF0, (0xF2 DIV 2) ^ 0xF0, 0xF2 DIV (2 ^ 0xF0); +0xF2 DIV 2 ^ 0xF0 (0xF2 DIV 2) ^ 0xF0 0xF2 DIV (2 ^ 0xF0) +1 137 1 +Testing that ^ has precedence over MOD +select 0xFF ^ 0xF0 MOD 0x20, (0xFF ^ 0xF0) MOD 0x20, 0xFF ^ (0xF0 MOD 0x20); +0xFF ^ 0xF0 MOD 0x20 (0xFF ^ 0xF0) MOD 0x20 0xFF ^ (0xF0 MOD 0x20) +15 15 239 +select 0xFF MOD 0x20 ^ 0xF0, (0xFF MOD 0x20) ^ 0xF0, 0xFF MOD (0x20 ^ 0xF0); +0xFF MOD 0x20 ^ 0xF0 (0xFF MOD 0x20) ^ 0xF0 0xFF MOD (0x20 ^ 0xF0) +47 239 47 diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 2cfbe7aadcb..a6c429a31fb 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6315,4 +6315,56 @@ CALL p1(); NULL SET NAMES default; DROP PROCEDURE p1; + +# Bug#13675. + +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP TABLE IF EXISTS t1; + +CREATE PROCEDURE p1(v DATETIME) CREATE TABLE t1 SELECT v; +CREATE PROCEDURE p2(v INT) CREATE TABLE t1 SELECT v; + +CALL p1(NOW()); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` datetime default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +DROP TABLE t1; + +CALL p1('text'); +Warnings: +Warning 1264 Out of range value adjusted for column 'v' at row 1 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` datetime default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +DROP TABLE t1; + +CALL p2(10); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` bigint(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +DROP TABLE t1; + +CALL p2('text'); +Warnings: +Warning 1366 Incorrect integer value: 'text' for column 'v' at row 1 +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `v` bigint(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + +DROP TABLE t1; + +DROP PROCEDURE p1; +DROP PROCEDURE p2; End of 5.0 tests diff --git a/mysql-test/t/comments.test b/mysql-test/t/comments.test index 52273ec9523..0c6853cf298 100644 --- a/mysql-test/t/comments.test +++ b/mysql-test/t/comments.test @@ -19,3 +19,36 @@ select 1 # The rest of the row will be ignored /* line with only comment */; # End of 4.1 tests + + +# +# Bug#28779 (mysql_query() allows execution of statements with unbalanced +# comments) +# + +--disable_warnings +drop table if exists table_28779; +--enable_warnings + +create table table_28779 (a int); + +--error 1064 +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';"; + +--error 1064 +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';*"; + +--error 1064 +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;"; + +--error 1064 +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;*"; + +--error 1064 +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';"; + +--error 1064 +prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';*"; + +drop table table_28779; + diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index 4edd5b5ec32..6ef216f6ed2 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -441,3 +441,22 @@ handler t1 open; --echo --> client 1 connection default; drop table t1; + +# +# Bug#30632 HANDLER read failure causes hang +# +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a int); +handler t1 open as t1_alias; +--error 1176 +handler t1_alias read a next; +--error 1054 +handler t1_alias READ a next where inexistent > 0; +--error 1176 +handler t1_alias read a next; +--error 1054 +handler t1_alias READ a next where inexistent > 0; +handler t1_alias close; +drop table t1; diff --git a/mysql-test/t/innodb-deadlock.test b/mysql-test/t/innodb-deadlock.test index 81acfba5c93..1a184f98771 100644 --- a/mysql-test/t/innodb-deadlock.test +++ b/mysql-test/t/innodb-deadlock.test @@ -112,4 +112,29 @@ commit; drop table t1, t2; -# End of 4.1 tests +--echo End of 4.1 tests + +# +# Bug#25164 create table `a` as select * from `A` hangs +# + +set storage_engine=innodb; + +--disable_warnings +drop table if exists a; +drop table if exists A; +--enable_warnings + +create table A (c int); +insert into A (c) values (0); +--error 0,ER_LOCK_DEADLOCK,ER_UPDATE_TABLE_USED +create table a as select * from A; +drop table A; + +--disable_warnings +drop table if exists a; +--enable_warnings + +set storage_engine=default; + +--echo End of 5.0 tests. diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 66bd2f67512..6e97d0faede 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -276,4 +276,9 @@ remove_file $MYSQLTEST_VARDIR/tmp/bug21412.sql; --exec $MYSQL --pager="540bytelengthstringxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -e "select 1" > /dev/null 2>&1 --exec $MYSQL --character-sets-dir="540bytelengthstringxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -e "select 1" 2>&1 +# +# bug #30164: Using client side macro inside server side comments generates broken queries +# +--exec $MYSQL test -e "/*! \C latin1 */ select 1;" + --echo End of 5.0 tests diff --git a/mysql-test/t/parser_precedence.test b/mysql-test/t/parser_precedence.test new file mode 100644 index 00000000000..484c8759779 --- /dev/null +++ b/mysql-test/t/parser_precedence.test @@ -0,0 +1,333 @@ + +--disable_warnings +drop table if exists t1_30237_bool; +--enable_warnings + +create table t1_30237_bool(A boolean, B boolean, C boolean); + +insert into t1_30237_bool values +(FALSE, FALSE, FALSE), +(FALSE, FALSE, NULL), +(FALSE, FALSE, TRUE), +(FALSE, NULL, FALSE), +(FALSE, NULL, NULL), +(FALSE, NULL, TRUE), +(FALSE, TRUE, FALSE), +(FALSE, TRUE, NULL), +(FALSE, TRUE, TRUE), +(NULL, FALSE, FALSE), +(NULL, FALSE, NULL), +(NULL, FALSE, TRUE), +(NULL, NULL, FALSE), +(NULL, NULL, NULL), +(NULL, NULL, TRUE), +(NULL, TRUE, FALSE), +(NULL, TRUE, NULL), +(NULL, TRUE, TRUE), +(TRUE, FALSE, FALSE), +(TRUE, FALSE, NULL), +(TRUE, FALSE, TRUE), +(TRUE, NULL, FALSE), +(TRUE, NULL, NULL), +(TRUE, NULL, TRUE), +(TRUE, TRUE, FALSE), +(TRUE, TRUE, NULL), +(TRUE, TRUE, TRUE) ; + +--echo Testing OR, XOR, AND +select A, B, A OR B, A XOR B, A AND B + from t1_30237_bool where C is null order by A, B; + +--echo Testing that OR is associative +select A, B, C, (A OR B) OR C, A OR (B OR C), A OR B OR C + from t1_30237_bool order by A, B, C; + +select count(*) from t1_30237_bool + where ((A OR B) OR C) != (A OR (B OR C)); + +--echo Testing that XOR is associative +select A, B, C, (A XOR B) XOR C, A XOR (B XOR C), A XOR B XOR C + from t1_30237_bool order by A, B, C; + +select count(*) from t1_30237_bool + where ((A XOR B) XOR C) != (A XOR (B XOR C)); + +--echo Testing that AND is associative +select A, B, C, (A AND B) AND C, A AND (B AND C), A AND B AND C + from t1_30237_bool order by A, B, C; + +select count(*) from t1_30237_bool + where ((A AND B) AND C) != (A AND (B AND C)); + +--echo Testing that AND has precedence over OR +select A, B, C, (A OR B) AND C, A OR (B AND C), A OR B AND C + from t1_30237_bool order by A, B, C; +select count(*) from t1_30237_bool + where (A OR (B AND C)) != (A OR B AND C); +select A, B, C, (A AND B) OR C, A AND (B OR C), A AND B OR C + from t1_30237_bool order by A, B, C; +select count(*) from t1_30237_bool + where ((A AND B) OR C) != (A AND B OR C); + +--echo Testing that AND has precedence over XOR +select A, B, C, (A XOR B) AND C, A XOR (B AND C), A XOR B AND C + from t1_30237_bool order by A, B, C; +select count(*) from t1_30237_bool + where (A XOR (B AND C)) != (A XOR B AND C); +select A, B, C, (A AND B) XOR C, A AND (B XOR C), A AND B XOR C + from t1_30237_bool order by A, B, C; +select count(*) from t1_30237_bool + where ((A AND B) XOR C) != (A AND B XOR C); + +--echo Testing that XOR has precedence over OR +select A, B, C, (A XOR B) OR C, A XOR (B OR C), A XOR B OR C + from t1_30237_bool order by A, B, C; +select count(*) from t1_30237_bool + where ((A XOR B) OR C) != (A XOR B OR C); +select A, B, C, (A OR B) XOR C, A OR (B XOR C), A OR B XOR C + from t1_30237_bool order by A, B, C; +select count(*) from t1_30237_bool + where (A OR (B XOR C)) != (A OR B XOR C); + +drop table t1_30237_bool; + +--echo Testing that NOT has precedence over OR +select (NOT FALSE) OR TRUE, NOT (FALSE OR TRUE), NOT FALSE OR TRUE; + +--echo Testing that NOT has precedence over XOR +select (NOT FALSE) XOR FALSE, NOT (FALSE XOR FALSE), NOT FALSE XOR FALSE; + +--echo Testing that NOT has precedence over AND +select (NOT FALSE) AND FALSE, NOT (FALSE AND FALSE), NOT FALSE AND FALSE; + +--echo Testing that NOT is associative +select NOT NOT TRUE, NOT NOT NOT FALSE; + +--echo Testing that IS has precedence over NOT +select (NOT NULL) IS TRUE, NOT (NULL IS TRUE), NOT NULL IS TRUE; +select (NOT NULL) IS NOT TRUE, NOT (NULL IS NOT TRUE), NOT NULL IS NOT TRUE; +select (NOT NULL) IS FALSE, NOT (NULL IS FALSE), NOT NULL IS FALSE; +select (NOT NULL) IS NOT FALSE, NOT (NULL IS NOT FALSE), NOT NULL IS NOT FALSE; +select (NOT TRUE) IS UNKNOWN, NOT (TRUE IS UNKNOWN), NOT TRUE IS UNKNOWN; +select (NOT TRUE) IS NOT UNKNOWN, NOT (TRUE IS NOT UNKNOWN), NOT TRUE IS NOT UNKNOWN; +select (NOT TRUE) IS NULL, NOT (TRUE IS NULL), NOT TRUE IS NULL; +select (NOT TRUE) IS NOT NULL, NOT (TRUE IS NOT NULL), NOT TRUE IS NOT NULL; + +--echo Testing that IS [NOT] TRUE/FALSE/UNKNOWN predicates are not associative +# Documenting existing behavior in 5.0.48 +-- error ER_PARSE_ERROR +select TRUE IS TRUE IS TRUE IS TRUE; +-- error ER_PARSE_ERROR +select FALSE IS NOT TRUE IS NOT TRUE IS NOT TRUE; +-- error ER_PARSE_ERROR +select NULL IS FALSE IS FALSE IS FALSE; +-- error ER_PARSE_ERROR +select TRUE IS NOT FALSE IS NOT FALSE IS NOT FALSE; +-- error ER_PARSE_ERROR +select FALSE IS UNKNOWN IS UNKNOWN IS UNKNOWN; +-- error ER_PARSE_ERROR +select TRUE IS NOT UNKNOWN IS NOT UNKNOWN IS NOT UNKNOWN; + +--echo Testing that IS [NOT] NULL predicates are associative +# Documenting existing behavior in 5.0.48 +select FALSE IS NULL IS NULL IS NULL; +select TRUE IS NOT NULL IS NOT NULL IS NOT NULL; + +--echo Testing that comparison operators are left associative +select 1 <=> 2 <=> 2, (1 <=> 2) <=> 2, 1 <=> (2 <=> 2); +select 1 = 2 = 2, (1 = 2) = 2, 1 = (2 = 2); +select 1 != 2 != 3, (1 != 2) != 3, 1 != (2 != 3); +select 1 <> 2 <> 3, (1 <> 2) <> 3, 1 <> (2 <> 3); +select 1 < 2 < 3, (1 < 2) < 3, 1 < (2 < 3); +select 3 <= 2 <= 1, (3 <= 2) <= 1, 3 <= (2 <= 1); +select 1 > 2 > 3, (1 > 2) > 3, 1 > (2 > 3); +select 1 >= 2 >= 3, (1 >= 2) >= 3, 1 >= (2 >= 3); + +-- echo Testing that | is associative +select 0xF0 | 0x0F | 0x55, (0xF0 | 0x0F) | 0x55, 0xF0 | (0x0F | 0x55); + +-- echo Testing that & is associative +select 0xF5 & 0x5F & 0x55, (0xF5 & 0x5F) & 0x55, 0xF5 & (0x5F & 0x55); + +-- echo Testing that << is left associative +select 4 << 3 << 2, (4 << 3) << 2, 4 << (3 << 2); + +-- echo Testing that >> is left associative +select 256 >> 3 >> 2, (256 >> 3) >> 2, 256 >> (3 >> 2); + +--echo Testing that & has precedence over | +select 0xF0 & 0x0F | 0x55, (0xF0 & 0x0F) | 0x55, 0xF0 & (0x0F | 0x55); +select 0x55 | 0xF0 & 0x0F, (0x55 | 0xF0) & 0x0F, 0x55 | (0xF0 & 0x0F); + +--echo Testing that << has precedence over | +select 0x0F << 4 | 0x0F, (0x0F << 4) | 0x0F, 0x0F << (4 | 0x0F); +select 0x0F | 0x0F << 4, (0x0F | 0x0F) << 4, 0x0F | (0x0F << 4); + +--echo Testing that >> has precedence over | +select 0xF0 >> 4 | 0xFF, (0xF0 >> 4) | 0xFF, 0xF0 >> (4 | 0xFF); +select 0xFF | 0xF0 >> 4, (0xFF | 0xF0) >> 4, 0xFF | (0xF0 >> 4); + +--echo Testing that << has precedence over & +select 0x0F << 4 & 0xF0, (0x0F << 4) & 0xF0, 0x0F << (4 & 0xF0); +select 0xF0 & 0x0F << 4, (0xF0 & 0x0F) << 4, 0xF0 & (0x0F << 4); + +--echo Testing that >> has precedence over & +select 0xF0 >> 4 & 0x55, (0xF0 >> 4) & 0x55, 0xF0 >> (4 & 0x55); +select 0x0F & 0xF0 >> 4, (0x0F & 0xF0) >> 4, 0x0F & (0xF0 >> 4); + +--echo Testing that >> and << have the same precedence +select 0xFF >> 4 << 2, (0xFF >> 4) << 2, 0xFF >> (4 << 2); +select 0x0F << 4 >> 2, (0x0F << 4) >> 2, 0x0F << (4 >> 2); + +--echo Testing that binary + is associative +select 1 + 2 + 3, (1 + 2) + 3, 1 + (2 + 3); + +--echo Testing that binary - is left associative +select 1 - 2 - 3, (1 - 2) - 3, 1 - (2 - 3); + +--echo Testing that binary + and binary - have the same precedence +# evaluated left to right +select 1 + 2 - 3, (1 + 2) - 3, 1 + (2 - 3); +select 1 - 2 + 3, (1 - 2) + 3, 1 - (2 + 3); + +--echo Testing that binary + has precedence over | +select 0xF0 + 0x0F | 0x55, (0xF0 + 0x0F) | 0x55, 0xF0 + (0x0F | 0x55); +select 0x55 | 0xF0 + 0x0F, (0x55 | 0xF0) + 0x0F, 0x55 | (0xF0 + 0x0F); + +--echo Testing that binary + has precedence over & +select 0xF0 + 0x0F & 0x55, (0xF0 + 0x0F) & 0x55, 0xF0 + (0x0F & 0x55); +select 0x55 & 0xF0 + 0x0F, (0x55 & 0xF0) + 0x0F, 0x55 & (0xF0 + 0x0F); + +--echo Testing that binary + has precedence over << +select 2 + 3 << 4, (2 + 3) << 4, 2 + (3 << 4); +select 3 << 4 + 2, (3 << 4) + 2, 3 << (4 + 2); + +--echo Testing that binary + has precedence over >> +select 4 + 3 >> 2, (4 + 3) >> 2, 4 + (3 >> 2); +select 3 >> 2 + 1, (3 >> 2) + 1, 3 >> (2 + 1); + +--echo Testing that binary - has precedence over | +select 0xFF - 0x0F | 0x55, (0xFF - 0x0F) | 0x55, 0xFF - (0x0F | 0x55); +select 0x55 | 0xFF - 0xF0, (0x55 | 0xFF) - 0xF0, 0x55 | (0xFF - 0xF0); + +--echo Testing that binary - has precedence over & +select 0xFF - 0xF0 & 0x55, (0xFF - 0xF0) & 0x55, 0xFF - (0xF0 & 0x55); +select 0x55 & 0xFF - 0xF0, (0x55 & 0xFF) - 0xF0, 0x55 & (0xFF - 0xF0); + +--echo Testing that binary - has precedence over << +select 16 - 3 << 2, (16 - 3) << 2, 16 - (3 << 2); +select 4 << 3 - 2, (4 << 3) - 2, 4 << (3 - 2); + +--echo Testing that binary - has precedence over >> +select 16 - 3 >> 2, (16 - 3) >> 2, 16 - (3 >> 2); +select 16 >> 3 - 2, (16 >> 3) - 2, 16 >> (3 - 2); + +--echo Testing that * is associative +select 2 * 3 * 4, (2 * 3) * 4, 2 * (3 * 4); + +--echo Testing that * has precedence over | +select 2 * 0x40 | 0x0F, (2 * 0x40) | 0x0F, 2 * (0x40 | 0x0F); +select 0x0F | 2 * 0x40, (0x0F | 2) * 0x40, 0x0F | (2 * 0x40); + +--echo Testing that * has precedence over & +select 2 * 0x40 & 0x55, (2 * 0x40) & 0x55, 2 * (0x40 & 0x55); +select 0xF0 & 2 * 0x40, (0xF0 & 2) * 0x40, 0xF0 & (2 * 0x40); + +--echo Testing that * has precedence over << +# Actually, can't prove it for the first case, +# since << is a multiplication by a power of 2, +# and * is associative +select 5 * 3 << 4, (5 * 3) << 4, 5 * (3 << 4); +select 2 << 3 * 4, (2 << 3) * 4, 2 << (3 * 4); + +--echo Testing that * has precedence over >> +# >> is a multiplication by a (negative) power of 2, +# see above. +select 3 * 4 >> 2, (3 * 4) >> 2, 3 * (4 >> 2); +select 4 >> 2 * 3, (4 >> 2) * 3, 4 >> (2 * 3); + +--echo Testing that * has precedence over binary + +select 2 * 3 + 4, (2 * 3) + 4, 2 * (3 + 4); +select 2 + 3 * 4, (2 + 3) * 4, 2 + (3 * 4); + +--echo Testing that * has precedence over binary - +select 4 * 3 - 2, (4 * 3) - 2, 4 * (3 - 2); +select 4 - 3 * 2, (4 - 3) * 2, 4 - (3 * 2); + +--echo Testing that / is left associative +select 15 / 5 / 3, (15 / 5) / 3, 15 / (5 / 3); + +--echo Testing that / has precedence over | +select 105 / 5 | 2, (105 / 5) | 2, 105 / (5 | 2); +select 105 | 2 / 5, (105 | 2) / 5, 105 | (2 / 5); + +--echo Testing that / has precedence over & +select 105 / 5 & 0x0F, (105 / 5) & 0x0F, 105 / (5 & 0x0F); +select 0x0F & 105 / 5, (0x0F & 105) / 5, 0x0F & (105 / 5); + +--echo Testing that / has precedence over << +select 0x80 / 4 << 2, (0x80 / 4) << 2, 0x80 / (4 << 2); +select 0x80 << 4 / 2, (0x80 << 4) / 2, 0x80 << (4 / 2); + +--echo Testing that / has precedence over >> +select 0x80 / 4 >> 2, (0x80 / 4) >> 2, 0x80 / (4 >> 2); +select 0x80 >> 4 / 2, (0x80 >> 4) / 2, 0x80 >> (4 / 2); + +--echo Testing that / has precedence over binary + +select 0x80 / 2 + 2, (0x80 / 2) + 2, 0x80 / (2 + 2); +select 0x80 + 2 / 2, (0x80 + 2) / 2, 0x80 + (2 / 2); + +--echo Testing that / has precedence over binary - +select 0x80 / 4 - 2, (0x80 / 4) - 2, 0x80 / (4 - 2); +select 0x80 - 4 / 2, (0x80 - 4) / 2, 0x80 - (4 / 2); + +# TODO: %, DIV, MOD + +--echo Testing that ^ is associative +select 0xFF ^ 0xF0 ^ 0x0F, (0xFF ^ 0xF0) ^ 0x0F, 0xFF ^ (0xF0 ^ 0x0F); +select 0xFF ^ 0xF0 ^ 0x55, (0xFF ^ 0xF0) ^ 0x55, 0xFF ^ (0xF0 ^ 0x55); + +--echo Testing that ^ has precedence over | +select 0xFF ^ 0xF0 | 0x0F, (0xFF ^ 0xF0) | 0x0F, 0xFF ^ (0xF0 | 0x0F); +select 0xF0 | 0xFF ^ 0xF0, (0xF0 | 0xFF) ^ 0xF0, 0xF0 | (0xFF ^ 0xF0); + +--echo Testing that ^ has precedence over & +select 0xFF ^ 0xF0 & 0x0F, (0xFF ^ 0xF0) & 0x0F, 0xFF ^ (0xF0 & 0x0F); +select 0x0F & 0xFF ^ 0xF0, (0x0F & 0xFF) ^ 0xF0, 0x0F & (0xFF ^ 0xF0); + +--echo Testing that ^ has precedence over << +select 0xFF ^ 0xF0 << 2, (0xFF ^ 0xF0) << 2, 0xFF ^ (0xF0 << 2); +select 0x0F << 2 ^ 0xFF, (0x0F << 2) ^ 0xFF, 0x0F << (2 ^ 0xFF); + +--echo Testing that ^ has precedence over >> +select 0xFF ^ 0xF0 >> 2, (0xFF ^ 0xF0) >> 2, 0xFF ^ (0xF0 >> 2); +select 0xFF >> 2 ^ 0xF0, (0xFF >> 2) ^ 0xF0, 0xFF >> (2 ^ 0xF0); + +--echo Testing that ^ has precedence over binary + +select 0xFF ^ 0xF0 + 0x0F, (0xFF ^ 0xF0) + 0x0F, 0xFF ^ (0xF0 + 0x0F); +select 0x0F + 0xFF ^ 0xF0, (0x0F + 0xFF) ^ 0xF0, 0x0F + (0xFF ^ 0xF0); + +--echo Testing that ^ has precedence over binary - +select 0xFF ^ 0xF0 - 1, (0xFF ^ 0xF0) - 1, 0xFF ^ (0xF0 - 1); +select 0x55 - 0x0F ^ 0x55, (0x55 - 0x0F) ^ 0x55, 0x55 - (0x0F ^ 0x55); + +--echo Testing that ^ has precedence over * +select 0xFF ^ 0xF0 * 2, (0xFF ^ 0xF0) * 2, 0xFF ^ (0xF0 * 2); +select 2 * 0xFF ^ 0xF0, (2 * 0xFF) ^ 0xF0, 2 * (0xFF ^ 0xF0); + +--echo Testing that ^ has precedence over / +select 0xFF ^ 0xF0 / 2, (0xFF ^ 0xF0) / 2, 0xFF ^ (0xF0 / 2); +select 0xF2 / 2 ^ 0xF0, (0xF2 / 2) ^ 0xF0, 0xF2 / (2 ^ 0xF0); + +--echo Testing that ^ has precedence over % +select 0xFF ^ 0xF0 % 0x20, (0xFF ^ 0xF0) % 0x20, 0xFF ^ (0xF0 % 0x20); +select 0xFF % 0x20 ^ 0xF0, (0xFF % 0x20) ^ 0xF0, 0xFF % (0x20 ^ 0xF0); + +--echo Testing that ^ has precedence over DIV +select 0xFF ^ 0xF0 DIV 2, (0xFF ^ 0xF0) DIV 2, 0xFF ^ (0xF0 DIV 2); +select 0xF2 DIV 2 ^ 0xF0, (0xF2 DIV 2) ^ 0xF0, 0xF2 DIV (2 ^ 0xF0); + +--echo Testing that ^ has precedence over MOD +select 0xFF ^ 0xF0 MOD 0x20, (0xFF ^ 0xF0) MOD 0x20, 0xFF ^ (0xF0 MOD 0x20); +select 0xFF MOD 0x20 ^ 0xF0, (0xFF MOD 0x20) ^ 0xF0, 0xFF MOD (0x20 ^ 0xF0); + diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 0b3dd89f3fa..8dd99c2b2f1 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -7300,4 +7300,58 @@ CALL p1(); SET NAMES default; DROP PROCEDURE p1; +# +# Bug#13675: DATETIME/DATE type in store proc param seems to be converted as +# varbinary +# + +--echo +--echo # Bug#13675. +--echo + +--disable_warnings +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; + +DROP TABLE IF EXISTS t1; +--enable_warnings + +--echo + +CREATE PROCEDURE p1(v DATETIME) CREATE TABLE t1 SELECT v; + +CREATE PROCEDURE p2(v INT) CREATE TABLE t1 SELECT v; + +--echo +CALL p1(NOW()); +SHOW CREATE TABLE t1; + +--echo +DROP TABLE t1; + +--echo +CALL p1('text'); +SHOW CREATE TABLE t1; + +--echo +DROP TABLE t1; + +--echo +CALL p2(10); +SHOW CREATE TABLE t1; + +--echo +DROP TABLE t1; + +--echo +CALL p2('text'); +SHOW CREATE TABLE t1; + +--echo +DROP TABLE t1; + +--echo +DROP PROCEDURE p1; +DROP PROCEDURE p2; + --echo End of 5.0 tests diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 7b6eaef08ec..8410c66b034 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1361,6 +1361,7 @@ public: Item_cond(List<Item> &nlist) :Item_bool_func(), list(nlist), abort_on_null(0) {} bool add(Item *item) { return list.push_back(item); } + bool add_at_head(Item *item) { return list.push_front(item); } void add_at_head(List<Item> *nlist) { list.prepand(nlist); } bool fix_fields(THD *, Item **ref); @@ -1553,6 +1554,15 @@ public: Item *neg_transformer(THD *thd); }; +inline bool is_cond_and(Item *item) +{ + if (item->type() != Item::COND_ITEM) + return FALSE; + + Item_cond *cond_item= (Item_cond*) item; + return (cond_item->functype() == Item_func::COND_AND_FUNC); +} + class Item_cond_or :public Item_cond { public: @@ -1574,6 +1584,14 @@ public: Item *neg_transformer(THD *thd); }; +inline bool is_cond_or(Item *item) +{ + if (item->type() != Item::COND_ITEM) + return FALSE; + + Item_cond *cond_item= (Item_cond*) item; + return (cond_item->functype() == Item_func::COND_OR_FUNC); +} /* XOR is Item_cond, not an Item_int_func because we could like to diff --git a/sql/lock.cc b/sql/lock.cc index 0036d0aef77..cf06be5f95f 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -172,6 +172,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, thd->lock_id)]; if (rc > 1) /* a timeout or a deadlock */ { + if (sql_lock->table_count) + VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count)); my_error(rc, MYF(0)); my_free((gptr) sql_lock,MYF(0)); sql_lock= 0; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index e1df1ce8d9a..9a29350880e 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1032,6 +1032,13 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) Query_cache_block_table *block_table, *block_table_end; ulong tot_length; Query_cache_query_flags flags; + const uint spin_treshold= 50000; + const double lock_time_treshold= 0.1; /* Time in seconds */ + uint spin_count= 0; + int lock_status= 0; + ulong new_time= 0; + ulong stop_time= 0; + DBUG_ENTER("Query_cache::send_result_to_client"); /* @@ -1078,7 +1085,29 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) } } - STRUCT_LOCK(&structure_guard_mutex); + stop_time= my_clock()+(ulong)lock_time_treshold*CLOCKS_PER_SEC; + while ((lock_status= pthread_mutex_trylock(&structure_guard_mutex)) == EBUSY + && spin_count < spin_treshold + && new_time < stop_time) + { + spin_count++; + if (spin_count%5) + new_time= my_clock(); + my_sleep(0); + } + + if (lock_status != 0) + { + /* + Query cache is too busy doing something else. + Fall back on ordinary statement execution. We also mark this + query as unsafe to cache because otherwise this thread will + still be halted when the result set is stored to the cache. + */ + thd->lex->safe_to_cache_query= FALSE; + goto err; + } + if (query_cache_size == 0 || flush_in_progress) { DBUG_PRINT("qcache", ("query cache disabled")); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 83c141f099f..9aefa71647e 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -440,7 +440,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, cond->cleanup(); // File was reopened if ((!cond->fixed && cond->fix_fields(thd, &cond)) || cond->check_cols(1)) - goto err0; + goto err; } if (keyname) @@ -448,13 +448,13 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, if ((keyno=find_type(keyname, &table->s->keynames, 1+2)-1)<0) { my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias); - goto err0; + goto err; } } if (insert_fields(thd, &thd->lex->select_lex.context, tables->db, tables->alias, &it, 0)) - goto err0; + goto err; protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index bd21d929291..f07af393070 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -417,7 +417,7 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, if (duplic == DUP_UPDATE || duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT) { - *lock_type= TL_WRITE; + *lock_type= TL_WRITE_DEFAULT; return; } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index d11c2b21635..f1b4ffc949d 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -526,6 +526,7 @@ static inline uint int_token(const char *str,uint length) int MYSQLlex(void *arg, void *yythd) { reg1 uchar c; + bool comment_closed; int tokval, result_state; uint length; enum my_lex_states state; @@ -961,15 +962,34 @@ int MYSQLlex(void *arg, void *yythd) break; } } - while (lip->ptr != lip->end_of_query && - ((c=yyGet()) != '*' || yyPeek() != '/')) + /* + Discard: + - regular '/' '*' comments, + - special comments '/' '*' '!' for a future version, + by scanning until we find a closing '*' '/' marker. + Note: There is no such thing as nesting comments, + the first '*' '/' sequence seen will mark the end. + */ + comment_closed= FALSE; + while (lip->ptr != lip->end_of_query) { - if (c == '\n') - lip->yylineno++; + c= yyGet(); + if (c == '*') + { + if (yyPeek() == '/') + { + yySkip(); + comment_closed= TRUE; + state = MY_LEX_START; + break; + } + } + else if (c == '\n') + lip->yylineno++; } - if (lip->ptr != lip->end_of_query) - yySkip(); // remove last '/' - state = MY_LEX_START; // Try again + /* Unbalanced comments with a missing '*' '/' are a syntax error */ + if (! comment_closed) + return (ABORT_SYM); break; case MY_LEX_END_LONG_COMMENT: if (lex->in_comment && yyPeek() == '/') @@ -1009,6 +1029,9 @@ int MYSQLlex(void *arg, void *yythd) if (lip->ptr >= lip->end_of_query) { lip->next_state=MY_LEX_END; // Mark for next loop + /* Unbalanced comments with a missing '*' '/' are a syntax error */ + if (lex->in_comment) + return (ABORT_SYM); return(END_OF_INPUT); } state=MY_LEX_CHAR; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a53cadafda8..e0b9ab28594 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -458,10 +458,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %pure_parser /* We have threads */ /* - Currently there is 251 shift/reduce conflict. We should not introduce - new conflicts any more. + Currently there are 245 shift/reduce conflicts. + We should not introduce new conflicts any more. */ -%expect 251 +%expect 245 %token END_OF_INPUT @@ -1011,7 +1011,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); /* A dummy token to force the priority of table_ref production in a join. */ %left TABLE_REF_PRIORITY %left SET_VAR -%left OR_OR_SYM OR_SYM OR2_SYM XOR +%left OR_OR_SYM OR_SYM OR2_SYM +%left XOR %left AND_SYM AND_AND_SYM %left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE %left EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM @@ -1024,6 +1025,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %left NEG '~' %right NOT_SYM NOT2_SYM %right BINARY COLLATE_SYM +%left INTERVAL_SYM %type <lex_str> IDENT IDENT_QUOTED TEXT_STRING DECIMAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM @@ -1066,8 +1068,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <item> literal text_literal insert_ident order_ident simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr - variable variable_aux bool_term bool_factor bool_test bool_pri - predicate bit_expr bit_term bit_factor value_expr term factor + variable variable_aux + bool_pri + predicate bit_expr table_wild simple_expr udf_expr expr_or_default set_expr_or_default interval_expr param_marker geometry_function @@ -4464,77 +4467,126 @@ optional_braces: | '(' ')' {}; /* all possible expressions */ -expr: - bool_term { Select->expr_list.push_front(new List<Item>); } - bool_or_expr +expr: + expr or expr %prec OR_SYM { - List<Item> *list= Select->expr_list.pop(); - if (list->elements) + /* + Design notes: + Do not use a manually maintained stack like thd->lex->xxx_list, + but use the internal bison stack ($$, $1 and $3) instead. + Using the bison stack is: + - more robust to changes in the grammar, + - guaranteed to be in sync with the parser state, + - better for performances (no memory allocation). + */ + Item_cond_or *item1; + Item_cond_or *item3; + if (is_cond_or($1)) { - list->push_front($1); - $$= new Item_cond_or(*list); - /* optimize construction of logical OR to reduce - amount of objects for complex expressions */ + item1= (Item_cond_or*) $1; + if (is_cond_or($3)) + { + item3= (Item_cond_or*) $3; + /* + (X1 OR X2) OR (Y1 OR Y2) ==> OR (X1, X2, Y1, Y2) + */ + item3->add_at_head(item1->argument_list()); + $$ = $3; + } + else + { + /* + (X1 OR X2) OR Y ==> OR (X1, X2, Y) + */ + item1->add($3); + $$ = $1; + } + } + else if (is_cond_or($3)) + { + item3= (Item_cond_or*) $3; + /* + X OR (Y1 OR Y2) ==> OR (X, Y1, Y2) + */ + item3->add_at_head($1); + $$ = $3; } else - $$= $1; - delete list; + { + /* X OR Y */ + $$ = new (YYTHD->mem_root) Item_cond_or($1, $3); + } } - ; - -bool_or_expr: - /* empty */ - | bool_or_expr or bool_term - { Select->expr_list.head()->push_back($3); } - ; - -bool_term: - bool_term XOR bool_term { $$= new Item_cond_xor($1,$3); } - | bool_factor { Select->expr_list.push_front(new List<Item>); } - bool_and_expr + | expr XOR expr %prec XOR + { + /* XOR is a proprietary extension */ + $$ = new (YYTHD->mem_root) Item_cond_xor($1, $3); + } + | expr and expr %prec AND_SYM { - List<Item> *list= Select->expr_list.pop(); - if (list->elements) + /* See comments in rule expr: expr or expr */ + Item_cond_and *item1; + Item_cond_and *item3; + if (is_cond_and($1)) + { + item1= (Item_cond_and*) $1; + if (is_cond_and($3)) + { + item3= (Item_cond_and*) $3; + /* + (X1 AND X2) AND (Y1 AND Y2) ==> AND (X1, X2, Y1, Y2) + */ + item3->add_at_head(item1->argument_list()); + $$ = $3; + } + else + { + /* + (X1 AND X2) AND Y ==> AND (X1, X2, Y) + */ + item1->add($3); + $$ = $1; + } + } + else if (is_cond_and($3)) { - list->push_front($1); - $$= new Item_cond_and(*list); - /* optimize construction of logical AND to reduce - amount of objects for complex expressions */ + item3= (Item_cond_and*) $3; + /* + X AND (Y1 AND Y2) ==> AND (X, Y1, Y2) + */ + item3->add_at_head($1); + $$ = $3; } else - $$= $1; - delete list; + { + /* X AND Y */ + $$ = new (YYTHD->mem_root) Item_cond_and($1, $3); + } } - ; - -bool_and_expr: - /* empty */ - | bool_and_expr and bool_factor - { Select->expr_list.head()->push_back($3); } - ; - -bool_factor: - NOT_SYM bool_factor { $$= negate_expression(YYTHD, $2); } - | bool_test ; - -bool_test: - bool_pri IS TRUE_SYM + | NOT_SYM expr %prec NOT_SYM + { $$= negate_expression(YYTHD, $2); } + | bool_pri IS TRUE_SYM %prec IS { $$= new (YYTHD->mem_root) Item_func_istrue($1); } - | bool_pri IS not TRUE_SYM + | bool_pri IS not TRUE_SYM %prec IS { $$= new (YYTHD->mem_root) Item_func_isnottrue($1); } - | bool_pri IS FALSE_SYM + | bool_pri IS FALSE_SYM %prec IS { $$= new (YYTHD->mem_root) Item_func_isfalse($1); } - | bool_pri IS not FALSE_SYM + | bool_pri IS not FALSE_SYM %prec IS { $$= new (YYTHD->mem_root) Item_func_isnotfalse($1); } - | bool_pri IS UNKNOWN_SYM { $$= new Item_func_isnull($1); } - | bool_pri IS not UNKNOWN_SYM { $$= new Item_func_isnotnull($1); } + | bool_pri IS UNKNOWN_SYM %prec IS + { $$= new Item_func_isnull($1); } + | bool_pri IS not UNKNOWN_SYM %prec IS + { $$= new Item_func_isnotnull($1); } | bool_pri ; bool_pri: - bool_pri IS NULL_SYM { $$= new Item_func_isnull($1); } - | bool_pri IS not NULL_SYM { $$= new Item_func_isnotnull($1); } - | bool_pri EQUAL_SYM predicate { $$= new Item_func_equal($1,$3); } + bool_pri IS NULL_SYM %prec IS + { $$= new Item_func_isnull($1); } + | bool_pri IS not NULL_SYM %prec IS + { $$= new Item_func_isnotnull($1); } + | bool_pri EQUAL_SYM predicate %prec EQUAL_SYM + { $$= new Item_func_equal($1,$3); } | bool_pri comp_op predicate %prec EQ { $$= (*$2)(0)->create($1,$3); } | bool_pri comp_op all_or_any '(' subselect ')' %prec EQ @@ -4577,11 +4629,11 @@ predicate: | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate { $$= new Item_func_between($1,$3,$5); } | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate - { - Item_func_between *item= new Item_func_between($1,$4,$6); - item->negate(); - $$= item; - } + { + Item_func_between *item= new Item_func_between($1,$4,$6); + item->negate(); + $$= item; + } | bit_expr SOUNDS_SYM LIKE bit_expr { $$= new Item_func_eq(new Item_func_soundex($1), new Item_func_soundex($4)); } @@ -4595,40 +4647,36 @@ predicate: | bit_expr ; bit_expr: - bit_expr '|' bit_term { $$= new Item_func_bit_or($1,$3); } - | bit_term ; - -bit_term: - bit_term '&' bit_factor { $$= new Item_func_bit_and($1,$3); } - | bit_factor ; - -bit_factor: - bit_factor SHIFT_LEFT value_expr - { $$= new Item_func_shift_left($1,$3); } - | bit_factor SHIFT_RIGHT value_expr - { $$= new Item_func_shift_right($1,$3); } - | value_expr ; - -value_expr: - value_expr '+' term { $$= new Item_func_plus($1,$3); } - | value_expr '-' term { $$= new Item_func_minus($1,$3); } - | value_expr '+' interval_expr interval - { $$= new Item_date_add_interval($1,$3,$4,0); } - | value_expr '-' interval_expr interval - { $$= new Item_date_add_interval($1,$3,$4,1); } - | term ; - -term: - term '*' factor { $$= new Item_func_mul($1,$3); } - | term '/' factor { $$= new Item_func_div($1,$3); } - | term '%' factor { $$= new Item_func_mod($1,$3); } - | term DIV_SYM factor { $$= new Item_func_int_div($1,$3); } - | term MOD_SYM factor { $$= new Item_func_mod($1,$3); } - | factor ; - -factor: - factor '^' simple_expr { $$= new Item_func_bit_xor($1,$3); } - | simple_expr ; + bit_expr '|' bit_expr %prec '|' + { $$= new Item_func_bit_or($1,$3); } + | bit_expr '&' bit_expr %prec '&' + { $$= new Item_func_bit_and($1,$3); } + | bit_expr SHIFT_LEFT bit_expr %prec SHIFT_LEFT + { $$= new Item_func_shift_left($1,$3); } + | bit_expr SHIFT_RIGHT bit_expr %prec SHIFT_RIGHT + { $$= new Item_func_shift_right($1,$3); } + | bit_expr '+' bit_expr %prec '+' + { $$= new Item_func_plus($1,$3); } + | bit_expr '-' bit_expr %prec '-' + { $$= new Item_func_minus($1,$3); } + | bit_expr '+' interval_expr interval %prec '+' + { $$= new Item_date_add_interval($1,$3,$4,0); } + | bit_expr '-' interval_expr interval %prec '-' + { $$= new Item_date_add_interval($1,$3,$4,1); } + | bit_expr '*' bit_expr %prec '*' + { $$= new Item_func_mul($1,$3); } + | bit_expr '/' bit_expr %prec '/' + { $$= new Item_func_div($1,$3); } + | bit_expr '%' bit_expr %prec '%' + { $$= new Item_func_mod($1,$3); } + | bit_expr DIV_SYM bit_expr %prec DIV_SYM + { $$= new Item_func_int_div($1,$3); } + | bit_expr MOD_SYM bit_expr %prec MOD_SYM + { $$= new Item_func_mod($1,$3); } + | bit_expr '^' bit_expr + { $$= new Item_func_bit_xor($1,$3); } + | simple_expr + ; or: OR_SYM | OR2_SYM; and: AND_SYM | AND_AND_SYM; @@ -4648,7 +4696,8 @@ all_or_any: ALL { $$ = 1; } ; interval_expr: - INTERVAL_SYM expr { $$=$2; } + INTERVAL_SYM expr %prec INTERVAL_SYM + { $$=$2; } ; simple_expr: |