summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2023-04-21 09:10:58 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2023-04-21 09:10:58 +0200
commit3d27f6d7f46121ba0b945818e59ec221c77ad378 (patch)
treee48f88ba77d3826eb76ca08ca7c836cec7b975ab
parentfc6e8a3d3264078bed28632a289130b1dc24daea (diff)
parent4c4939bbf619d7e516131c0b3e5691b1c2d2ff8f (diff)
downloadmariadb-git-3d27f6d7f46121ba0b945818e59ec221c77ad378.tar.gz
Merge branch '10.3' into 10.4
-rw-r--r--debian/control1
-rw-r--r--mysql-test/lib/My/CoreDump.pm33
-rw-r--r--mysql-test/main/bootstrap.result45
-rw-r--r--mysql-test/main/bootstrap.test107
-rw-r--r--mysql-test/main/derived.result23
-rw-r--r--mysql-test/main/derived.test30
-rw-r--r--mysql-test/main/parser.result28
-rw-r--r--mysql-test/main/parser.test17
-rw-r--r--sql/mysqld.cc5
-rw-r--r--sql/sql_derived.cc3
-rw-r--r--sql/sql_yacc.yy54
-rw-r--r--sql/sql_yacc_ora.yy54
-rw-r--r--storage/spider/mysql-test/spider/bugfix/r/mdev_29644.result41
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf3
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_29644.test56
-rw-r--r--storage/spider/spd_db_mysql.cc88
-rw-r--r--storage/spider/spd_db_mysql.h4
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,