diff options
author | Georgi Kodinov <kgeorge@mysql.com> | 2008-10-08 14:23:53 +0300 |
---|---|---|
committer | Georgi Kodinov <kgeorge@mysql.com> | 2008-10-08 14:23:53 +0300 |
commit | 6d54b0443a55142263754e0f7a6a36a5bafc2a21 (patch) | |
tree | 9244a02dac3bb0b0d2dafbc410630a91346aba2f /mysql-test | |
parent | 68fa4edc84c9beca00b5813621159561f9006b1d (diff) | |
download | mariadb-git-6d54b0443a55142263754e0f7a6a36a5bafc2a21.tar.gz |
Bug #32124: crash if prepared statements refer to variables in the where clause
The code to get read the value of a system variable was extracting its value
on PREPARE stage and was substituting the value (as a constant) into the parse tree.
Note that this must be a reversible transformation, i.e. it must be reversed before
each re-execution.
Unfortunately this cannot be reliably done using the current code, because there are
other non-reversible source tree transformations that can interfere with this
reversible transformation.
Fixed by not resolving the value at PREPARE, but at EXECUTE (as the rest of the
functions operate). Added a cache of the value (so that it's constant throughout
the execution of the query). Note that the cache also caches NULL values.
Updated an obsolete related test suite (variables-big) and the code to test the
result type of system variables (as per bug 74).
mysql-test/extra/rpl_tests/rpl_insert_id.test:
Bug #32124: removed ambiguous testcase
mysql-test/r/innodb_data_home_dir_basic.result:
Bug #32124: fixed wrong test case
mysql-test/r/innodb_flush_method_basic.result:
Bug #32124: fixed wrong test case
mysql-test/r/ps_11bugs.result:
Bug #32124: test case
mysql-test/r/ssl_capath_basic.result:
Bug #32124: fixed wrong test case
mysql-test/r/ssl_cipher_basic.result:
Bug #32124: fixed wrong test case
mysql-test/r/variables.result:
Bug #32124: system vars are shown as such in EXPLAIN EXTENDED, not as constants.
mysql-test/suite/rpl/r/rpl_insert_id.result:
Bug #32124: removed ambiguous testcase
mysql-test/t/ps_11bugs.test:
Bug #32124: test case
sql/item.cc:
Bug #32124: placed the code to convert string to longlong or double
to a function (so that it can be reused)
sql/item.h:
Bug #32124: placed the code to convert string to longlong or double
to a function (so that it can be reused)
sql/item_func.cc:
Bug #32124: moved the evaluation of system variables at runtime (val_xxx).
sql/item_func.h:
Bug #32124: moved the evaluation of system variables at runtime (val_xxx).
sql/set_var.cc:
Bug #32124: removed the code that calculated the system variable's value
at PREPARE
sql/set_var.h:
Bug #32124: removed the code that calculated the system variable's value
at PREPARE
tests/mysql_client_test.c:
Bug #32124 : removed the reading of the system variable, because its max
length is depended on the system charset and client charset and can't be
easily calculated.
Diffstat (limited to 'mysql-test')
-rw-r--r-- | mysql-test/extra/rpl_tests/rpl_insert_id.test | 2 | ||||
-rw-r--r-- | mysql-test/r/innodb_data_home_dir_basic.result | 10 | ||||
-rw-r--r-- | mysql-test/r/innodb_flush_method_basic.result | 10 | ||||
-rw-r--r-- | mysql-test/r/ps_11bugs.result | 28 | ||||
-rw-r--r-- | mysql-test/r/ssl_capath_basic.result | 10 | ||||
-rw-r--r-- | mysql-test/r/ssl_cipher_basic.result | 10 | ||||
-rw-r--r-- | mysql-test/r/variables.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_insert_id.result | 28 | ||||
-rw-r--r-- | mysql-test/t/ps_11bugs.test | 37 |
9 files changed, 96 insertions, 41 deletions
diff --git a/mysql-test/extra/rpl_tests/rpl_insert_id.test b/mysql-test/extra/rpl_tests/rpl_insert_id.test index d8ea267d62b..bd815d9de02 100644 --- a/mysql-test/extra/rpl_tests/rpl_insert_id.test +++ b/mysql-test/extra/rpl_tests/rpl_insert_id.test @@ -442,8 +442,6 @@ SELECT f1(); INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2()); INSERT INTO t1 VALUES (NULL, f2()); -INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)), - (NULL, @@LAST_INSERT_ID); # Test replication of substitution "IS NULL" -> "= LAST_INSERT_ID". INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID()); UPDATE t1 SET j= -1 WHERE i IS NULL; diff --git a/mysql-test/r/innodb_data_home_dir_basic.result b/mysql-test/r/innodb_data_home_dir_basic.result index fb9a0b0bca5..e4bdd79b7c3 100644 --- a/mysql-test/r/innodb_data_home_dir_basic.result +++ b/mysql-test/r/innodb_data_home_dir_basic.result @@ -1,7 +1,7 @@ '#---------------------BS_STVARS_025_01----------------------#' SELECT COUNT(@@GLOBAL.innodb_data_home_dir); COUNT(@@GLOBAL.innodb_data_home_dir) -0 +1 1 Expected '#---------------------BS_STVARS_025_02----------------------#' SET @@GLOBAL.innodb_data_home_dir=1; @@ -9,7 +9,7 @@ ERROR HY000: Variable 'innodb_data_home_dir' is a read only variable Expected error 'Read only variable' SELECT COUNT(@@GLOBAL.innodb_data_home_dir); COUNT(@@GLOBAL.innodb_data_home_dir) -0 +1 1 Expected '#---------------------BS_STVARS_025_03----------------------#' SELECT @@GLOBAL.innodb_data_home_dir = VARIABLE_VALUE @@ -20,7 +20,7 @@ NULL 1 Expected SELECT COUNT(@@GLOBAL.innodb_data_home_dir); COUNT(@@GLOBAL.innodb_data_home_dir) -0 +1 1 Expected SELECT COUNT(VARIABLE_VALUE) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES @@ -36,7 +36,7 @@ NULL '#---------------------BS_STVARS_025_05----------------------#' SELECT COUNT(@@innodb_data_home_dir); COUNT(@@innodb_data_home_dir) -0 +1 1 Expected SELECT COUNT(@@local.innodb_data_home_dir); ERROR HY000: Variable 'innodb_data_home_dir' is a GLOBAL variable @@ -46,7 +46,7 @@ ERROR HY000: Variable 'innodb_data_home_dir' is a GLOBAL variable Expected error 'Variable is a GLOBAL variable' SELECT COUNT(@@GLOBAL.innodb_data_home_dir); COUNT(@@GLOBAL.innodb_data_home_dir) -0 +1 1 Expected SELECT innodb_data_home_dir = @@SESSION.innodb_data_home_dir; ERROR 42S22: Unknown column 'innodb_data_home_dir' in 'field list' diff --git a/mysql-test/r/innodb_flush_method_basic.result b/mysql-test/r/innodb_flush_method_basic.result index 836328c5c9b..8c8924cdd86 100644 --- a/mysql-test/r/innodb_flush_method_basic.result +++ b/mysql-test/r/innodb_flush_method_basic.result @@ -1,7 +1,7 @@ '#---------------------BS_STVARS_029_01----------------------#' SELECT COUNT(@@GLOBAL.innodb_flush_method); COUNT(@@GLOBAL.innodb_flush_method) -0 +1 1 Expected '#---------------------BS_STVARS_029_02----------------------#' SET @@GLOBAL.innodb_flush_method=1; @@ -9,7 +9,7 @@ ERROR HY000: Variable 'innodb_flush_method' is a read only variable Expected error 'Read only variable' SELECT COUNT(@@GLOBAL.innodb_flush_method); COUNT(@@GLOBAL.innodb_flush_method) -0 +1 1 Expected '#---------------------BS_STVARS_029_03----------------------#' SELECT @@GLOBAL.innodb_flush_method = VARIABLE_VALUE @@ -20,7 +20,7 @@ NULL 1 Expected SELECT COUNT(@@GLOBAL.innodb_flush_method); COUNT(@@GLOBAL.innodb_flush_method) -0 +1 1 Expected SELECT COUNT(VARIABLE_VALUE) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES @@ -36,7 +36,7 @@ NULL '#---------------------BS_STVARS_029_05----------------------#' SELECT COUNT(@@innodb_flush_method); COUNT(@@innodb_flush_method) -0 +1 1 Expected SELECT COUNT(@@local.innodb_flush_method); ERROR HY000: Variable 'innodb_flush_method' is a GLOBAL variable @@ -46,7 +46,7 @@ ERROR HY000: Variable 'innodb_flush_method' is a GLOBAL variable Expected error 'Variable is a GLOBAL variable' SELECT COUNT(@@GLOBAL.innodb_flush_method); COUNT(@@GLOBAL.innodb_flush_method) -0 +1 1 Expected SELECT innodb_flush_method = @@SESSION.innodb_flush_method; ERROR 42S22: Unknown column 'innodb_flush_method' in 'field list' diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result index ebe161f46b3..a298c552806 100644 --- a/mysql-test/r/ps_11bugs.result +++ b/mysql-test/r/ps_11bugs.result @@ -162,4 +162,32 @@ a b 12 NULL drop table t1; drop table t2; +CREATE TABLE t1 (a INT); +PREPARE stmt FROM 'select 1 from `t1` where `a` = any (select (@@tmpdir))'; +EXECUTE stmt; +1 +DEALLOCATE PREPARE stmt; +DROP TABLE t1; +CREATE TABLE t2 (a INT PRIMARY KEY); +INSERT INTO t2 VALUES (400000), (400001); +SET @@sort_buffer_size=400000; +CREATE FUNCTION p1(i INT) RETURNS INT +BEGIN +SET @@sort_buffer_size= i; +RETURN i + 1; +END| +SELECT * FROM t2 WHERE a = @@sort_buffer_size AND p1(@@sort_buffer_size + 1) > a - 1; +a +400000 +DROP TABLE t2; +DROP FUNCTION p1; +SELECT CONCAT(@@sort_buffer_size); +CONCAT(@@sort_buffer_size) +400001 +SELECT LEFT("12345", @@ft_boolean_syntax); +LEFT("12345", @@ft_boolean_syntax) + +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '+ -><()~*:""&|' +SET @@sort_buffer_size=DEFAULT; End of 5.0 tests. diff --git a/mysql-test/r/ssl_capath_basic.result b/mysql-test/r/ssl_capath_basic.result index a2c01aab806..3d161392917 100644 --- a/mysql-test/r/ssl_capath_basic.result +++ b/mysql-test/r/ssl_capath_basic.result @@ -1,7 +1,7 @@ '#---------------------BS_STVARS_046_01----------------------#' SELECT COUNT(@@GLOBAL.ssl_capath); COUNT(@@GLOBAL.ssl_capath) -0 +1 1 Expected '#---------------------BS_STVARS_046_02----------------------#' SET @@GLOBAL.ssl_capath=1; @@ -9,7 +9,7 @@ ERROR HY000: Variable 'ssl_capath' is a read only variable Expected error 'Read only variable' SELECT COUNT(@@GLOBAL.ssl_capath); COUNT(@@GLOBAL.ssl_capath) -0 +1 1 Expected '#---------------------BS_STVARS_046_03----------------------#' SELECT @@GLOBAL.ssl_capath = VARIABLE_VALUE @@ -20,7 +20,7 @@ NULL 1 Expected SELECT COUNT(@@GLOBAL.ssl_capath); COUNT(@@GLOBAL.ssl_capath) -0 +1 1 Expected SELECT COUNT(VARIABLE_VALUE) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES @@ -36,7 +36,7 @@ NULL '#---------------------BS_STVARS_046_05----------------------#' SELECT COUNT(@@ssl_capath); COUNT(@@ssl_capath) -0 +1 1 Expected SELECT COUNT(@@local.ssl_capath); ERROR HY000: Variable 'ssl_capath' is a GLOBAL variable @@ -46,7 +46,7 @@ ERROR HY000: Variable 'ssl_capath' is a GLOBAL variable Expected error 'Variable is a GLOBAL variable' SELECT COUNT(@@GLOBAL.ssl_capath); COUNT(@@GLOBAL.ssl_capath) -0 +1 1 Expected SELECT ssl_capath = @@SESSION.ssl_capath; ERROR 42S22: Unknown column 'ssl_capath' in 'field list' diff --git a/mysql-test/r/ssl_cipher_basic.result b/mysql-test/r/ssl_cipher_basic.result index 3c7098e1150..df0fc8b5aad 100644 --- a/mysql-test/r/ssl_cipher_basic.result +++ b/mysql-test/r/ssl_cipher_basic.result @@ -1,7 +1,7 @@ '#---------------------BS_STVARS_048_01----------------------#' SELECT COUNT(@@GLOBAL.ssl_cipher); COUNT(@@GLOBAL.ssl_cipher) -0 +1 1 Expected '#---------------------BS_STVARS_048_02----------------------#' SET @@GLOBAL.ssl_cipher=1; @@ -9,7 +9,7 @@ ERROR HY000: Variable 'ssl_cipher' is a read only variable Expected error 'Read only variable' SELECT COUNT(@@GLOBAL.ssl_cipher); COUNT(@@GLOBAL.ssl_cipher) -0 +1 1 Expected '#---------------------BS_STVARS_048_03----------------------#' SELECT @@GLOBAL.ssl_cipher = VARIABLE_VALUE @@ -20,7 +20,7 @@ NULL 1 Expected SELECT COUNT(@@GLOBAL.ssl_cipher); COUNT(@@GLOBAL.ssl_cipher) -0 +1 1 Expected SELECT COUNT(VARIABLE_VALUE) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES @@ -36,7 +36,7 @@ NULL '#---------------------BS_STVARS_048_05----------------------#' SELECT COUNT(@@ssl_cipher); COUNT(@@ssl_cipher) -0 +1 1 Expected SELECT COUNT(@@local.ssl_cipher); ERROR HY000: Variable 'ssl_cipher' is a GLOBAL variable @@ -46,7 +46,7 @@ ERROR HY000: Variable 'ssl_cipher' is a GLOBAL variable Expected error 'Variable is a GLOBAL variable' SELECT COUNT(@@GLOBAL.ssl_cipher); COUNT(@@GLOBAL.ssl_cipher) -0 +1 1 Expected SELECT ssl_cipher = @@SESSION.ssl_cipher; ERROR 42S22: Unknown column 'ssl_cipher' in 'field list' diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 3f66599751d..aee84c98e4f 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -157,7 +157,7 @@ explain extended select @@IDENTITY,last_insert_id(), @@identity; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select 345 AS `@@IDENTITY`,last_insert_id() AS `last_insert_id()`,345 AS `@@identity` +Note 1003 select @@IDENTITY AS `@@IDENTITY`,last_insert_id() AS `last_insert_id()`,@@identity AS `@@identity` set big_tables=OFF, big_tables=ON, big_tables=0, big_tables=1, big_tables="OFF", big_tables="ON"; set global concurrent_insert=2; show variables like 'concurrent_insert'; diff --git a/mysql-test/suite/rpl/r/rpl_insert_id.result b/mysql-test/suite/rpl/r/rpl_insert_id.result index 76e405c68de..e171e247b6c 100644 --- a/mysql-test/suite/rpl/r/rpl_insert_id.result +++ b/mysql-test/suite/rpl/r/rpl_insert_id.result @@ -398,8 +398,6 @@ f1() INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2()); INSERT INTO t1 VALUES (NULL, f2()); -INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)), -(NULL, @@LAST_INSERT_ID); INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID()); UPDATE t1 SET j= -1 WHERE i IS NULL; INSERT INTO t1 (i) VALUES (NULL); @@ -422,20 +420,17 @@ i j 11 3 12 3 13 8 -14 13 -15 5 -16 13 -17 -1 -18 14 -19 0 -20 0 +14 -1 +15 13 +16 0 +17 0 SELECT * FROM t2 ORDER BY i; i 2 3 5 6 -19 +16 SELECT * FROM t1; i j 1 -1 @@ -451,20 +446,17 @@ i j 11 3 12 3 13 8 -14 13 -15 5 -16 13 -17 -1 -18 14 -19 0 -20 0 +14 -1 +15 13 +16 0 +17 0 SELECT * FROM t2; i 2 3 5 6 -19 +16 DROP PROCEDURE p1; DROP FUNCTION f1; DROP FUNCTION f2; diff --git a/mysql-test/t/ps_11bugs.test b/mysql-test/t/ps_11bugs.test index 515bcc03c1a..ccab833e878 100644 --- a/mysql-test/t/ps_11bugs.test +++ b/mysql-test/t/ps_11bugs.test @@ -177,4 +177,41 @@ select * from t2; drop table t1; drop table t2; +# +# Bug #32124: crash if prepared statements refer to variables in the where +# clause +# + +CREATE TABLE t1 (a INT); +PREPARE stmt FROM 'select 1 from `t1` where `a` = any (select (@@tmpdir))'; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + +CREATE TABLE t2 (a INT PRIMARY KEY); +INSERT INTO t2 VALUES (400000), (400001); + +SET @@sort_buffer_size=400000; + +DELIMITER |; + +CREATE FUNCTION p1(i INT) RETURNS INT +BEGIN + SET @@sort_buffer_size= i; + RETURN i + 1; +END| + +DELIMITER ;| + +SELECT * FROM t2 WHERE a = @@sort_buffer_size AND p1(@@sort_buffer_size + 1) > a - 1; + +DROP TABLE t2; +DROP FUNCTION p1; + + +SELECT CONCAT(@@sort_buffer_size); +SELECT LEFT("12345", @@ft_boolean_syntax); + +SET @@sort_buffer_size=DEFAULT; + --echo End of 5.0 tests. |