diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2023-04-21 09:10:58 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2023-04-21 09:10:58 +0200 |
commit | 3d27f6d7f46121ba0b945818e59ec221c77ad378 (patch) | |
tree | e48f88ba77d3826eb76ca08ca7c836cec7b975ab | |
parent | fc6e8a3d3264078bed28632a289130b1dc24daea (diff) | |
parent | 4c4939bbf619d7e516131c0b3e5691b1c2d2ff8f (diff) | |
download | mariadb-git-3d27f6d7f46121ba0b945818e59ec221c77ad378.tar.gz |
Merge branch '10.3' into 10.4
-rw-r--r-- | debian/control | 1 | ||||
-rw-r--r-- | mysql-test/lib/My/CoreDump.pm | 33 | ||||
-rw-r--r-- | mysql-test/main/bootstrap.result | 45 | ||||
-rw-r--r-- | mysql-test/main/bootstrap.test | 107 | ||||
-rw-r--r-- | mysql-test/main/derived.result | 23 | ||||
-rw-r--r-- | mysql-test/main/derived.test | 30 | ||||
-rw-r--r-- | mysql-test/main/parser.result | 28 | ||||
-rw-r--r-- | mysql-test/main/parser.test | 17 | ||||
-rw-r--r-- | sql/mysqld.cc | 5 | ||||
-rw-r--r-- | sql/sql_derived.cc | 3 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 54 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 54 | ||||
-rw-r--r-- | storage/spider/mysql-test/spider/bugfix/r/mdev_29644.result | 41 | ||||
-rw-r--r-- | storage/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf | 3 | ||||
-rw-r--r-- | storage/spider/mysql-test/spider/bugfix/t/mdev_29644.test | 56 | ||||
-rw-r--r-- | storage/spider/spd_db_mysql.cc | 88 | ||||
-rw-r--r-- | storage/spider/spd_db_mysql.h | 4 |
17 files changed, 413 insertions, 179 deletions
diff --git a/debian/control b/debian/control index 85d131bbd11..c14a6f7dd93 100644 --- a/debian/control +++ b/debian/control @@ -552,6 +552,7 @@ Depends: libxml2, unixodbc, ${misc:Depends}, ${shlibs:Depends} +Recommends: curl Breaks: mariadb-connect-engine-10.1, mariadb-connect-engine-10.2, mariadb-connect-engine-10.3 diff --git a/mysql-test/lib/My/CoreDump.pm b/mysql-test/lib/My/CoreDump.pm index 05b6edf1385..be6d21146d1 100644 --- a/mysql-test/lib/My/CoreDump.pm +++ b/mysql-test/lib/My/CoreDump.pm @@ -310,16 +310,8 @@ sub cdb_check { `cdb -? 2>&1`; if ($? >> 8) { - print "Cannot find cdb. Please Install Debugging tools for Windows\n"; - print "from http://www.microsoft.com/whdc/devtools/debugging/"; - if($ENV{'ProgramW6432'}) - { - print "install64bit.mspx (native x64 version)\n"; - } - else - { - print "installx86.mspx\n"; - } + print "Cannot find the cdb debugger. Please install Debugging tools for Windows\n"; + print "and set PATH environment variable to include location of cdb.exe"; } } @@ -328,25 +320,6 @@ sub _cdb { my ($core_name, $format)= @_; print "\nTrying 'cdb' to get a backtrace\n"; return unless -f $core_name; - - # Try to set environment for debugging tools for Windows - if ($ENV{'PATH'} !~ /Debugging Tools/) - { - if ($ENV{'ProgramW6432'}) - { - # On x64 computer - $ENV{'PATH'}.= ";".$ENV{'ProgramW6432'}."\\Debugging Tools For Windows (x64)"; - } - else - { - # On x86 computer. Newest versions of Debugging tools are installed in the - # directory with (x86) suffix, older versions did not have this suffix. - $ENV{'PATH'}.= ";".$ENV{'ProgramFiles'}."\\Debugging Tools For Windows (x86)"; - $ENV{'PATH'}.= ";".$ENV{'ProgramFiles'}."\\Debugging Tools For Windows"; - } - } - - # Read module list, find out the name of executable and # build symbol path (required by cdb if executable was built on # different machine) @@ -384,7 +357,7 @@ sub _cdb { if (!$ENV{'_NT_SYMBOL_PATH'}) { my $windir= $ENV{'windir'}; - my $symbol_cache= substr($windir ,0, index($windir,'\\'))."\\cdb_symbols"; + my $symbol_cache= substr($windir ,0, index($windir,'\\'))."\\symbols"; print "OS debug symbols will be downloaded and stored in $symbol_cache.\n"; print "You can control the location of symbol cache with _NT_SYMBOL_PATH\n"; diff --git a/mysql-test/main/bootstrap.result b/mysql-test/main/bootstrap.result index 6801791221e..7cd8a851e56 100644 --- a/mysql-test/main/bootstrap.result +++ b/mysql-test/main/bootstrap.result @@ -1,15 +1,28 @@ -drop table if exists t1; +# +# test mysqld in bootstrap mode +# +# +# Check that --bootstrap reads from stdin +# # Kill the server # restart drop table t1; +# +# Check that --bootstrap of file with SQL error returns error +# # Kill the server # restart drop table t1; ERROR 42S02: Unknown table 'test.t1' +# +# Bootstrap with a large thd->net.max_packet +# # Kill the server # restart drop table t1; -End of 5.1 tests +# +# End of 5.1 tests +# # # Bug #11766306: 59393: HAVE_INNODB=YES WHEN MYSQLD # STARTED WITH --SKIP-INNODB @@ -18,9 +31,23 @@ SELECT 'bug' as '' FROM INFORMATION_SCHEMA.ENGINES WHERE engine='innodb' and SUPPORT='YES'; # Kill the server +# +# MDEV-13063 Server crashes in intern_plugin_lock or assertion `plugin_ptr->ref_count == 1' fails in plugin_init +# +# +# MDEV-19349 mysql_install_db: segfault at tmp_file_prefix check +# # restart -End of 5.5 tests +# +# End of 5.5 tests +# +# +# Check that --bootstrap can install and uninstall plugins +# # Kill the server +# +# Check that installed plugins are *not* automatically loaded in --bootstrap +# # restart flush tables; show create table t1; @@ -34,4 +61,16 @@ name dl EXAMPLE ha_example.so truncate table mysql.plugin; # Kill the server +# +# MDEV-9969 mysql_install_db error processing ignore_db_dirs. +# +# +# MDEV-13397 MariaDB upgrade fail when using default_time_zone +# +# +# MDEV-30818 invalid ssl prevents bootstrap +# # restart +# +# End of 10.3 tests +# diff --git a/mysql-test/main/bootstrap.test b/mysql-test/main/bootstrap.test index 1c8dafd8f28..8eee907e166 100644 --- a/mysql-test/main/bootstrap.test +++ b/mysql-test/main/bootstrap.test @@ -1,17 +1,20 @@ +--echo # +--echo # test mysqld in bootstrap mode +--echo # --source include/not_embedded.inc -# -# test mysqld in bootstrap mode -# ---disable_warnings -drop table if exists t1; ---enable_warnings +--source include/have_example_plugin.inc + +--let test_bootstrap=$MYSQLTEST_VARDIR/tmp/test_bootstrap.sql +--write_file $test_bootstrap +use test; +EOF # Add the datadir to the bootstrap command let $MYSQLD_DATADIR= `select @@datadir`; let $MYSQLD_BOOTSTRAP_CMD= $MYSQLD_BOOTSTRAP_CMD --datadir=$MYSQLD_DATADIR --tmpdir=$MYSQL_TMP_DIR --default-storage-engine=MyISAM --loose-skip-innodb --plugin-maturity=unknown; -# -# Check that --bootstrap reads from stdin -# +--echo # +--echo # Check that --bootstrap reads from stdin +--echo # --write_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql use test; CREATE TABLE t1(a int); @@ -21,9 +24,9 @@ EOF --source include/start_mysqld.inc drop table t1; remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql; -# -# Check that --bootstrap of file with SQL error returns error -# +--echo # +--echo # Check that --bootstrap of file with SQL error returns error +--echo # --write_file $MYSQLTEST_VARDIR/tmp/bootstrap_error.sql use test; CREATE TABLE t1; @@ -37,9 +40,9 @@ EOF drop table t1; remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_error.sql; -# -# Bootstrap with a large thd->net.max_packet -# +--echo # +--echo # Bootstrap with a large thd->net.max_packet +--echo # --disable_query_log create table t1 select 2 as a, concat(repeat('MySQL', @@max_allowed_packet/10), ';') as b; eval select * into outfile '$MYSQLTEST_VARDIR/tmp/long_query.sql' from t1; @@ -51,7 +54,9 @@ remove_file $MYSQLTEST_VARDIR/tmp/long_query.sql; --source include/start_mysqld.inc drop table t1; ---echo End of 5.1 tests +--echo # +--echo # End of 5.1 tests +--echo # --echo # --echo # Bug #11766306: 59393: HAVE_INNODB=YES WHEN MYSQLD @@ -63,29 +68,25 @@ SELECT 'bug' as '' FROM INFORMATION_SCHEMA.ENGINES WHERE engine='innodb' and SUPPORT='YES'; --source include/kill_mysqld.inc -# -# MDEV-13063 Server crashes in intern_plugin_lock or assertion `plugin_ptr->ref_count == 1' fails in plugin_init -# +--echo # +--echo # MDEV-13063 Server crashes in intern_plugin_lock or assertion `plugin_ptr->ref_count == 1' fails in plugin_init +--echo # --error 1 --exec $MYSQLD_BOOTSTRAP_CMD --myisam_recover_options=NONE -# -# MDEV-19349 mysql_install_db: segfault at tmp_file_prefix check -# ---write_file $MYSQLTEST_VARDIR/tmp/1 -use test; -EOF ---exec $MYSQLD_BOOTSTRAP_CMD < $MYSQLTEST_VARDIR/tmp/1 >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 ---remove_file $MYSQLTEST_VARDIR/tmp/1 +--echo # +--echo # MDEV-19349 mysql_install_db: segfault at tmp_file_prefix check +--echo # +--exec $MYSQLD_BOOTSTRAP_CMD < $test_bootstrap >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 --source include/start_mysqld.inc ---echo End of 5.5 tests +--echo # +--echo # End of 5.5 tests +--echo # ---source include/not_windows_embedded.inc ---source include/have_example_plugin.inc -# -# Check that --bootstrap can install and uninstall plugins -# +--echo # +--echo # Check that --bootstrap can install and uninstall plugins +--echo # let $PLUGIN_DIR=`select @@plugin_dir`; --source include/kill_mysqld.inc --write_file $MYSQLTEST_VARDIR/tmp/install_plugin.sql @@ -95,9 +96,9 @@ EOF --exec $MYSQLD_BOOTSTRAP_CMD --plugin-dir=$PLUGIN_DIR < $MYSQLTEST_VARDIR/tmp/install_plugin.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 --remove_file $MYSQLTEST_VARDIR/tmp/install_plugin.sql -# -# Check that installed plugins are *not* automatically loaded in --bootstrap -# +--echo # +--echo # Check that installed plugins are *not* automatically loaded in --bootstrap +--echo # --write_file $MYSQLTEST_VARDIR/tmp/bootstrap_plugins.sql SET SQL_MODE=""; use test; @@ -113,24 +114,24 @@ drop table t1; select * from mysql.plugin; truncate table mysql.plugin; - -# -# MDEV-9969 mysql_install_db error processing ignore_db_dirs. -# ---write_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql -use test; -EOF --source include/kill_mysqld.inc ---exec $MYSQLD_BOOTSTRAP_CMD --ignore-db-dirs='some_dir' --ignore-db-dirs='some_dir' < $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 ---remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql +--echo # +--echo # MDEV-9969 mysql_install_db error processing ignore_db_dirs. +--echo # +--exec $MYSQLD_BOOTSTRAP_CMD --ignore-db-dirs='some_dir' --ignore-db-dirs='some_dir' < $test_bootstrap >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 -# -# MDEV-13397 MariaDB upgrade fail when using default_time_zone -# ---write_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql -use test; -EOF ---exec $MYSQLD_BOOTSTRAP_CMD --default-time-zone=Europe/Moscow < $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 ---remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql +--echo # +--echo # MDEV-13397 MariaDB upgrade fail when using default_time_zone +--echo # +--exec $MYSQLD_BOOTSTRAP_CMD --default-time-zone=Europe/Moscow < $test_bootstrap >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 + +--echo # +--echo # MDEV-30818 invalid ssl prevents bootstrap +--echo # +--exec $MYSQLD_BOOTSTRAP_CMD --ssl-ca=/dev/nonexistent < $test_bootstrap >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 --source include/start_mysqld.inc +--echo # +--echo # End of 10.3 tests +--echo # +--remove_file $test_bootstrap diff --git a/mysql-test/main/derived.result b/mysql-test/main/derived.result index bee77be2e11..a9d97132535 100644 --- a/mysql-test/main/derived.result +++ b/mysql-test/main/derived.result @@ -1327,5 +1327,28 @@ a b DROP VIEW v1; DROP TABLE t1; # +# MDEV-28616: derived table over union with order by clause that +# contains subquery with unresolvable column reference +# +SELECT 1 FROM ( +SELECT 1 UNION SELECT 2 ORDER BY (SELECT 1 FROM DUAL WHERE xxx = 0) +) dt; +ERROR 42S22: Unknown column 'xxx' in 'where clause' +create table t1 (a int, b int); +insert into t1 values (3,8), (7,2), (1,4), (5,9); +create table t2 (a int, b int); +insert into t2 values (9,1), (7,3), (2,6); +create table t3 (c int, d int); +insert into t3 values (7,8), (1,2), (3,8); +select * from +( +select a,b from t1 where t1.a > 3 +union +select a,b from t2 where t2.b < 6 +order by (a - b / (select a + max(c) from t3 where d = x)) +) dt; +ERROR 42S22: Unknown column 'x' in 'where clause' +drop table t1,t2,t3; +# # End of 10.3 tests # diff --git a/mysql-test/main/derived.test b/mysql-test/main/derived.test index 6a831000e57..dca7243febb 100644 --- a/mysql-test/main/derived.test +++ b/mysql-test/main/derived.test @@ -1138,5 +1138,35 @@ DROP VIEW v1; DROP TABLE t1; --echo # +--echo # MDEV-28616: derived table over union with order by clause that +--echo # contains subquery with unresolvable column reference +--echo # + +--error ER_BAD_FIELD_ERROR +SELECT 1 FROM ( + SELECT 1 UNION SELECT 2 ORDER BY (SELECT 1 FROM DUAL WHERE xxx = 0) +) dt; + +create table t1 (a int, b int); +insert into t1 values (3,8), (7,2), (1,4), (5,9); + +create table t2 (a int, b int); +insert into t2 values (9,1), (7,3), (2,6); + +create table t3 (c int, d int); +insert into t3 values (7,8), (1,2), (3,8); + +--error ER_BAD_FIELD_ERROR +select * from +( + select a,b from t1 where t1.a > 3 + union + select a,b from t2 where t2.b < 6 + order by (a - b / (select a + max(c) from t3 where d = x)) +) dt; + +drop table t1,t2,t3; + +--echo # --echo # End of 10.3 tests --echo # diff --git a/mysql-test/main/parser.result b/mysql-test/main/parser.result index 32cc70bf50c..91bb051b75b 100644 --- a/mysql-test/main/parser.result +++ b/mysql-test/main/parser.result @@ -1873,12 +1873,32 @@ SET @@sql_mode=@save_sql_mode; # # MDEV-30151 parse error 1=2 not between/in # -select 1=2 not in (3,4); -1=2 not in (3,4) +SELECT 1=2 NOT IN (3,4); +1=2 NOT IN (3,4) 1 -select 1=2 not between 3 and 4; -1=2 not between 3 and 4 +SELECT 1=2 NOT BETWEEN 3 AND 4; +1=2 NOT BETWEEN 3 AND 4 1 +CREATE TABLE t1 ( f INT AS ( 1 IN ( 2 NOT BETWEEN 3 AND 4 ) ) ); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f` int(11) GENERATED ALWAYS AS (1 = 2 not between 3 and 4) VIRTUAL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1; +CREATE TABLE t1 ( f INT, CHECK ( 1 IN ( 2 NOT BETWEEN 3 AND 4 ) ) ); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f` int(11) DEFAULT NULL, + CONSTRAINT `CONSTRAINT_1` CHECK (1 = 2 not between 3 and 4) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t1; +CREATE VIEW v1 AS SELECT 1 IN ( 2 NOT BETWEEN 3 AND 4 ); +SHOW CREATE VIEW v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 = 2 not between 3 and 4 AS `1 IN ( 2 NOT BETWEEN 3 AND 4 )` latin1 latin1_swedish_ci +DROP VIEW v1; # # End of 10.3 tests # diff --git a/mysql-test/main/parser.test b/mysql-test/main/parser.test index 13126b77f78..ee0b8e819b4 100644 --- a/mysql-test/main/parser.test +++ b/mysql-test/main/parser.test @@ -1681,8 +1681,21 @@ SET @@sql_mode=@save_sql_mode; --echo # --echo # MDEV-30151 parse error 1=2 not between/in --echo # -select 1=2 not in (3,4); -select 1=2 not between 3 and 4; + +SELECT 1=2 NOT IN (3,4); +SELECT 1=2 NOT BETWEEN 3 AND 4; + +CREATE TABLE t1 ( f INT AS ( 1 IN ( 2 NOT BETWEEN 3 AND 4 ) ) ); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 ( f INT, CHECK ( 1 IN ( 2 NOT BETWEEN 3 AND 4 ) ) ); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE VIEW v1 AS SELECT 1 IN ( 2 NOT BETWEEN 3 AND 4 ); +SHOW CREATE VIEW v1; +DROP VIEW v1; --echo # --echo # End of 10.3 tests diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 23494d8aff0..228a3d909e2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4747,7 +4747,10 @@ static void init_ssl() { sql_print_error("Failed to setup SSL"); sql_print_error("SSL error: %s", sslGetErrString(error)); - unireg_abort(1); + if (!opt_bootstrap) + unireg_abort(1); + opt_use_ssl = 0; + have_ssl= SHOW_OPTION_DISABLED; } else ssl_acceptor_stats.init(); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 2e232730799..c8a335497e9 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -787,6 +787,9 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) cursor->outer_join|= JOIN_TYPE_OUTER; } } + // Prevent it for possible ORDER BY clause + if (unit->fake_select_lex) + unit->fake_select_lex->context.outer_context= 0; if (unlikely(thd->trace_started())) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 902b7d16022..20fc299624f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -834,7 +834,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); /* We should not introduce any further shift/reduce conflicts. */ -%expect 83 +%expect 65 /* Comments for TOKENS. @@ -1631,7 +1631,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %left PREC_BELOW_NOT -%nonassoc LOW_PRIORITY_NOT +/* The precendence of boolean NOT is in fact here. See the comment below. */ + %left '=' EQUAL_SYM GE '>' LE '<' NE %nonassoc IS %right BETWEEN_SYM @@ -1643,6 +1644,24 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %left '*' '/' '%' DIV_SYM MOD_SYM %left '^' %left MYSQL_CONCAT_SYM +/* + Boolean negation has a special branch in "expr" starting with NOT_SYM. + The precedence of logical negation is determined by the grammar itself + (without using Bison terminal symbol precedence) in this order + - Boolean factor (i.e. logical AND) + - Boolean NOT + - Boolean test (such as '=', IS NULL, IS TRUE) + + But we also need a precedence for NOT_SYM in other contexts, + to shift (without reduce) in these cases: + predicate <here> NOT IN ... + predicate <here> NOT BETWEEN ... + predicate <here> NOT LIKE ... + predicate <here> NOT REGEXP ... + If the precedence of NOT_SYM was low, it would reduce immediately + after scanning "predicate" and then produce a syntax error on "NOT". +*/ +%nonassoc NOT_SYM %nonassoc NEG '~' NOT2_SYM BINARY %nonassoc COLLATE_SYM %nonassoc SUBQUERY_AS_EXPR @@ -1886,6 +1905,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); literal insert_ident order_ident temporal_literal simple_ident expr sum_expr in_sum_expr variable variable_aux + boolean_test predicate bit_expr parenthesized_expr table_wild simple_expr column_default_non_parenthesized_expr udf_expr primary_expr string_factor_expr mysql_concatenation_expr @@ -10065,79 +10085,83 @@ expr: MYSQL_YYABORT; } } - | NOT_SYM expr %prec LOW_PRIORITY_NOT + | NOT_SYM expr { $$= negate_expression(thd, $2); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS TRUE_SYM %prec IS + | boolean_test %prec PREC_BELOW_NOT + ; + +boolean_test: + boolean_test IS TRUE_SYM %prec IS { $$= new (thd->mem_root) Item_func_istrue(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS not TRUE_SYM %prec IS + | boolean_test IS not TRUE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnottrue(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS FALSE_SYM %prec IS + | boolean_test IS FALSE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isfalse(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS not FALSE_SYM %prec IS + | boolean_test IS not FALSE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotfalse(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS UNKNOWN_SYM %prec IS + | boolean_test IS UNKNOWN_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnull(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS not UNKNOWN_SYM %prec IS + | boolean_test IS not UNKNOWN_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotnull(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS NULL_SYM %prec PREC_BELOW_NOT + | boolean_test IS NULL_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnull(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS not NULL_SYM %prec IS + | boolean_test IS not NULL_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotnull(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr EQUAL_SYM predicate %prec EQUAL_SYM + | boolean_test EQUAL_SYM predicate %prec EQUAL_SYM { $$= new (thd->mem_root) Item_func_equal(thd, $1, $3); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr comp_op predicate %prec '=' + | boolean_test comp_op predicate %prec '=' { $$= (*$2)(0)->create(thd, $1, $3); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr comp_op all_or_any '(' subselect ')' %prec '=' + | boolean_test comp_op all_or_any '(' subselect ')' %prec '=' { $$= all_any_subquery_creator(thd, $1, $2, $3, $5); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | predicate + | predicate %prec BETWEEN_SYM ; predicate: diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 1e1af943d83..afc1b007b11 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -310,7 +310,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); /* We should not introduce any further shift/reduce conflicts. */ -%expect 84 +%expect 66 /* Comments for TOKENS. @@ -1107,7 +1107,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %left PREC_BELOW_NOT -%nonassoc LOW_PRIORITY_NOT +/* The precendence of boolean NOT is in fact here. See the comment below. */ + %left '=' EQUAL_SYM GE '>' LE '<' NE %nonassoc IS %right BETWEEN_SYM @@ -1119,6 +1120,24 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %left '*' '/' '%' DIV_SYM MOD_SYM %left '^' %left MYSQL_CONCAT_SYM +/* + Boolean negation has a special branch in "expr" starting with NOT_SYM. + The precedence of logical negation is determined by the grammar itself + (without using Bison terminal symbol precedence) in this order + - Boolean factor (i.e. logical AND) + - Boolean NOT + - Boolean test (such as '=', IS NULL, IS TRUE) + + But we also need a precedence for NOT_SYM in other contexts, + to shift (without reduce) in these cases: + predicate <here> NOT IN ... + predicate <here> NOT BETWEEN ... + predicate <here> NOT LIKE ... + predicate <here> NOT REGEXP ... + If the precedence of NOT_SYM was low, it would reduce immediately + after scanning "predicate" and then produce a syntax error on "NOT". +*/ +%nonassoc NOT_SYM %nonassoc NEG '~' NOT2_SYM BINARY %nonassoc COLLATE_SYM %nonassoc SUBQUERY_AS_EXPR @@ -1369,6 +1388,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); literal insert_ident order_ident temporal_literal simple_ident expr sum_expr in_sum_expr variable variable_aux + boolean_test predicate bit_expr parenthesized_expr table_wild simple_expr column_default_non_parenthesized_expr udf_expr primary_expr string_factor_expr mysql_concatenation_expr @@ -10180,79 +10200,83 @@ expr: MYSQL_YYABORT; } } - | NOT_SYM expr %prec LOW_PRIORITY_NOT + | NOT_SYM expr { $$= negate_expression(thd, $2); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS TRUE_SYM %prec IS + | boolean_test %prec PREC_BELOW_NOT + ; + +boolean_test: + boolean_test IS TRUE_SYM %prec IS { $$= new (thd->mem_root) Item_func_istrue(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS not TRUE_SYM %prec IS + | boolean_test IS not TRUE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnottrue(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS FALSE_SYM %prec IS + | boolean_test IS FALSE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isfalse(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS not FALSE_SYM %prec IS + | boolean_test IS not FALSE_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotfalse(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS UNKNOWN_SYM %prec IS + | boolean_test IS UNKNOWN_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnull(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS not UNKNOWN_SYM %prec IS + | boolean_test IS not UNKNOWN_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotnull(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS NULL_SYM %prec PREC_BELOW_NOT + | boolean_test IS NULL_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnull(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr IS not NULL_SYM %prec IS + | boolean_test IS not NULL_SYM %prec IS { $$= new (thd->mem_root) Item_func_isnotnull(thd, $1); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr EQUAL_SYM predicate %prec EQUAL_SYM + | boolean_test EQUAL_SYM predicate %prec EQUAL_SYM { $$= new (thd->mem_root) Item_func_equal(thd, $1, $3); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr comp_op predicate %prec '=' + | boolean_test comp_op predicate %prec '=' { $$= (*$2)(0)->create(thd, $1, $3); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | expr comp_op all_or_any '(' subselect ')' %prec '=' + | boolean_test comp_op all_or_any '(' subselect ')' %prec '=' { $$= all_any_subquery_creator(thd, $1, $2, $3, $5); if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | predicate + | predicate %prec BETWEEN_SYM ; predicate: diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29644.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29644.result new file mode 100644 index 00000000000..b52cecc5bb7 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29644.result @@ -0,0 +1,41 @@ +# +# MDEV-29644 a potential bug of null pointer dereference in spider_db_mbase::print_warnings() +# +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +a CHAR(5) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +SET GLOBAL sql_mode=''; +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a ( +a CHAR(255) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; +SET sql_mode=''; +INSERT INTO tbl_a VALUES ("this will be truncated"); +NOT FOUND /\[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*/ in mysqld.1.1.err +SET GLOBAL spider_log_result_errors=4; +INSERT INTO tbl_a VALUES ("this will be truncated"); +FOUND 1 /\[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*/ in mysqld.1.1.err +connection master_1; +SET GLOBAL spider_log_result_errors=DEFAULT; +SET sql_mode=DEFAULT; +DROP DATABASE IF EXISTS auto_test_local; +connection child2_1; +SET GLOBAL sql_mode=DEFAULT; +DROP DATABASE IF EXISTS auto_test_remote; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.test new file mode 100644 index 00000000000..3a8fbb251e1 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.test @@ -0,0 +1,56 @@ +--echo # +--echo # MDEV-29644 a potential bug of null pointer dereference in spider_db_mbase::print_warnings() +--echo # + +# The test case below does not cause the potential null pointer dereference. +# It is just for checking spider_db_mbase::fetch_and_print_warnings() works. + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +eval CREATE TABLE tbl_a ( + a CHAR(5) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +SET GLOBAL sql_mode=''; + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; +eval CREATE TABLE tbl_a ( + a CHAR(255) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"'; + +SET sql_mode=''; + +let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.1.err; +let SEARCH_PATTERN= \[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*; + +INSERT INTO tbl_a VALUES ("this will be truncated"); +--source include/search_pattern_in_file.inc # should not find + +SET GLOBAL spider_log_result_errors=4; + +INSERT INTO tbl_a VALUES ("this will be truncated"); +--source include/search_pattern_in_file.inc # should find + +--connection master_1 +SET GLOBAL spider_log_result_errors=DEFAULT; +SET sql_mode=DEFAULT; +DROP DATABASE IF EXISTS auto_test_local; + +--connection child2_1 +SET GLOBAL sql_mode=DEFAULT; +DROP DATABASE IF EXISTS auto_test_remote; + +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_query_log +--enable_result_log diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index ce4e36b93b2..a51c1497b02 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -2197,7 +2197,7 @@ int spider_db_mbase::exec_query( db_conn->affected_rows, db_conn->insert_id, db_conn->server_status, db_conn->warning_count); if (spider_param_log_result_errors() >= 3) - print_warnings(l_time); + fetch_and_print_warnings(l_time); } else if (log_result_errors >= 4) { time_t cur_time = (time_t) time((time_t*) 0); @@ -2279,61 +2279,43 @@ bool spider_db_mbase::is_xa_nota_error( DBUG_RETURN(xa_nota); } -void spider_db_mbase::print_warnings( - struct tm *l_time -) { - DBUG_ENTER("spider_db_mbase::print_warnings"); - DBUG_PRINT("info",("spider this=%p", this)); - if (db_conn->status == MYSQL_STATUS_READY) +void spider_db_mbase::fetch_and_print_warnings(struct tm *l_time) +{ + DBUG_ENTER("spider_db_mbase::fetch_and_print_warnings"); + + if (spider_param_dry_access() || db_conn->status != MYSQL_STATUS_READY || + db_conn->server_status & SERVER_MORE_RESULTS_EXISTS) + DBUG_VOID_RETURN; + + if (mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR, + SPIDER_SQL_SHOW_WARNINGS_LEN)) + DBUG_VOID_RETURN; + + MYSQL_RES *res= mysql_store_result(db_conn); + if (!res) + DBUG_VOID_RETURN; + + uint num_fields= mysql_num_fields(res); + if (num_fields != 3) { -#if MYSQL_VERSION_ID < 50500 - if (!(db_conn->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS)) -#else - if (!(db_conn->server_status & SERVER_MORE_RESULTS_EXISTS)) -#endif - { - if ( - spider_param_dry_access() || - !mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR, - SPIDER_SQL_SHOW_WARNINGS_LEN) - ) { - MYSQL_RES *res = NULL; - MYSQL_ROW row = NULL; - uint num_fields; - if ( - spider_param_dry_access() || - !(res = mysql_store_result(db_conn)) || - !(row = mysql_fetch_row(res)) - ) { - if (mysql_errno(db_conn)) - { - if (res) - mysql_free_result(res); - DBUG_VOID_RETURN; - } - /* no record is ok */ - } - num_fields = mysql_num_fields(res); - if (num_fields != 3) - { - mysql_free_result(res); - DBUG_VOID_RETURN; - } - while (row) - { - fprintf(stderr, "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] " - "from [%s] %ld to %ld: %s %s %s\n", + mysql_free_result(res); + DBUG_VOID_RETURN; + } + + MYSQL_ROW row= mysql_fetch_row(res); + while (row) + { + fprintf(stderr, + "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] from [%s] %ld " + "to %ld: %s %s %s\n", l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, - l_time->tm_hour, l_time->tm_min, l_time->tm_sec, - conn->tgt_host, (ulong) db_conn->thread_id, - (ulong) current_thd->thread_id, row[0], row[1], row[2]); - row = mysql_fetch_row(res); - } - if (res) - mysql_free_result(res); - } - } + l_time->tm_hour, l_time->tm_min, l_time->tm_sec, conn->tgt_host, + (ulong) db_conn->thread_id, (ulong) current_thd->thread_id, row[0], + row[1], row[2]); + row= mysql_fetch_row(res); } + mysql_free_result(res); + DBUG_VOID_RETURN; } diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h index d0be89c0b51..bc7b0baa9b5 100644 --- a/storage/spider/spd_db_mysql.h +++ b/storage/spider/spd_db_mysql.h @@ -437,9 +437,7 @@ public: bool is_xa_nota_error( int error_num ); - void print_warnings( - struct tm *l_time - ); + void fetch_and_print_warnings(struct tm *l_time); spider_db_result *store_result( spider_db_result_buffer **spider_res_buf, st_spider_db_request_key *request_key, |