Re: [Maria-developers] [Commits] 28fcccc: MDEV-5231: Per query variables from Percona Server (rewritten)
Hi, Sanja! On Oct 13, sanja@mariadb.com wrote:
revision-id: 28fccccad32fa8a47dc572b968613e18ff51b634 parent(s): fec5ab5a56cb9a45c621207620cc85079cddf537 committer: Oleksandr Byelkin branch nick: work-maria-10.1-sysvar2 timestamp: 2014-10-13 22:35:40 +0200 message:
MDEV-5231: Per query variables from Percona Server (rewritten)
This looks a lot better that the previous patch. Thanks! See my comments below. Some parts of the patch are not used (left-overs from the old implementation?). Some others, I think, are not needed. And some of the old tests don't make much sense, your new tests made them redundant and useless. A couple of comments after reading my previous review: * please add a test for any sysvar with non-trivial implementations of sys_var::session_update(), that is, for a sysvar where old approach doesn't work. Unless, of course, your timestamp tests are exactly that :) * add tests with @@default_engine. For example: SET @@default_engine=MyISAM; SET STATEMENT @@default_engine=MEMORY CREATE TABLE t1 (a int); SHOW CREATE TABLE t1; -- verify the engine SET STATEMENT @@default_engine=MyISAM CREATE TABLE t2 (a int); etc. See other comments below:
diff --git a/mysql-test/r/set_statement.result b/mysql-test/r/set_statement.result new file mode 100644 index 0000000..fed937e --- /dev/null +++ b/mysql-test/r/set_statement.result @@ -0,0 +1,941 @@ +'# SET STATEMENT ..... FOR .... TEST' +DROP TABLE IF EXISTS t1; +DROP FUNCTION IF EXISTS myProc; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP PROCEDURE IF EXISTS p3; +DROP PROCEDURE IF EXISTS p4; +DROP PROCEDURE IF EXISTS p5; +DROP TABLE IF EXISTS STATEMENT; +'# Setup database' +CREATE TABLE t1 (v1 INT, v2 INT); +INSERT INTO t1 VALUES (1,2); +INSERT INTO t1 VALUES (3,4); +'' +'#------------------ STATEMENT Test 1 -----------------------#' +'# Initialize variables to known setting' +SET SESSION sort_buffer_size=100000; +'' +'# Pre-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; +Variable_name Value +sort_buffer_size 100000 +SET STATEMENT sort_buffer_size=150000 FOR SELECT *,@@sort_buffer_size FROM t1; +v1 v2 @@sort_buffer_size +1 2 150000 +3 4 150000 +'' +'# Post-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; +Variable_name Value +sort_buffer_size 100000 +'' +'#------------------ STATEMENT Test 2 -----------------------#' +'# Initialize variables to known setting' +SET SESSION binlog_format=mixed; +SET SESSION sort_buffer_size=100000; +'# Pre-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; +Variable_name Value +sort_buffer_size 100000 +SHOW SESSION VARIABLES LIKE 'binlog_format'; +Variable_name Value +binlog_format MIXED +SET STATEMENT sort_buffer_size=150000, binlog_format=row +FOR SELECT *,@@sort_buffer_size,@@binlog_format FROM t1; +v1 v2 @@sort_buffer_size @@binlog_format +1 2 150000 ROW +3 4 150000 ROW +'# Post-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; +Variable_name Value +sort_buffer_size 100000 +SHOW SESSION VARIABLES LIKE 'binlog_format'; +Variable_name Value +binlog_format MIXED +'' +'#------------------ STATEMENT Test 3 -----------------------#' +'# set initial variable value, make prepared statement +SET SESSION binlog_format=row; +PREPARE stmt1 FROM 'SET STATEMENT binlog_format=row FOR SELECT *,@@binlog_format FROM t1'; +'' +'# Change variable setting' +SET SESSION binlog_format=mixed; +'' +'# Pre-STATEMENT variable value' +'' +SHOW SESSION VARIABLES LIKE 'binlog_format'; +Variable_name Value +binlog_format MIXED +'' +EXECUTE stmt1; +v1 v2 @@binlog_format +1 2 ROW +3 4 ROW +'' +'# Post-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'binlog_format'; +Variable_name Value +binlog_format MIXED +'' +DEALLOCATE PREPARE stmt1; +'#------------------ STATEMENT Test 4 -----------------------#' +'# set initial variable value, make prepared statement +SET SESSION myisam_sort_buffer_size=500000, myisam_repair_threads=1; +'' +'# Pre-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'myisam_sort_buffer_size'; +Variable_name Value +myisam_sort_buffer_size 500000 +SHOW SESSION VARIABLES LIKE 'myisam_repair_threads'; +Variable_name Value +myisam_repair_threads 1 +'' +SET STATEMENT myisam_sort_buffer_size=800000, +myisam_repair_threads=2 FOR OPTIMIZE TABLE t1;
1. this is not "make prepared statement" as the comment says 2. what does it actually test? you don't verify whether new values had any effect.
+Table Op Msg_type Msg_text +test.t1 optimize status OK +'' +'# Post-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'myisam_sort_buffer_size'; +Variable_name Value +myisam_sort_buffer_size 500000 +SHOW SESSION VARIABLES LIKE 'myisam_repair_threads'; +Variable_name Value +myisam_repair_threads 1 +'' +'#------------------ STATEMENT Test 5 -----------------------#' +'# Initialize variables to known setting' +SET SESSION sort_buffer_size=100000; +'' +'# Pre-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; +Variable_name Value +sort_buffer_size 100000 +'' +SET STATEMENT sort_buffer_size=150000 FOR SELECT * FROM t2; +ERROR 42S02: Table 'test.t2' doesn't exist +'' +'# Post-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; +Variable_name Value +sort_buffer_size 150000
Looks wrong. The value is not restored in case of an error.
+'' +'#------------------ STATEMENT Test 6 -----------------------#' +'# Initialize variables to known setting' +SET SESSION keep_files_on_create=ON; +'' +'# Pre-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'keep_files_on_create'; +Variable_name Value +keep_files_on_create ON +'' +SET STATEMENT keep_files_on_create=OFF FOR SELECT *,@@keep_files_on_create FROM t1; +v1 v2 @@keep_files_on_create +1 2 0 +3 4 0
How is this test different from other tests above?
+'' +'# Post-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'keep_files_on_create'; +Variable_name Value +keep_files_on_create ON +'' +'#------------------ STATEMENT Test 7 -----------------------#' +'# Initialize variables to known setting' +SET SESSION max_join_size=2222220000000; +'' +'# Pre-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'max_join_size'; +Variable_name Value +max_join_size 2222220000000 +'' +SET STATEMENT max_join_size=1000000000000 FOR SELECT *,@@max_join_size FROM t1; +v1 v2 @@max_join_size +1 2 1000000000000 +3 4 1000000000000
Same question - how is this test different from other tests above?
+'' +'# Post-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'max_join_size'; +Variable_name Value +max_join_size 2222220000000 +'' +'#------------------Test 8-----------------------#' +'# Initialize test variables' +SET SESSION myisam_sort_buffer_size=500000, +myisam_repair_threads=1, +sort_buffer_size = 200000, +max_join_size=2222220000000, +keep_files_on_create=ON; +'' +'# LONG ' +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; +Variable_name Value +sort_buffer_size 200000 +SET STATEMENT sort_buffer_size = 100000 +FOR SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; +Variable_name Value +sort_buffer_size 100000 +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; +Variable_name Value +sort_buffer_size 200000 +'' +'# MY_BOOL ' +SHOW SESSION VARIABLES LIKE 'keep_files_on_create'; +Variable_name Value +keep_files_on_create ON +SET STATEMENT keep_files_on_create=OFF +FOR SHOW SESSION VARIABLES LIKE 'keep_files_on_create'; +Variable_name Value +keep_files_on_create OFF +SHOW SESSION VARIABLES LIKE 'keep_files_on_create'; +Variable_name Value +keep_files_on_create ON +'' +'# INT/LONG ' +SHOW SESSION VARIABLES LIKE 'myisam_repair_threads'; +Variable_name Value +myisam_repair_threads 1 +SET STATEMENT myisam_repair_threads=2 +FOR SHOW SESSION VARIABLES LIKE 'myisam_repair_threads'; +Variable_name Value +myisam_repair_threads 2 +SHOW SESSION VARIABLES LIKE 'myisam_repair_threads'; +Variable_name Value +myisam_repair_threads 1 +'' +'# ULONGLONG ' +SHOW SESSION VARIABLES LIKE 'max_join_size'; +Variable_name Value +max_join_size 2222220000000 +SET STATEMENT max_join_size=2000000000000 +FOR SHOW SESSION VARIABLES LIKE 'max_join_size'; +Variable_name Value +max_join_size 2000000000000 +SHOW SESSION VARIABLES LIKE 'max_join_size'; +Variable_name Value +max_join_size 2222220000000 +'' +'#------------------Test 9-----------------------#' +'# set initial variable values +SET SESSION myisam_sort_buffer_size=500000, +myisam_repair_threads=1, +sort_buffer_size=100000, +binlog_format=mixed, +keep_files_on_create=ON, +max_join_size=2222220000000; +'' +'' +'# Pre-STATEMENT variable value +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +CREATE FUNCTION myProc (cost DECIMAL(10,2)) +RETURNS DECIMAL(10,2) +SQL SECURITY DEFINER +tax: BEGIN +DECLARE order_tax DECIMAL(10,2); +SET order_tax = cost * .05; +RETURN order_tax; +END| +'' +'# During Execution values +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +binlog_format=row, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +SELECT myProc(123.45); +myProc(123.45) +6.17
How does this verify that SET STATEMENT had any effect?
+'' +'# Post-STATEMENT No 1 variable value Pre-STATEMENT for No 2' +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +binlog_format=row, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +DROP FUNCTION myProc;
How does this verify that SET STATEMENT had any effect?
+'' +'# Post-STATEMENT No 2 variable value +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'#------------------Test 10-----------------------#' +'# set initial variable values +SET SESSION myisam_sort_buffer_size=500000, +myisam_repair_threads=1, +sort_buffer_size=100000, +binlog_format=mixed, +keep_files_on_create=ON, +max_join_size=2222220000000; +'' +'# Pre-STATEMENT variable value +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +binlog_format=row, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +PREPARE stmt2 +FROM 'SELECT * FROM t1'; +'' +'Test No 1 Post Value & Test 2 Pre values' +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +binlog_format=row, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +EXECUTE stmt2; +v1 v2 +1 2 +3 4
How does this verify that SET STATEMENT had any effect? Add @@binlog_format and @@sort_buffer_size to the SELECT and use different values for @@sort_buffer_size in SET STATEMENT for PREPARE and EXECUTE. Ok, I see that you do it below. Then how is this test useful?
+'' +'# Post-STATEMENT No 2 +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +DEALLOCATE PREPARE stmt2; +'' +'#------------------Test 11-----------------------#' +'# set initial variable values +SET SESSION myisam_sort_buffer_size=500000, +myisam_repair_threads=1, +sort_buffer_size=100000, +binlog_format=mixed, +keep_files_on_create=ON, +max_join_size=2222220000000; +'' +'' +'# Pre-STATEMENT variable value +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +PREPARE stmt1 FROM +'SET STATEMENT binlog_format=row FOR SELECT *,@@binlog_format FROM t1';
please also add @@sort_buffer_size to this SELECT
+'' +'Test No 1 Post Value & Test 2 Pre values' +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +EXECUTE stmt1; +v1 v2 @@binlog_format +1 2 ROW +3 4 ROW +'' +'# Post-STATEMENT No 2 +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +'#------------------Test 12-----------------------#' +'# set initial variable values +SET SESSION myisam_sort_buffer_size=500000, +myisam_repair_threads=1, +sort_buffer_size=100000, +binlog_format=mixed, +keep_files_on_create=ON, +max_join_size=2222220000000; +'' +'' +'# Pre-STATEMENT variable value +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +binlog_format=row, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +CREATE PROCEDURE p1() BEGIN +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +END| +'' +'Test No 1 Post Value & Test 2 Pre values' +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +binlog_format=row, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR
Use different values here, not same as in the previous SET STATEMENT
+CALL p1(); +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +400000 2 200000 ROW 0 4444440000000 +'' +'# Post-STATEMENT No 2 +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +'#------------------Test 13-----------------------#' +'# set initial variable values +SET SESSION myisam_sort_buffer_size=500000, +myisam_repair_threads=1, +sort_buffer_size=100000, +binlog_format=mixed, +keep_files_on_create=ON, +max_join_size=2222220000000; +'' +'' +CREATE PROCEDURE p2() BEGIN +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=3, +sort_buffer_size=300000, +binlog_format=mixed, +keep_files_on_create=OFF, +max_join_size=3333330000000 FOR +CALL p1(); +END| +'' +'# Pre-STATEMENT variable value +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +binlog_format=row, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +CALL p2(); +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +400000 3 300000 MIXED 0 3333330000000 +'' +'# Post-STATEMENT +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +'#------------------Test 14-----------------------#' +'# set initial variable values +SET SESSION myisam_sort_buffer_size=500000, +myisam_repair_threads=1, +sort_buffer_size=100000, +binlog_format=mixed, +keep_files_on_create=ON, +max_join_size=2222220000000; +'' +'' +CREATE PROCEDURE p3() BEGIN +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +SET STATEMENT myisam_sort_buffer_size=320000, +myisam_repair_threads=2, +sort_buffer_size=220022, +binlog_format=row, +keep_files_on_create=ON, +max_join_size=2222220000000 FOR +CALL p2(); +END| +'' +'# Pre-STATEMENT variable value +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +binlog_format=row, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +CALL p3(); +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +400000 2 200000 ROW 0 4444440000000 +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +400000 3 300000 MIXED 0 3333330000000 +'' +'# Post-STATEMENT +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +'' +'' +'#------------------Test 15-----------------------#' +'# set initial variable values +SET SESSION myisam_sort_buffer_size=500000, +myisam_repair_threads=1, +sort_buffer_size=100000, +binlog_format=mixed, +keep_files_on_create=ON, +max_join_size=2222220000000; +'' +'' +CREATE PROCEDURE p4() BEGIN +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +SET STATEMENT myisam_sort_buffer_size=320000, +myisam_repair_threads=2, +sort_buffer_size=220022, +binlog_format=row, +keep_files_on_create=ON, +max_join_size=2222220000000 FOR +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +SET STATEMENT myisam_sort_buffer_size=320000, +myisam_repair_threads=2, +sort_buffer_size=220022, +binlog_format=row, +keep_files_on_create=ON, +max_join_size=2222220000000 FOR +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +SET STATEMENT myisam_sort_buffer_size=320000, +myisam_repair_threads=2, +sort_buffer_size=220022, +binlog_format=row, +keep_files_on_create=ON, +max_join_size=2222220000000 FOR +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +END| +'' +'# Pre-STATEMENT variable value +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +binlog_format=row, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +CALL p4(); +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +400000 2 200000 ROW 0 4444440000000 +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +320000 2 220022 ROW 1 2222220000000 +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +320000 2 220022 ROW 1 2222220000000 +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +320000 2 220022 ROW 1 2222220000000 +'' +'# Post-STATEMENT +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +'#------------------Test 16-----------------------#' +'' +'# Pre-STATEMENT variable value +SELECT @@sql_mode; +@@sql_mode + +'' +'' +SET STATEMENT sql_mode='ansi' FOR PREPARE stmt FROM 'SELECT "t1".* FROM t1'; +execute stmt; +v1 v2 +1 2 +3 4
Ok, that's getting interesting. Now before deallocating, try to trigger automatic reprepare. e.g. ALTER TABLE t1 ADD COLUMN v3 int; and then execute it again. also do the same with SP. I mean, set statement sql_mode=ansi create procedure this procedure uses ansi quotes. verify that the correct sql mode (ansi) is recorded in mysql.proc table.
+deallocate prepare stmt; +'' +'# Post-STATEMENT +SELECT @@sql_mode; +@@sql_mode + +'' +'' +'#------------------Test 17-----------------------#' +'# set initial variable values +SET SESSION myisam_sort_buffer_size=500000, +myisam_repair_threads=1, +sort_buffer_size=100000, +binlog_format=mixed, +keep_files_on_create=ON, +max_join_size=2222220000000; +'' +'# Pre-STATEMENT variable value +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +SET STATEMENT myisam_sort_buffer_size=320000, +myisam_repair_threads=2, +sort_buffer_size=220022, +binlog_format=row, +keep_files_on_create=ON, +max_join_size=2222220000000 +FOR SET SESSION +myisam_sort_buffer_size=260000, +myisam_repair_threads=3, +sort_buffer_size=230013, +binlog_format=row, +keep_files_on_create=ON, +max_join_size=2323230000000;
Add a couple of other variables to SET SESSION. The point - have some variables in SET SESSION that are *not* present in SET STATEMENT. Verify that their values were correctly set. Ok, I see that you do it below. Then how is this test useful?
+'' +'# Post-STATEMENT +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +'#------------------Test 18-----------------------#' +'# set initial variable values +SET SESSION myisam_sort_buffer_size=500000, +myisam_repair_threads=1, +sort_buffer_size=100000, +binlog_format=mixed, +keep_files_on_create=ON, +max_join_size=2222220000000; +'' +'# Pre-STATEMENT variable value +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +CREATE PROCEDURE p5() BEGIN +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +SET SESSION +myisam_sort_buffer_size=260000, +myisam_repair_threads=3, +sort_buffer_size=230013, +binlog_format=row, +keep_files_on_create=ON, +max_join_size=2323230000000; +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +END|
How is this test different from other tests above?
+'' +'' +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=2, +sort_buffer_size=200000, +binlog_format=row, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +CALL p5(); +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +400000 2 200000 ROW 0 4444440000000 +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +260000 3 230013 ROW 1 2323230000000 +'' +'# Post-STATEMENT +SELECT @@myisam_sort_buffer_size, +@@myisam_repair_threads, +@@sort_buffer_size, +@@binlog_format, +@@keep_files_on_create, +@@max_join_size; +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size +500000 1 100000 MIXED 1 2222220000000 +'' +'' +'#------------------Test 19-----------------------#' +SET STATEMENT max_error_count=100 FOR; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 +SET STATEMENT max_error_count=100 INSERT t1 VALUES (1,2); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INSERT t1 VALUES (1,2)' at line 1 +SET STATEMENT FOR INSERT INTO t1 VALUES (1,2); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FOR INSERT INTO t1 VALUES (1,2)' at line 1 +SET max_error_count=100 FOR INSERT INTO t1 VALUES (1,2); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FOR INSERT INTO t1 VALUES (1,2)' at line 1 +SET max_error_count=100 FOR INSERT INTO t1 VALUES (1,2);
Same erroneous statement tested twice?
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FOR INSERT INTO t1 VALUES (1,2)' at line 1 +SET STATEMENT GLOBAL max_error_count=100 FOR INSERT INTO t1 VALUES (1,2); +ERROR HY000: Unknown system variable 'GLOBAL' +SET STATEMENT @@global.max_error_count=100 FOR INSERT INTO t1 VALUES (1,2); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '@@global.max_error_count=100 FOR INSERT INTO t1 VALUES (1,2)' at line 1 +'' +'' +'#------------------Test 20-----------------------#' +SET STATEMENT connect_timeout=100 FOR INSERT INTO t1 VALUES (1,2); +ERROR HY000: Variable 'connect_timeout' is a GLOBAL variable and should be set with SET GLOBAL +'' +'' +'#------------------Test 21-----------------------#' +SELECT @@myisam_sort_buffer_size, @@sort_buffer_size; +@@myisam_sort_buffer_size @@sort_buffer_size +500000 100000 +SET STATEMENT myisam_sort_buffer_size = 700000, sort_buffer_size = 3000000 +FOR SET STATEMENT myisam_sort_buffer_size=200000 +FOR SELECT @@myisam_sort_buffer_size, @@sort_buffer_size; +@@myisam_sort_buffer_size @@sort_buffer_size +200000 100000 +SELECT @@myisam_sort_buffer_size, @@sort_buffer_size; +@@myisam_sort_buffer_size @@sort_buffer_size +500000 100000 +'' +'' +'#------------------Test 22-----------------------#' +CREATE TABLE STATEMENT(a INT); +DROP TABLE STATEMENT; +'' +'# Cleanup' +DROP TABLE t1; +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP PROCEDURE p3; +DROP PROCEDURE p4; +DROP PROCEDURE p5; +CREATE TABLE t1 (v1 INT, v2 INT); +PREPARE stmt +FROM 'SELECT * FROM t1'; +SET STATEMENT myisam_sort_buffer_size=400000, +myisam_repair_threads=(select max(v1) from t1), +sort_buffer_size=200000, +binlog_format=row, +keep_files_on_create=OFF, +max_join_size=4444440000000 FOR +EXECUTE stmt; +ERROR HY000: SET STATEMENT does not support using tables in the assignment variables expressions
Why do you need a prepared statement to test that error?
+deallocate prepare stmt; +drop table t1; +set session binlog_format=mixed; +PREPARE stmt1 FROM 'SELECT @@binlog_format'; +execute stmt1; +@@binlog_format +MIXED +set statement binlog_format=row for execute stmt1; +@@binlog_format +ROW +execute stmt1; +@@binlog_format +MIXED +deallocate prepare stmt1; +set statement binlog_format=row for PREPARE stmt1 FROM 'SELECT @@binlog_format'; +execute stmt1; +@@binlog_format +MIXED +execute stmt1; +@@binlog_format +MIXED +deallocate prepare stmt1; +PREPARE stmt1 FROM 'set statement binlog_format=row for SELECT @@binlog_format'; +execute stmt1; +@@binlog_format +ROW +execute stmt1; +@@binlog_format +ROW +deallocate prepare stmt1; +set session binlog_format=default; +set session binlog_format=mixed; +SET STATEMENT sort_buffer_size=150000 FOR set session binlog_format=row; +SELECT @@binlog_format; +@@binlog_format +ROW
those are good tests, and they make many of the tests above unnecessary
+#Correctly set timestamp +set session timestamp=4646464; +select @@timestamp != 4646464; +@@timestamp != 4646464 +0 +select @@timestamp != 4646464; +@@timestamp != 4646464 +0 +#Correctly returned normal behaviour +set session timestamp=default; +select @@timestamp != 4646464; +@@timestamp != 4646464 +1 +select @@timestamp != 4646464; +@@timestamp != 4646464 +1 +#here timestamp should be set only for the statement then restored default +set statement timestamp=4646464 for select @@timestamp; +@@timestamp +4646464.000000 +set @save_tm=@@timestamp; +select @@timestamp != 4646464; +@@timestamp != 4646464 +1 +select @@timestamp != 4646464; +@@timestamp != 4646464 +1 +select @@timestamp != @save_tm; +@@timestamp != @save_tm +1 diff --git a/sql/set_var.cc b/sql/set_var.cc index bae6511..20e3040 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -147,7 +147,7 @@ void sys_var_end() flags(flags_arg), show_val_type(show_val_type_arg), guard(lock), offset(off), on_check(on_check_func), on_update(on_update_func), deprecation_substitute(substitute), - is_os_charset(FALSE) + is_os_charset(FALSE), default_val(TRUE)
I've asked below why is that needed.
{ /* There is a limitation in handle_options() related to short options: @@ -695,7 +695,8 @@ int sql_set_variables(THD *thd, List<set_var_base> *var_list) }
err: - free_underlaid_joins(thd, &thd->lex->select_lex); + if (free) + free_underlaid_joins(thd, &thd->lex->select_lex);
Ok, so in normal SET you want to free_underlaid_joins, and in SET STATEMENT you don't. Right?
DBUG_RETURN(error); }
diff --git a/sql/item_func.cc b/sql/item_func.cc index 2b89aa0..651e0b1 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5556,7 +5556,7 @@ longlong Item_func_get_user_var::val_int() tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name, new Item_null()))); /* Create the variable */ - if (sql_set_variables(thd, &tmp_var_list)) + if (sql_set_variables(thd, &tmp_var_list, true))
Make if 'false', not 'true' here. It doesn't make any practical difference (there are no joins, the variable is set to Item_null, explicitly), but makes the logic a bit clearer (standalone SET statement = free joins, a SET that is part of another statement = don't free joins). Alternatively (and better) approach would be to remove sql_set_variables() here and use the same code that Item_func_set_user_var does. And then sql_set_variables() will be only used in SET variants, where a sysvar can be used. Here sysvars aren't possible, so sql_set_variables() is misleading.
{ thd->lex= sav_lex; goto err; diff --git a/sql/set_var.h b/sql/set_var.h index e48f394..9ee914b 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -118,6 +119,9 @@ class sys_var */ bool set_default(THD *thd, set_var *var); bool update(THD *thd, set_var *var); + void stmt_update(THD *thd) { + on_update && on_update(this, thd, OPT_SESSION); + }
Doesn't seem to be used anywhere in the patch
String *val_str_nolock(String *str, THD *thd, const uchar *value); longlong val_int(bool *is_null, THD *thd, enum_var_type type, const LEX_STRING *base); diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 233bb83..4072af4 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7110,3 +7110,5 @@ ER_SLAVE_SKIP_NOT_IN_GTID eng "When using GTID, @@sql_slave_skip_counter can not be used. Instead, setting @@gtid_slave_pos explicitly can be used to skip to after a given GTID position." ER_STATEMENT_TIMEOUT 70100 eng "Query execution was interrupted (max_statement_time exceeded)" +ER_SET_STATEMENT_TABLES_IS_NOT_SUPPORTED + eng "SET STATEMENT does not support using tables in the assignment variables expressions"
Better write it as ER_SUBQUERIES_NOT_SUPPORTED eng "%s does not support subqueries or stored functions." and use it for SET STATEMENT: my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT"); and also use it for KILL: - my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored " - "function calls as part of this statement"); + my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "KILL");
diff --git a/sql/sql_class.h b/sql/sql_class.h index d7bbfc3..0f6b39e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3711,6 +3711,10 @@ class THD :public Statement, void rgi_unlock_temporary_tables(); bool rgi_have_temporary_tables(); public: + inline MEM_ROOT *get_execution_mem_root() + { + return &main_mem_root; + }
Doesn't seem to be used anywhere in this patch
/* Flag, mutex and condition for a thread to wait for a signal from another thread. diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 5e9c7b9..03861d1 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2379,6 +2381,8 @@ struct LEX: public Query_tables_list required a local context, the parser pops the top-most context. */ List<Name_resolution_context> context_stack; + /* true if SET STATEMENT ... FOR ... statement is use, false otherwise */ + bool set_statement;
This doesn't seem to be needed, I've checked all places where set_statement is used below.
SQL_I_List<ORDER> proc_list; SQL_I_List<TABLE_LIST> auxiliary_table_list, save_list; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d8906b2..eff0e08 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2637,6 +2637,98 @@ static bool do_execute_sp(THD *thd, sp_head *sp) thd->get_binlog_format(&orig_binlog_format, &orig_current_stmt_binlog_format);
+ if (lex->set_statement && !lex->stmt_var_list.is_empty())
Why do you check lex->set_statement? I'd think that if (!lex->stmt_var_list.is_empty()) is quite enough.
+ { + DBUG_PRINT("info", ("SET STATEMENT %d vars", lex->stmt_var_list.elements)); + + lex->old_var_list.empty(); + List_iterator_fast<set_var_base> it(lex->stmt_var_list); + set_var_base *var; + while ((var=it++)) + { + DBUG_ASSERT(var->is_system()); + set_var *o= NULL, *v= (set_var*)var; + if (v->var->is_default()) + o= new set_var(v->type, v->var, &v->base, NULL);
Why do you treat default values differently?
+ else + { + switch (v->var->option.var_type) + { + case GET_BOOL: + case GET_INT: + case GET_LONG: + case GET_LL: + { + bool null_value; + longlong val= v->var->val_int(&null_value, thd, v->type, &v->base); + o= new set_var(v->type, v->var, &v->base, + (null_value ? + (Item *)new Item_null() : + (Item *)new Item_int(val))); + } + break; + case GET_UINT: + case GET_ULONG: + case GET_ULL: + { + bool null_value; + ulonglong val= v->var->val_int(&null_value, thd, v->type, &v->base); + o= new set_var(v->type, v->var, &v->base, + (null_value ? + (Item *)new Item_null() : + (Item *)new Item_uint(val))); + } + break; + case GET_DOUBLE: + { + bool null_value; + double val= v->var->val_real(&null_value, thd, v->type, &v->base); + o= new set_var(v->type, v->var, &v->base, + (null_value ? + (Item *)new Item_null() : + (Item *)new Item_float(val, 1))); + } + break; + default: + case GET_NO_ARG: + case GET_DISABLED: + DBUG_ASSERT(0); + case 0: + case GET_FLAGSET: + case GET_ASK_ADDR: + case GET_TYPE_MASK: + case GET_ENUM: + case GET_SET: + case GET_STR: + case GET_STR_ALLOC: + { + char buff[STRING_BUFFER_USUAL_SIZE]; + String tmp(buff, sizeof(buff), v->var->charset(thd)),*val; + val= v->var->val_str(&tmp, thd, v->type, &v->base); + if (val) + { + Item_string *str= new Item_string(v->var->charset(thd)); + str->set_str_with_copy(val->ptr(), val->length()); + o= new set_var(v->type, v->var, &v->base, str); + } + else + o= new set_var(v->type, v->var, &v->base, new Item_null()); + } + break; + } + } + DBUG_ASSERT(o); + lex->old_var_list.push_back(o); + } + if (thd->is_error() || + (res= sql_set_variables(thd, &lex->stmt_var_list, false))) + { + if (!thd->is_error()) + my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET"); + goto error; + } + } + /* Force statement logging for DDL commands to allow us to update privilege, system or statistic tables directly without the updates @@ -2812,6 +2904,12 @@ static bool do_execute_sp(THD *thd, sp_head *sp) } case SQLCOM_EXECUTE: { + /* + Clean up free_list here from Items used in setting statement variables + to present clear item list to Prepared_statement::execute_loop which + need it empty because switch arena (and so item list) on statement arena. + */ + //free_items(thd->free_list); thd->free_list= NULL;
Eh? Forgot to remove it?
mysql_sql_stmt_execute(thd); break; } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 9ae3d79..4b54989 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -4078,3 +4078,48 @@ static void restore_ptr_backup(uint n, st_ptr_backup *backup) (backup++)->restore(); }
+ +/** + Create deep copy of system_variables instance. +*/ +struct system_variables * +copy_system_variables(const struct system_variables *src)
Doesn't seem to be used anywhere in the patch
+{ + struct system_variables *dst; + + DBUG_ASSERT(src); + + dst= (struct system_variables *) + sql_alloc(sizeof(struct system_variables)); + if (!dst) + return NULL; + *dst= *src; + + if (dst->dynamic_variables_ptr) + { + if (!(dst->dynamic_variables_ptr= + (char *)my_malloc(dst->dynamic_variables_size, MYF(MY_WME | MY_FAE)))) + return NULL; + memcpy(dst->dynamic_variables_ptr, + src->dynamic_variables_ptr, + src->dynamic_variables_size); + } + + mysql_mutex_lock(&LOCK_plugin); + dst->table_plugin= + intern_plugin_lock(NULL, src->table_plugin); + mysql_mutex_unlock(&LOCK_plugin); + + return dst; +} + +void free_system_variables(struct system_variables *v)
Doesn't seem to be used anywhere in the patch
+{ + DBUG_ASSERT(v); + + mysql_mutex_lock(&LOCK_plugin); + intern_plugin_unlock(NULL, v->table_plugin); + mysql_mutex_unlock(&LOCK_plugin); + + my_free(v->dynamic_variables_ptr); +} diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e7fcdfb..d140597 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -14416,8 +14420,52 @@ set: } start_option_value_list {} + | SET STATEMENT_SYM + { + LEX *lex= Lex; + mysql_init_select(lex); + lex->sql_command= SQLCOM_SET_OPTION; + /* Don't clear var_list in the case of recursive statement */
What's "recursive set statement"? SET STATEMENT a=1 FOR SET STATEMENT ? I'd simply return a syntax error here. Like MYSQL_YYABORT_UNLESS(lex->stmt_var_list.is_empty());
+ if (!lex->set_statement) + { + lex->var_list.empty(); + lex->stmt_var_list.empty();
Why here, and not in lex_start() ?
+ } + lex->autocommit= 0; + lex->set_statement= true; + sp_head *sp= lex->sphead; + if (sp && !sp->is_invoked()) + { + sp->m_param_begin= ((yychar == YYEMPTY) ? YYLIP->get_ptr() : YYLIP->get_tok_start()); + sp->m_param_end= ((yychar == YYEMPTY) ? YYLIP->get_ptr() : YYLIP->get_tok_end());
what's that?
+ } + } + set_stmt_option_value_following_option_type_list + { + LEX *lex= Lex; + if (lex->query_tables) + { + my_error(ER_SET_STATEMENT_TABLES_IS_NOT_SUPPORTED, MYF(0));
why? what about stored functions that use tables internally?
+ MYSQL_YYABORT; + } + //if (lex->set_statement && lex->stmt_var_list.is_empty()) + { + lex->stmt_var_list= lex->var_list; + lex->var_list.empty(); + } + } + FOR_SYM statement + {} ;
+set_stmt_option_value_following_option_type_list: + /* + Only system variables can be used here. If this condition is changed + please check careful code under lex->option_type == OPT_STATEMENT + condition on wrong type casts. + */ + option_value_following_option_type + | set_stmt_option_value_following_option_type_list ',' option_value_following_option_type
// Start of option value list start_option_value_list: @@ -14522,6 +14570,14 @@ option_value_following_option_type: { LEX *lex= Lex;
+ /* + Ignore SET STATEMENT variables list on slaves because system + variables are not replicated except certain variables set the + values of whose are written to binlog event header and nothing + additional is required to set them. + */ + if (!(thd->slave_thread && lex->set_statement)) + {
Hmm, okay. Alternatively, you can simply make sure that set statement is not written into binlog. Or don't execute assignments in the slave thread.
if ($1.var && $1.var != trg_new_row_fake_var) { /* It is a system variable. */
Regards, Sergei
On 17.10.14 21:00, Sergei Golubchik wrote: > Hi, Sanja! > > On Oct 13, sanja@mariadb.com wrote: >> revision-id: 28fccccad32fa8a47dc572b968613e18ff51b634 >> parent(s): fec5ab5a56cb9a45c621207620cc85079cddf537 >> committer: Oleksandr Byelkin >> branch nick: work-maria-10.1-sysvar2 >> timestamp: 2014-10-13 22:35:40 +0200 >> message: >> >> MDEV-5231: Per query variables from Percona Server (rewritten) > This looks a lot better that the previous patch. Thanks! > See my comments below. > > Some parts of the patch are not used (left-overs from the old > implementation?). Some others, I think, are not needed. Yes, I found that I made cleanup in wrong tree :( > > And some of the old tests don't make much sense, your new tests made > them redundant and useless. > > A couple of comments after reading my previous review: > > * please add a test for any sysvar with non-trivial implementations of > sys_var::session_update(), that is, for a sysvar where old approach > doesn't work. Unless, of course, your timestamp tests are exactly that :) yes, timestamp is that test. > > * add tests with @@default_engine. For example: > > SET @@default_engine=MyISAM; > SET STATEMENT @@default_engine=MEMORY CREATE TABLE t1 (a int); > SHOW CREATE TABLE t1; -- verify the engine > SET STATEMENT @@default_engine=MyISAM CREATE TABLE t2 (a int); Done. I think that to test other & current engine is enough because we test variable not engines and using 2 engine which always present makes the test simpler. > > etc. > > See other comments below: > >> diff --git a/mysql-test/r/set_statement.result b/mysql-test/r/set_statement.result >> new file mode 100644 >> index 0000000..fed937e >> --- /dev/null >> +++ b/mysql-test/r/set_statement.result >> @@ -0,0 +1,941 @@ >> +'# SET STATEMENT ..... FOR .... TEST' >> +DROP TABLE IF EXISTS t1; >> +DROP FUNCTION IF EXISTS myProc; >> +DROP PROCEDURE IF EXISTS p1; >> +DROP PROCEDURE IF EXISTS p2; >> +DROP PROCEDURE IF EXISTS p3; >> +DROP PROCEDURE IF EXISTS p4; >> +DROP PROCEDURE IF EXISTS p5; >> +DROP TABLE IF EXISTS STATEMENT; >> +'# Setup database' >> +CREATE TABLE t1 (v1 INT, v2 INT); >> +INSERT INTO t1 VALUES (1,2); >> +INSERT INTO t1 VALUES (3,4); >> +'' >> +'#------------------ STATEMENT Test 1 -----------------------#' >> +'# Initialize variables to known setting' >> +SET SESSION sort_buffer_size=100000; >> +'' >> +'# Pre-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; >> +Variable_name Value >> +sort_buffer_size 100000 >> +SET STATEMENT sort_buffer_size=150000 FOR SELECT *,@@sort_buffer_size FROM t1; >> +v1 v2 @@sort_buffer_size >> +1 2 150000 >> +3 4 150000 >> +'' >> +'# Post-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; >> +Variable_name Value >> +sort_buffer_size 100000 >> +'' >> +'#------------------ STATEMENT Test 2 -----------------------#' >> +'# Initialize variables to known setting' >> +SET SESSION binlog_format=mixed; >> +SET SESSION sort_buffer_size=100000; >> +'# Pre-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; >> +Variable_name Value >> +sort_buffer_size 100000 >> +SHOW SESSION VARIABLES LIKE 'binlog_format'; >> +Variable_name Value >> +binlog_format MIXED >> +SET STATEMENT sort_buffer_size=150000, binlog_format=row >> +FOR SELECT *,@@sort_buffer_size,@@binlog_format FROM t1; >> +v1 v2 @@sort_buffer_size @@binlog_format >> +1 2 150000 ROW >> +3 4 150000 ROW >> +'# Post-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; >> +Variable_name Value >> +sort_buffer_size 100000 >> +SHOW SESSION VARIABLES LIKE 'binlog_format'; >> +Variable_name Value >> +binlog_format MIXED >> +'' >> +'#------------------ STATEMENT Test 3 -----------------------#' >> +'# set initial variable value, make prepared statement >> +SET SESSION binlog_format=row; >> +PREPARE stmt1 FROM 'SET STATEMENT binlog_format=row FOR SELECT *,@@binlog_format FROM t1'; >> +'' >> +'# Change variable setting' >> +SET SESSION binlog_format=mixed; >> +'' >> +'# Pre-STATEMENT variable value' >> +'' >> +SHOW SESSION VARIABLES LIKE 'binlog_format'; >> +Variable_name Value >> +binlog_format MIXED >> +'' >> +EXECUTE stmt1; >> +v1 v2 @@binlog_format >> +1 2 ROW >> +3 4 ROW >> +'' >> +'# Post-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'binlog_format'; >> +Variable_name Value >> +binlog_format MIXED >> +'' >> +DEALLOCATE PREPARE stmt1; >> +'#------------------ STATEMENT Test 4 -----------------------#' >> +'# set initial variable value, make prepared statement >> +SET SESSION myisam_sort_buffer_size=500000, myisam_repair_threads=1; >> +'' >> +'# Pre-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'myisam_sort_buffer_size'; >> +Variable_name Value >> +myisam_sort_buffer_size 500000 >> +SHOW SESSION VARIABLES LIKE 'myisam_repair_threads'; >> +Variable_name Value >> +myisam_repair_threads 1 >> +'' >> +SET STATEMENT myisam_sort_buffer_size=800000, >> +myisam_repair_threads=2 FOR OPTIMIZE TABLE t1; > 1. this is not "make prepared statement" as the comment says Yes, probably mistake of test creator (cut'n'paste?) > 2. what does it actually test? you don't verify whether > new values had any effect. I have no idea how to check the effect, but maybe it is testing crash... >> +Table Op Msg_type Msg_text >> +test.t1 optimize status OK >> +'' >> +'# Post-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'myisam_sort_buffer_size'; >> +Variable_name Value >> +myisam_sort_buffer_size 500000 >> +SHOW SESSION VARIABLES LIKE 'myisam_repair_threads'; >> +Variable_name Value >> +myisam_repair_threads 1 >> +'' >> +'#------------------ STATEMENT Test 5 -----------------------#' >> +'# Initialize variables to known setting' >> +SET SESSION sort_buffer_size=100000; >> +'' >> +'# Pre-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; >> +Variable_name Value >> +sort_buffer_size 100000 >> +'' >> +SET STATEMENT sort_buffer_size=150000 FOR SELECT * FROM t2; >> +ERROR 42S02: Table 'test.t2' doesn't exist >> +'' >> +'# Post-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; >> +Variable_name Value >> +sort_buffer_size 150000 > Looks wrong. The value is not restored in case of an error. fixed. It was problem that sql_set_variables was not working correctly is you enter it with already happened error. > >> +'' >> +'#------------------ STATEMENT Test 6 -----------------------#' >> +'# Initialize variables to known setting' >> +SET SESSION keep_files_on_create=ON; >> +'' >> +'# Pre-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'keep_files_on_create'; >> +Variable_name Value >> +keep_files_on_create ON >> +'' >> +SET STATEMENT keep_files_on_create=OFF FOR SELECT *,@@keep_files_on_create FROM t1; >> +v1 v2 @@keep_files_on_create >> +1 2 0 >> +3 4 0 > How is this test different from other tests above? > >> +'' >> +'# Post-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'keep_files_on_create'; >> +Variable_name Value >> +keep_files_on_create ON >> +'' >> +'#------------------ STATEMENT Test 7 -----------------------#' >> +'# Initialize variables to known setting' >> +SET SESSION max_join_size=2222220000000; >> +'' >> +'# Pre-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'max_join_size'; >> +Variable_name Value >> +max_join_size 2222220000000 >> +'' >> +SET STATEMENT max_join_size=1000000000000 FOR SELECT *,@@max_join_size FROM t1; >> +v1 v2 @@max_join_size >> +1 2 1000000000000 >> +3 4 1000000000000 > Same question - how is this test different from other tests above? Probably they check different variables? > >> +'' >> +'# Post-STATEMENT variable value' >> +SHOW SESSION VARIABLES LIKE 'max_join_size'; >> +Variable_name Value >> +max_join_size 2222220000000 >> +'' >> +'#------------------Test 8-----------------------#' >> +'# Initialize test variables' >> +SET SESSION myisam_sort_buffer_size=500000, >> +myisam_repair_threads=1, >> +sort_buffer_size = 200000, >> +max_join_size=2222220000000, >> +keep_files_on_create=ON; >> +'' >> +'# LONG ' >> +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; >> +Variable_name Value >> +sort_buffer_size 200000 >> +SET STATEMENT sort_buffer_size = 100000 >> +FOR SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; >> +Variable_name Value >> +sort_buffer_size 100000 >> +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; >> +Variable_name Value >> +sort_buffer_size 200000 >> +'' >> +'# MY_BOOL ' >> +SHOW SESSION VARIABLES LIKE 'keep_files_on_create'; >> +Variable_name Value >> +keep_files_on_create ON >> +SET STATEMENT keep_files_on_create=OFF >> +FOR SHOW SESSION VARIABLES LIKE 'keep_files_on_create'; >> +Variable_name Value >> +keep_files_on_create OFF >> +SHOW SESSION VARIABLES LIKE 'keep_files_on_create'; >> +Variable_name Value >> +keep_files_on_create ON >> +'' >> +'# INT/LONG ' >> +SHOW SESSION VARIABLES LIKE 'myisam_repair_threads'; >> +Variable_name Value >> +myisam_repair_threads 1 >> +SET STATEMENT myisam_repair_threads=2 >> +FOR SHOW SESSION VARIABLES LIKE 'myisam_repair_threads'; >> +Variable_name Value >> +myisam_repair_threads 2 >> +SHOW SESSION VARIABLES LIKE 'myisam_repair_threads'; >> +Variable_name Value >> +myisam_repair_threads 1 >> +'' >> +'# ULONGLONG ' >> +SHOW SESSION VARIABLES LIKE 'max_join_size'; >> +Variable_name Value >> +max_join_size 2222220000000 >> +SET STATEMENT max_join_size=2000000000000 >> +FOR SHOW SESSION VARIABLES LIKE 'max_join_size'; >> +Variable_name Value >> +max_join_size 2000000000000 >> +SHOW SESSION VARIABLES LIKE 'max_join_size'; >> +Variable_name Value >> +max_join_size 2222220000000 >> +'' >> +'#------------------Test 9-----------------------#' >> +'# set initial variable values >> +SET SESSION myisam_sort_buffer_size=500000, >> +myisam_repair_threads=1, >> +sort_buffer_size=100000, >> +binlog_format=mixed, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000; >> +'' >> +'' >> +'# Pre-STATEMENT variable value >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +CREATE FUNCTION myProc (cost DECIMAL(10,2)) >> +RETURNS DECIMAL(10,2) >> +SQL SECURITY DEFINER >> +tax: BEGIN >> +DECLARE order_tax DECIMAL(10,2); >> +SET order_tax = cost * .05; >> +RETURN order_tax; >> +END| >> +'' >> +'# During Execution values >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +binlog_format=row, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +SELECT myProc(123.45); >> +myProc(123.45) >> +6.17 > How does this verify that SET STATEMENT had any effect? fixed > >> +'' >> +'# Post-STATEMENT No 1 variable value Pre-STATEMENT for No 2' >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +binlog_format=row, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +DROP FUNCTION myProc; > How does this verify that SET STATEMENT had any effect? I have no idea what is verified here (crash, syntax, or just test suite was strange from the beginning?) > >> +'' >> +'# Post-STATEMENT No 2 variable value >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'#------------------Test 10-----------------------#' >> +'# set initial variable values >> +SET SESSION myisam_sort_buffer_size=500000, >> +myisam_repair_threads=1, >> +sort_buffer_size=100000, >> +binlog_format=mixed, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000; >> +'' >> +'# Pre-STATEMENT variable value >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +binlog_format=row, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +PREPARE stmt2 >> +FROM 'SELECT * FROM t1'; >> +'' >> +'Test No 1 Post Value & Test 2 Pre values' >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +binlog_format=row, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +EXECUTE stmt2; >> +v1 v2 >> +1 2 >> +3 4 > How does this verify that SET STATEMENT had any effect? > > Add @@binlog_format and @@sort_buffer_size to the SELECT > and use different values for @@sort_buffer_size in > SET STATEMENT for PREPARE and EXECUTE. > > Ok, I see that you do it below. Then how is this test useful? removed > >> +'' >> +'# Post-STATEMENT No 2 >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +DEALLOCATE PREPARE stmt2; >> +'' >> +'#------------------Test 11-----------------------#' >> +'# set initial variable values >> +SET SESSION myisam_sort_buffer_size=500000, >> +myisam_repair_threads=1, >> +sort_buffer_size=100000, >> +binlog_format=mixed, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000; >> +'' >> +'' >> +'# Pre-STATEMENT variable value >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +PREPARE stmt1 FROM >> +'SET STATEMENT binlog_format=row FOR SELECT *,@@binlog_format FROM t1'; > please also add @@sort_buffer_size to this SELECT ok > >> +'' >> +'Test No 1 Post Value & Test 2 Pre values' >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +EXECUTE stmt1; >> +v1 v2 @@binlog_format >> +1 2 ROW >> +3 4 ROW >> +'' >> +'# Post-STATEMENT No 2 >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +'#------------------Test 12-----------------------#' >> +'# set initial variable values >> +SET SESSION myisam_sort_buffer_size=500000, >> +myisam_repair_threads=1, >> +sort_buffer_size=100000, >> +binlog_format=mixed, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000; >> +'' >> +'' >> +'# Pre-STATEMENT variable value >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +binlog_format=row, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +CREATE PROCEDURE p1() BEGIN >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +END| >> +'' >> +'Test No 1 Post Value & Test 2 Pre values' >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +binlog_format=row, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR > Use different values here, not same as in the previous SET STATEMENT ok > >> +CALL p1(); >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +400000 2 200000 ROW 0 4444440000000 >> +'' >> +'# Post-STATEMENT No 2 >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +'#------------------Test 13-----------------------#' >> +'# set initial variable values >> +SET SESSION myisam_sort_buffer_size=500000, >> +myisam_repair_threads=1, >> +sort_buffer_size=100000, >> +binlog_format=mixed, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000; >> +'' >> +'' >> +CREATE PROCEDURE p2() BEGIN >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=3, >> +sort_buffer_size=300000, >> +binlog_format=mixed, >> +keep_files_on_create=OFF, >> +max_join_size=3333330000000 FOR >> +CALL p1(); >> +END| >> +'' >> +'# Pre-STATEMENT variable value >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +binlog_format=row, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +CALL p2(); >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +400000 3 300000 MIXED 0 3333330000000 >> +'' >> +'# Post-STATEMENT >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +'#------------------Test 14-----------------------#' >> +'# set initial variable values >> +SET SESSION myisam_sort_buffer_size=500000, >> +myisam_repair_threads=1, >> +sort_buffer_size=100000, >> +binlog_format=mixed, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000; >> +'' >> +'' >> +CREATE PROCEDURE p3() BEGIN >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +SET STATEMENT myisam_sort_buffer_size=320000, >> +myisam_repair_threads=2, >> +sort_buffer_size=220022, >> +binlog_format=row, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000 FOR >> +CALL p2(); >> +END| >> +'' >> +'# Pre-STATEMENT variable value >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +binlog_format=row, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +CALL p3(); >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +400000 2 200000 ROW 0 4444440000000 >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +400000 3 300000 MIXED 0 3333330000000 >> +'' >> +'# Post-STATEMENT >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +'' >> +'' >> +'#------------------Test 15-----------------------#' >> +'# set initial variable values >> +SET SESSION myisam_sort_buffer_size=500000, >> +myisam_repair_threads=1, >> +sort_buffer_size=100000, >> +binlog_format=mixed, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000; >> +'' >> +'' >> +CREATE PROCEDURE p4() BEGIN >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +SET STATEMENT myisam_sort_buffer_size=320000, >> +myisam_repair_threads=2, >> +sort_buffer_size=220022, >> +binlog_format=row, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000 FOR >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +SET STATEMENT myisam_sort_buffer_size=320000, >> +myisam_repair_threads=2, >> +sort_buffer_size=220022, >> +binlog_format=row, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000 FOR >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +SET STATEMENT myisam_sort_buffer_size=320000, >> +myisam_repair_threads=2, >> +sort_buffer_size=220022, >> +binlog_format=row, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000 FOR >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +END| >> +'' >> +'# Pre-STATEMENT variable value >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +binlog_format=row, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +CALL p4(); >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +400000 2 200000 ROW 0 4444440000000 >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +320000 2 220022 ROW 1 2222220000000 >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +320000 2 220022 ROW 1 2222220000000 >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +320000 2 220022 ROW 1 2222220000000 >> +'' >> +'# Post-STATEMENT >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +'#------------------Test 16-----------------------#' >> +'' >> +'# Pre-STATEMENT variable value >> +SELECT @@sql_mode; >> +@@sql_mode >> + >> +'' >> +'' >> +SET STATEMENT sql_mode='ansi' FOR PREPARE stmt FROM 'SELECT "t1".* FROM t1'; >> +execute stmt; >> +v1 v2 >> +1 2 >> +3 4 > Ok, that's getting interesting. Now before deallocating, try to trigger > automatic reprepare. e.g. ALTER TABLE t1 ADD COLUMN v3 int; > and then execute it again. > > also do the same with SP. I mean, set statement sql_mode=ansi create procedure > this procedure uses ansi quotes. verify that the correct sql mode (ansi) > is recorded in mysql.proc table. All checks added and fixed what could be fixed. > >> +deallocate prepare stmt; >> +'' >> +'# Post-STATEMENT >> +SELECT @@sql_mode; >> +@@sql_mode >> + >> +'' >> +'' >> +'#------------------Test 17-----------------------#' >> +'# set initial variable values >> +SET SESSION myisam_sort_buffer_size=500000, >> +myisam_repair_threads=1, >> +sort_buffer_size=100000, >> +binlog_format=mixed, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000; >> +'' >> +'# Pre-STATEMENT variable value >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +SET STATEMENT myisam_sort_buffer_size=320000, >> +myisam_repair_threads=2, >> +sort_buffer_size=220022, >> +binlog_format=row, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000 >> +FOR SET SESSION >> +myisam_sort_buffer_size=260000, >> +myisam_repair_threads=3, >> +sort_buffer_size=230013, >> +binlog_format=row, >> +keep_files_on_create=ON, >> +max_join_size=2323230000000; > Add a couple of other variables to SET SESSION. The point - have some > variables in SET SESSION that are *not* present in SET STATEMENT. > Verify that their values were correctly set. > > Ok, I see that you do it below. Then how is this test useful? > >> +'' >> +'# Post-STATEMENT >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +'#------------------Test 18-----------------------#' >> +'# set initial variable values >> +SET SESSION myisam_sort_buffer_size=500000, >> +myisam_repair_threads=1, >> +sort_buffer_size=100000, >> +binlog_format=mixed, >> +keep_files_on_create=ON, >> +max_join_size=2222220000000; >> +'' >> +'# Pre-STATEMENT variable value >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +CREATE PROCEDURE p5() BEGIN >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +SET SESSION >> +myisam_sort_buffer_size=260000, >> +myisam_repair_threads=3, >> +sort_buffer_size=230013, >> +binlog_format=row, >> +keep_files_on_create=ON, >> +max_join_size=2323230000000; >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +END| > How is this test different from other tests above? > >> +'' >> +'' >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=2, >> +sort_buffer_size=200000, >> +binlog_format=row, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +CALL p5(); >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +400000 2 200000 ROW 0 4444440000000 >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +260000 3 230013 ROW 1 2323230000000 >> +'' >> +'# Post-STATEMENT >> +SELECT @@myisam_sort_buffer_size, >> +@@myisam_repair_threads, >> +@@sort_buffer_size, >> +@@binlog_format, >> +@@keep_files_on_create, >> +@@max_join_size; >> +@@myisam_sort_buffer_size @@myisam_repair_threads @@sort_buffer_size @@binlog_format @@keep_files_on_create @@max_join_size >> +500000 1 100000 MIXED 1 2222220000000 >> +'' >> +'' >> +'#------------------Test 19-----------------------#' >> +SET STATEMENT max_error_count=100 FOR; >> +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 >> +SET STATEMENT max_error_count=100 INSERT t1 VALUES (1,2); >> +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INSERT t1 VALUES (1,2)' at line 1 >> +SET STATEMENT FOR INSERT INTO t1 VALUES (1,2); >> +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FOR INSERT INTO t1 VALUES (1,2)' at line 1 >> +SET max_error_count=100 FOR INSERT INTO t1 VALUES (1,2); >> +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FOR INSERT INTO t1 VALUES (1,2)' at line 1 >> +SET max_error_count=100 FOR INSERT INTO t1 VALUES (1,2); > Same erroneous statement tested twice? removed > >> +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FOR INSERT INTO t1 VALUES (1,2)' at line 1 >> +SET STATEMENT GLOBAL max_error_count=100 FOR INSERT INTO t1 VALUES (1,2); >> +ERROR HY000: Unknown system variable 'GLOBAL' >> +SET STATEMENT @@global.max_error_count=100 FOR INSERT INTO t1 VALUES (1,2); >> +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '@@global.max_error_count=100 FOR INSERT INTO t1 VALUES (1,2)' at line 1 >> +'' >> +'' >> +'#------------------Test 20-----------------------#' >> +SET STATEMENT connect_timeout=100 FOR INSERT INTO t1 VALUES (1,2); >> +ERROR HY000: Variable 'connect_timeout' is a GLOBAL variable and should be set with SET GLOBAL >> +'' >> +'' >> +'#------------------Test 21-----------------------#' >> +SELECT @@myisam_sort_buffer_size, @@sort_buffer_size; >> +@@myisam_sort_buffer_size @@sort_buffer_size >> +500000 100000 >> +SET STATEMENT myisam_sort_buffer_size = 700000, sort_buffer_size = 3000000 >> +FOR SET STATEMENT myisam_sort_buffer_size=200000 >> +FOR SELECT @@myisam_sort_buffer_size, @@sort_buffer_size; >> +@@myisam_sort_buffer_size @@sort_buffer_size >> +200000 100000 >> +SELECT @@myisam_sort_buffer_size, @@sort_buffer_size; >> +@@myisam_sort_buffer_size @@sort_buffer_size >> +500000 100000 >> +'' >> +'' >> +'#------------------Test 22-----------------------#' >> +CREATE TABLE STATEMENT(a INT); >> +DROP TABLE STATEMENT; >> +'' >> +'# Cleanup' >> +DROP TABLE t1; >> +DROP PROCEDURE p1; >> +DROP PROCEDURE p2; >> +DROP PROCEDURE p3; >> +DROP PROCEDURE p4; >> +DROP PROCEDURE p5; >> +CREATE TABLE t1 (v1 INT, v2 INT); >> +PREPARE stmt >> +FROM 'SELECT * FROM t1'; >> +SET STATEMENT myisam_sort_buffer_size=400000, >> +myisam_repair_threads=(select max(v1) from t1), >> +sort_buffer_size=200000, >> +binlog_format=row, >> +keep_files_on_create=OFF, >> +max_join_size=4444440000000 FOR >> +EXECUTE stmt; >> +ERROR HY000: SET STATEMENT does not support using tables in the assignment variables expressions > Why do you need a prepared statement to test that error? Fixed > >> +deallocate prepare stmt; >> +drop table t1; >> +set session binlog_format=mixed; >> +PREPARE stmt1 FROM 'SELECT @@binlog_format'; >> +execute stmt1; >> +@@binlog_format >> +MIXED >> +set statement binlog_format=row for execute stmt1; >> +@@binlog_format >> +ROW >> +execute stmt1; >> +@@binlog_format >> +MIXED >> +deallocate prepare stmt1; >> +set statement binlog_format=row for PREPARE stmt1 FROM 'SELECT @@binlog_format'; >> +execute stmt1; >> +@@binlog_format >> +MIXED >> +execute stmt1; >> +@@binlog_format >> +MIXED >> +deallocate prepare stmt1; >> +PREPARE stmt1 FROM 'set statement binlog_format=row for SELECT @@binlog_format'; >> +execute stmt1; >> +@@binlog_format >> +ROW >> +execute stmt1; >> +@@binlog_format >> +ROW >> +deallocate prepare stmt1; >> +set session binlog_format=default; >> +set session binlog_format=mixed; >> +SET STATEMENT sort_buffer_size=150000 FOR set session binlog_format=row; >> +SELECT @@binlog_format; >> +@@binlog_format >> +ROW > those are good tests, and they make many of the tests above unnecessary I only can guess what some test means, so I tried keep all test just in case they are testing something I am not think of. > >> +#Correctly set timestamp >> +set session timestamp=4646464; >> +select @@timestamp != 4646464; >> +@@timestamp != 4646464 >> +0 >> +select @@timestamp != 4646464; >> +@@timestamp != 4646464 >> +0 >> +#Correctly returned normal behaviour >> +set session timestamp=default; >> +select @@timestamp != 4646464; >> +@@timestamp != 4646464 >> +1 >> +select @@timestamp != 4646464; >> +@@timestamp != 4646464 >> +1 >> +#here timestamp should be set only for the statement then restored default >> +set statement timestamp=4646464 for select @@timestamp; >> +@@timestamp >> +4646464.000000 >> +set @save_tm=@@timestamp; >> +select @@timestamp != 4646464; >> +@@timestamp != 4646464 >> +1 >> +select @@timestamp != 4646464; >> +@@timestamp != 4646464 >> +1 >> +select @@timestamp != @save_tm; >> +@@timestamp != @save_tm >> +1 >> diff --git a/sql/set_var.cc b/sql/set_var.cc >> index bae6511..20e3040 100644 >> --- a/sql/set_var.cc >> +++ b/sql/set_var.cc >> @@ -147,7 +147,7 @@ void sys_var_end() >> flags(flags_arg), show_val_type(show_val_type_arg), >> guard(lock), offset(off), on_check(on_check_func), on_update(on_update_func), >> deprecation_substitute(substitute), >> - is_os_charset(FALSE) >> + is_os_charset(FALSE), default_val(TRUE) > I've asked below why is that needed. For some variables (like timestamp) default value is not a certain value but a special state (timestamp in such state returns current time instead of fixed value). > >> { >> /* >> There is a limitation in handle_options() related to short options: >> @@ -695,7 +695,8 @@ int sql_set_variables(THD *thd, List<set_var_base> *var_list) >> } >> >> err: >> - free_underlaid_joins(thd, &thd->lex->select_lex); >> + if (free) >> + free_underlaid_joins(thd, &thd->lex->select_lex); > Ok, so in normal SET you want to free_underlaid_joins, > and in SET STATEMENT you don't. Right? yes > >> DBUG_RETURN(error); >> } >> >> diff --git a/sql/item_func.cc b/sql/item_func.cc >> index 2b89aa0..651e0b1 100644 >> --- a/sql/item_func.cc >> +++ b/sql/item_func.cc >> @@ -5556,7 +5556,7 @@ longlong Item_func_get_user_var::val_int() >> tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name, >> new Item_null()))); >> /* Create the variable */ >> - if (sql_set_variables(thd, &tmp_var_list)) >> + if (sql_set_variables(thd, &tmp_var_list, true)) > Make if 'false', not 'true' here. It doesn't make any practical difference > (there are no joins, the variable is set to Item_null, explicitly), > but makes the logic a bit clearer (standalone SET statement = free joins, > a SET that is part of another statement = don't free joins). I went this way as i means less changes > > Alternatively (and better) approach would be to remove sql_set_variables() > here and use the same code that Item_func_set_user_var does. > > And then sql_set_variables() will be only used in SET variants, where > a sysvar can be used. Here sysvars aren't possible, so sql_set_variables() is > misleading. > >> { >> thd->lex= sav_lex; >> goto err; >> diff --git a/sql/set_var.h b/sql/set_var.h >> index e48f394..9ee914b 100644 >> --- a/sql/set_var.h >> +++ b/sql/set_var.h >> @@ -118,6 +119,9 @@ class sys_var >> */ >> bool set_default(THD *thd, set_var *var); >> bool update(THD *thd, set_var *var); >> + void stmt_update(THD *thd) { >> + on_update && on_update(this, thd, OPT_SESSION); >> + } > Doesn't seem to be used anywhere in the patch removed > >> >> String *val_str_nolock(String *str, THD *thd, const uchar *value); >> longlong val_int(bool *is_null, THD *thd, enum_var_type type, const LEX_STRING *base); >> diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt >> index 233bb83..4072af4 100644 >> --- a/sql/share/errmsg-utf8.txt >> +++ b/sql/share/errmsg-utf8.txt >> @@ -7110,3 +7110,5 @@ ER_SLAVE_SKIP_NOT_IN_GTID >> eng "When using GTID, @@sql_slave_skip_counter can not be used. Instead, setting @@gtid_slave_pos explicitly can be used to skip to after a given GTID position." >> ER_STATEMENT_TIMEOUT 70100 >> eng "Query execution was interrupted (max_statement_time exceeded)" >> +ER_SET_STATEMENT_TABLES_IS_NOT_SUPPORTED >> + eng "SET STATEMENT does not support using tables in the assignment variables expressions" > Better write it as > > ER_SUBQUERIES_NOT_SUPPORTED > eng "%s does not support subqueries or stored functions." > > and use it for SET STATEMENT: > > my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT"); > > and also use it for KILL: > > - my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored " > - "function calls as part of this statement"); > + my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "KILL"); fixed > >> diff --git a/sql/sql_class.h b/sql/sql_class.h >> index d7bbfc3..0f6b39e 100644 >> --- a/sql/sql_class.h >> +++ b/sql/sql_class.h >> @@ -3711,6 +3711,10 @@ class THD :public Statement, >> void rgi_unlock_temporary_tables(); >> bool rgi_have_temporary_tables(); >> public: >> + inline MEM_ROOT *get_execution_mem_root() >> + { >> + return &main_mem_root; >> + } > Doesn't seem to be used anywhere in this patch removed > >> /* >> Flag, mutex and condition for a thread to wait for a signal from another >> thread. >> diff --git a/sql/sql_lex.h b/sql/sql_lex.h >> index 5e9c7b9..03861d1 100644 >> --- a/sql/sql_lex.h >> +++ b/sql/sql_lex.h >> @@ -2379,6 +2381,8 @@ struct LEX: public Query_tables_list >> required a local context, the parser pops the top-most context. >> */ >> List<Name_resolution_context> context_stack; >> + /* true if SET STATEMENT ... FOR ... statement is use, false otherwise */ >> + bool set_statement; > This doesn't seem to be needed, I've checked all places where > set_statement is used below. removed > >> >> SQL_I_List<ORDER> proc_list; >> SQL_I_List<TABLE_LIST> auxiliary_table_list, save_list; >> diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc >> index d8906b2..eff0e08 100644 >> --- a/sql/sql_parse.cc >> +++ b/sql/sql_parse.cc >> @@ -2637,6 +2637,98 @@ static bool do_execute_sp(THD *thd, sp_head *sp) >> thd->get_binlog_format(&orig_binlog_format, >> &orig_current_stmt_binlog_format); >> >> + if (lex->set_statement && !lex->stmt_var_list.is_empty()) > Why do you check lex->set_statement? I'd think that > > if (!lex->stmt_var_list.is_empty()) > > is quite enough. yes > >> + { >> + DBUG_PRINT("info", ("SET STATEMENT %d vars", lex->stmt_var_list.elements)); >> + >> + lex->old_var_list.empty(); >> + List_iterator_fast<set_var_base> it(lex->stmt_var_list); >> + set_var_base *var; >> + while ((var=it++)) >> + { >> + DBUG_ASSERT(var->is_system()); >> + set_var *o= NULL, *v= (set_var*)var; >> + if (v->var->is_default()) >> + o= new set_var(v->type, v->var, &v->base, NULL); > Why do you treat default values differently? because default value is not just a value for some variables, but special state. > >> + else >> + { >> + switch (v->var->option.var_type) >> + { >> + case GET_BOOL: >> + case GET_INT: >> + case GET_LONG: >> + case GET_LL: >> + { >> + bool null_value; >> + longlong val= v->var->val_int(&null_value, thd, v->type, &v->base); >> + o= new set_var(v->type, v->var, &v->base, >> + (null_value ? >> + (Item *)new Item_null() : >> + (Item *)new Item_int(val))); >> + } >> + break; >> + case GET_UINT: >> + case GET_ULONG: >> + case GET_ULL: >> + { >> + bool null_value; >> + ulonglong val= v->var->val_int(&null_value, thd, v->type, &v->base); >> + o= new set_var(v->type, v->var, &v->base, >> + (null_value ? >> + (Item *)new Item_null() : >> + (Item *)new Item_uint(val))); >> + } >> + break; >> + case GET_DOUBLE: >> + { >> + bool null_value; >> + double val= v->var->val_real(&null_value, thd, v->type, &v->base); >> + o= new set_var(v->type, v->var, &v->base, >> + (null_value ? >> + (Item *)new Item_null() : >> + (Item *)new Item_float(val, 1))); >> + } >> + break; >> + default: >> + case GET_NO_ARG: >> + case GET_DISABLED: >> + DBUG_ASSERT(0); >> + case 0: >> + case GET_FLAGSET: >> + case GET_ASK_ADDR: >> + case GET_TYPE_MASK: >> + case GET_ENUM: >> + case GET_SET: >> + case GET_STR: >> + case GET_STR_ALLOC: >> + { >> + char buff[STRING_BUFFER_USUAL_SIZE]; >> + String tmp(buff, sizeof(buff), v->var->charset(thd)),*val; >> + val= v->var->val_str(&tmp, thd, v->type, &v->base); >> + if (val) >> + { >> + Item_string *str= new Item_string(v->var->charset(thd)); >> + str->set_str_with_copy(val->ptr(), val->length()); >> + o= new set_var(v->type, v->var, &v->base, str); >> + } >> + else >> + o= new set_var(v->type, v->var, &v->base, new Item_null()); >> + } >> + break; >> + } >> + } >> + DBUG_ASSERT(o); >> + lex->old_var_list.push_back(o); >> + } >> + if (thd->is_error() || >> + (res= sql_set_variables(thd, &lex->stmt_var_list, false))) >> + { >> + if (!thd->is_error()) >> + my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET"); >> + goto error; >> + } >> + } >> + >> /* >> Force statement logging for DDL commands to allow us to update >> privilege, system or statistic tables directly without the updates >> @@ -2812,6 +2904,12 @@ static bool do_execute_sp(THD *thd, sp_head *sp) >> } >> case SQLCOM_EXECUTE: >> { >> + /* >> + Clean up free_list here from Items used in setting statement variables >> + to present clear item list to Prepared_statement::execute_loop which >> + need it empty because switch arena (and so item list) on statement arena. >> + */ >> + //free_items(thd->free_list); thd->free_list= NULL; > Eh? Forgot to remove it? removed > >> mysql_sql_stmt_execute(thd); >> break; >> } >> diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc >> index 9ae3d79..4b54989 100644 >> --- a/sql/sql_plugin.cc >> +++ b/sql/sql_plugin.cc >> @@ -4078,3 +4078,48 @@ static void restore_ptr_backup(uint n, st_ptr_backup *backup) >> (backup++)->restore(); >> } >> >> + >> +/** >> + Create deep copy of system_variables instance. >> +*/ >> +struct system_variables * >> +copy_system_variables(const struct system_variables *src) > Doesn't seem to be used anywhere in the patch removed > >> +{ >> + struct system_variables *dst; >> + >> + DBUG_ASSERT(src); >> + >> + dst= (struct system_variables *) >> + sql_alloc(sizeof(struct system_variables)); >> + if (!dst) >> + return NULL; >> + *dst= *src; >> + >> + if (dst->dynamic_variables_ptr) >> + { >> + if (!(dst->dynamic_variables_ptr= >> + (char *)my_malloc(dst->dynamic_variables_size, MYF(MY_WME | MY_FAE)))) >> + return NULL; >> + memcpy(dst->dynamic_variables_ptr, >> + src->dynamic_variables_ptr, >> + src->dynamic_variables_size); >> + } >> + >> + mysql_mutex_lock(&LOCK_plugin); >> + dst->table_plugin= >> + intern_plugin_lock(NULL, src->table_plugin); >> + mysql_mutex_unlock(&LOCK_plugin); >> + >> + return dst; >> +} >> + >> +void free_system_variables(struct system_variables *v) > Doesn't seem to be used anywhere in the patch removed >> +{ >> + DBUG_ASSERT(v); >> + >> + mysql_mutex_lock(&LOCK_plugin); >> + intern_plugin_unlock(NULL, v->table_plugin); >> + mysql_mutex_unlock(&LOCK_plugin); >> + >> + my_free(v->dynamic_variables_ptr); >> +} >> diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy >> index e7fcdfb..d140597 100644 >> --- a/sql/sql_yacc.yy >> +++ b/sql/sql_yacc.yy >> @@ -14416,8 +14420,52 @@ set: >> } >> start_option_value_list >> {} >> + | SET STATEMENT_SYM >> + { >> + LEX *lex= Lex; >> + mysql_init_select(lex); >> + lex->sql_command= SQLCOM_SET_OPTION; >> + /* Don't clear var_list in the case of recursive statement */ > What's "recursive set statement"? SET STATEMENT a=1 FOR SET STATEMENT ? > I'd simply return a syntax error here. Like > > MYSQL_YYABORT_UNLESS(lex->stmt_var_list.is_empty()); now with separate lists they will not conflicts. > >> + if (!lex->set_statement) >> + { >> + lex->var_list.empty(); >> + lex->stmt_var_list.empty(); > Why here, and not in lex_start() ? more work on every command, but I've moved >> + } >> + lex->autocommit= 0; >> + lex->set_statement= true; >> + sp_head *sp= lex->sphead; >> + if (sp && !sp->is_invoked()) >> + { >> + sp->m_param_begin= ((yychar == YYEMPTY) ? YYLIP->get_ptr() : YYLIP->get_tok_start()); >> + sp->m_param_end= ((yychar == YYEMPTY) ? YYLIP->get_ptr() : YYLIP->get_tok_end()); > what's that? Looks like black magic but it has no effect on execution. Removed. > >> + } >> + } >> + set_stmt_option_value_following_option_type_list >> + { >> + LEX *lex= Lex; >> + if (lex->query_tables) >> + { >> + my_error(ER_SET_STATEMENT_TABLES_IS_NOT_SUPPORTED, MYF(0)); > why? what about stored functions that use tables internally? I added check later (where we iterate the list to store old values). > >> + MYSQL_YYABORT; >> + } >> + //if (lex->set_statement && lex->stmt_var_list.is_empty()) >> + { >> + lex->stmt_var_list= lex->var_list; >> + lex->var_list.empty(); >> + } >> + } >> + FOR_SYM statement >> + {} >> ; >> >> +set_stmt_option_value_following_option_type_list: >> + /* >> + Only system variables can be used here. If this condition is changed >> + please check careful code under lex->option_type == OPT_STATEMENT >> + condition on wrong type casts. >> + */ >> + option_value_following_option_type >> + | set_stmt_option_value_following_option_type_list ',' option_value_following_option_type >> >> // Start of option value list >> start_option_value_list: >> @@ -14522,6 +14570,14 @@ option_value_following_option_type: >> { >> LEX *lex= Lex; >> >> + /* >> + Ignore SET STATEMENT variables list on slaves because system >> + variables are not replicated except certain variables set the >> + values of whose are written to binlog event header and nothing >> + additional is required to set them. >> + */ >> + if (!(thd->slave_thread && lex->set_statement)) >> + { > Hmm, okay. Alternatively, you can simply make sure that set statement > is not written into binlog. Or don't execute assignments in the slave thread. Having SET STATEMENT in a separate list we do not need this check. > >> if ($1.var && $1.var != trg_new_row_fake_var) >> { >> /* It is a system variable. */ > Regards, > Sergei
Hi, Oleksandr! On Oct 21, Oleksandr Byelkin wrote: > > > > * add tests with @@default_engine. For example: > > > > SET @@default_engine=MyISAM; > > SET STATEMENT @@default_engine=MEMORY CREATE TABLE t1 (a int); > > SHOW CREATE TABLE t1; -- verify the engine > > SET STATEMENT @@default_engine=MyISAM CREATE TABLE t2 (a int); > Done. I think that to test other & current engine is enough because we > test variable not engines and using 2 engine which always present makes > the test simpler. The point was to test plugin locking. When you change a default engine, old engine plugin is unlocked, new engine plugin is locked. In the debug mode there's a code to assert that locks and unlocks are correctly paired. It doesn't matter what two engines you use, so your tests are ok. > >> +'#------------------ STATEMENT Test 4 -----------------------#' > >> +'# set initial variable value, make prepared statement > >> +SET SESSION myisam_sort_buffer_size=500000, myisam_repair_threads=1; > >> +'' > >> +'# Pre-STATEMENT variable value' > >> +SHOW SESSION VARIABLES LIKE 'myisam_sort_buffer_size'; > >> +Variable_name Value > >> +myisam_sort_buffer_size 500000 > >> +SHOW SESSION VARIABLES LIKE 'myisam_repair_threads'; > >> +Variable_name Value > >> +myisam_repair_threads 1 > >> +'' > >> +SET STATEMENT myisam_sort_buffer_size=800000, > >> +myisam_repair_threads=2 FOR OPTIMIZE TABLE t1; > > 1. this is not "make prepared statement" as the comment says > Yes, probably mistake of test creator (cut'n'paste?) > > 2. what does it actually test? you don't verify whether > > new values had any effect. > I have no idea how to check the effect, but maybe it is testing crash... I think it's just one of those useless tests that doesn't test anything. There were many of them in the original patch. > >> +SET STATEMENT sort_buffer_size=150000 FOR SELECT * FROM t2; > >> +ERROR 42S02: Table 'test.t2' doesn't exist > >> +'' > >> +'# Post-STATEMENT variable value' > >> +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; > >> +Variable_name Value > >> +sort_buffer_size 150000 > > Looks wrong. The value is not restored in case of an error. > fixed. It was problem that sql_set_variables was not working correctly > is you enter it with already happened error. But the test was good, I hope you kept it. > >> +SET STATEMENT myisam_sort_buffer_size=400000, > >> +myisam_repair_threads=2, > >> +sort_buffer_size=200000, > >> +binlog_format=row, > >> +keep_files_on_create=OFF, > >> +max_join_size=4444440000000 FOR > >> +DROP FUNCTION myProc; > > How does this verify that SET STATEMENT had any effect? > I have no idea what is verified here (crash, syntax, or just test suite > was strange from the beginning?) Again, one of many useless tests in the original patch, I suppose. > >> diff --git a/sql/set_var.cc b/sql/set_var.cc > >> index bae6511..20e3040 100644 > >> --- a/sql/set_var.cc > >> +++ b/sql/set_var.cc > >> @@ -147,7 +147,7 @@ void sys_var_end() > >> flags(flags_arg), show_val_type(show_val_type_arg), > >> guard(lock), offset(off), on_check(on_check_func), on_update(on_update_func), > >> deprecation_substitute(substitute), > >> - is_os_charset(FALSE) > >> + is_os_charset(FALSE), default_val(TRUE) > > I've asked below why is that needed. > For some variables (like timestamp) default value is not a certain value > but a special state (timestamp in such state returns current time > instead of fixed value). > >> + DBUG_ASSERT(var->is_system()); > >> + set_var *o= NULL, *v= (set_var*)var; > >> + if (v->var->is_default()) > >> + o= new set_var(v->type, v->var, &v->base, NULL); > > Why do you treat default values differently? > because default value is not just a value for some variables, but > special state. And here's the review: > diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result > index e359921..95fc690 100644 > --- a/mysql-test/r/events_bugs.result > +++ b/mysql-test/r/events_bugs.result > @@ -218,13 +218,13 @@ drop event events_test.mysqltest_user1; > drop user mysqltest_user1@localhost; > drop database mysqltest_db1; > create event e_53 on schedule at (select s1 from ttx) do drop table t; > -ERROR 42000: This version of MariaDB doesn't yet support 'Usage of subqueries or stored function calls as part of this statement' > +ERROR HY000: CREATE/ALTER EVENT does not support subqueries or stored functions. SQLSTATE 42000 looks fine, please change your error message to use it > create event e_53 on schedule every (select s1 from ttx) second do drop table t; > -ERROR 42000: This version of MariaDB doesn't yet support 'Usage of subqueries or stored function calls as part of this statement' > +ERROR HY000: CREATE/ALTER EVENT does not support subqueries or stored functions. > create event e_53 on schedule every 5 second starts (select s1 from ttx) do drop table t; > -ERROR 42000: This version of MariaDB doesn't yet support 'Usage of subqueries or stored function calls as part of this statement' > +ERROR HY000: CREATE/ALTER EVENT does not support subqueries or stored functions. > create event e_53 on schedule every 5 second ends (select s1 from ttx) do drop table t; > -ERROR 42000: This version of MariaDB doesn't yet support 'Usage of subqueries or stored function calls as part of this statement' > +ERROR HY000: CREATE/ALTER EVENT does not support subqueries or stored functions. > drop event if exists e_16; > drop procedure if exists p_16; > create event e_16 on schedule every 1 second do set @a=5; > diff --git a/mysql-test/t/set_statement.test b/mysql-test/t/set_statement.test > index 3ea9235..9a2e577 100644 > --- a/mysql-test/t/set_statement.test > +++ b/mysql-test/t/set_statement.test > @@ -661,10 +610,92 @@ SELECT @@sql_mode; > --echo '' > SET STATEMENT sql_mode='ansi' FOR PREPARE stmt FROM 'SELECT "t1".* FROM t1'; > execute stmt; > +ALTER TABLE t1 ADD COLUMN v3 int; > +# repreparation with other mode cause an error > +--error ER_PARSE_ERROR > +execute stmt; > +ALTER TABLE t1 drop COLUMN v3; > deallocate prepare stmt; > --echo '' > --echo '# Post-STATEMENT > SELECT @@sql_mode; > +--echo check the same behaviour in normal set > +SET sql_mode='ansi'; > +PREPARE stmt FROM 'SELECT "t1".* FROM t1'; > +SET sql_mode=default; > +execute stmt; > +ALTER TABLE t1 ADD COLUMN v3 int; > +# repreparation with other mode cause an error > +--error ER_PARSE_ERROR > +execute stmt; > +ALTER TABLE t1 drop COLUMN v3; > +deallocate prepare stmt; > +# the above test about SP > +SELECT @@sql_mode; > +SET sql_mode='ansi'; > +SELECT @@sql_mode; > +DELIMITER |; > + CREATE PROCEDURE p6() BEGIN > + SELECT @@sql_mode; > + SELECT "t1".* FROM t1; > + END| > +DELIMITER ;| > +SET sql_mode=default; > +call p6; > +ALTER TABLE t1 ADD COLUMN v3 int; > +--echo # no reparsing for now You can still force re-parsing by somehow flushing the SP cache. E.g. you can start a new connection and run the SP there, try that, please. > +call p6; > +ALTER TABLE t1 drop COLUMN v3; > +drop procedure p6; > + > + > +SELECT @@sql_mode; > +DELIMITER |; > +--echo # SET and the statement parsed as one unit before the SET takes effect > +--error ER_PARSE_ERROR > +SET STATEMENT sql_mode='ansi' FOR > + CREATE PROCEDURE p6() BEGIN > + SELECT @@sql_mode; > + SELECT "t1".* FROM t1; > + END| > +DELIMITER ;| > +#call p1; > +#ALTER TABLE t1 ADD COLUMN v3 int; > +#--echo # no reparsing for now > +#call p1; > +#ALTER TABLE t1 drop COLUMN v3; > +#drop procedure p1; > + > + > +# the above test about compaund statement compOund, not compAund > +SELECT @@sql_mode; > +SET sql_mode='ansi'; > +SELECT @@sql_mode; > +DELIMITER |; > +BEGIN NOT ATOMIC > + SELECT @@sql_mode; > + SELECT "t1".* FROM t1; > +END| > +DELIMITER ;| > +SET sql_mode=default; > + > + > +SELECT @@sql_mode; > +DELIMITER |; > +--echo # SET and the statement parsed as one unit before the SET takes effect > +--error ER_PARSE_ERROR > +SET STATEMENT sql_mode='ansi' FOR > +BEGIN NOT ATOMIC > + SELECT @@sql_mode; > + SELECT "t1".* FROM t1; > +END| > +SET STATEMENT sql_mode='ansi' FOR > +BEGIN NOT ATOMIC > + SELECT @@sql_mode; > + SELECT * FROM t1; > + SELECT @@sql_mode; > +END| > +DELIMITER ;| > --echo '' > --echo '' > --echo '#------------------Test 17-----------------------#' > diff --git a/sql/set_var.cc b/sql/set_var.cc > index 20e3040..1dad360 100644 > --- a/sql/set_var.cc > +++ b/sql/set_var.cc > @@ -687,7 +688,7 @@ int sql_set_variables(THD *thd, List<set_var_base> *var_list, bool free) > if ((error= var->check(thd))) > goto err; > } > - if (!(error= MY_TEST(thd->is_error()))) > + if (was_error || !(error= MY_TEST(thd->is_error()))) ok, this is that bug with restoring values after an error... > { > it.rewind(); > while ((var= it++)) > diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt > index 4072af4..e3f0de7 100644 > --- a/sql/share/errmsg-utf8.txt > +++ b/sql/share/errmsg-utf8.txt > @@ -7110,5 +7110,5 @@ ER_SLAVE_SKIP_NOT_IN_GTID > eng "When using GTID, @@sql_slave_skip_counter can not be used. Instead, setting @@gtid_slave_pos explicitly can be used to skip to after a given GTID position." > ER_STATEMENT_TIMEOUT 70100 > eng "Query execution was interrupted (max_statement_time exceeded)" > -ER_SET_STATEMENT_TABLES_IS_NOT_SUPPORTED > - eng "SET STATEMENT does not support using tables in the assignment variables expressions" > +ER_SUBQUERIES_NOT_SUPPORTED Here use SQLSTATE 42000 > + eng "%s does not support subqueries or stored functions." > diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc > index eff0e08..0fa3b15 100644 > --- a/sql/sql_parse.cc > +++ b/sql/sql_parse.cc > @@ -2648,6 +2648,11 @@ static bool do_execute_sp(THD *thd, sp_head *sp) > { > DBUG_ASSERT(var->is_system()); > set_var *o= NULL, *v= (set_var*)var; > + if (v->value->walk(&Item::is_sp_processor, FALSE, NULL)) > + { > + my_error(ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT"); > + goto error; > + } couldn't you rather check lex->table_or_sp_used() in the parser (like events or KILL are doing) instead of walking the item tree? > if (v->var->is_default()) > o= new set_var(v->type, v->var, &v->base, NULL); > else > @@ -2727,6 +2732,11 @@ static bool do_execute_sp(THD *thd, sp_head *sp) > my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET"); > goto error; > } > + if (lex->sql_command == SQLCOM_COMPOUND) > + { > + /* mode might be changed by SET STATEMENT */ > + lex->sphead->m_sql_mode= thd->variables.sql_mode; > + } In fact, it might be that you don't need that and you can remove my fix for MDEV-6609 and simply put this assignment into 'case SQLCOM_COMPOUND:' > } > > /* Regards, Sergei
On 21.10.14 17:40, Sergei Golubchik wrote: [skip]
+SET STATEMENT sort_buffer_size=150000 FOR SELECT * FROM t2; +ERROR 42S02: Table 'test.t2' doesn't exist +'' +'# Post-STATEMENT variable value' +SHOW SESSION VARIABLES LIKE 'sort_buffer_size'; +Variable_name Value +sort_buffer_size 150000 Looks wrong. The value is not restored in case of an error. fixed. It was problem that sql_set_variables was not working correctly is you enter it with already happened error. But the test was good, I hope you kept it.
yes of course
create event e_53 on schedule every (select s1 from ttx) second do drop table t; -ERROR 42000: This version of MariaDB doesn't yet support 'Usage of subqueries or stored function calls as part of this statement' +ERROR HY000: CREATE/ALTER EVENT does not support subqueries or stored functions. create event e_53 on schedule every 5 second starts (select s1 from ttx) do drop table t; -ERROR 42000: This version of MariaDB doesn't yet support 'Usage of subqueries or stored function calls as part of this statement' +ERROR HY000: CREATE/ALTER EVENT does not support subqueries or stored functions. create event e_53 on schedule every 5 second ends (select s1 from ttx) do drop table t; -ERROR 42000: This version of MariaDB doesn't yet support 'Usage of subqueries or stored function calls as part of this statement' +ERROR HY000: CREATE/ALTER EVENT does not support subqueries or stored functions. drop event if exists e_16; drop procedure if exists p_16; create event e_16 on schedule every 1 second do set @a=5; diff --git a/mysql-test/t/set_statement.test b/mysql-test/t/set_statement.test index 3ea9235..9a2e577 100644 --- a/mysql-test/t/set_statement.test +++ b/mysql-test/t/set_statement.test @@ -661,10 +610,92 @@ SELECT @@sql_mode; --echo '' SET STATEMENT sql_mode='ansi' FOR PREPARE stmt FROM 'SELECT "t1".* FROM t1'; execute stmt; +ALTER TABLE t1 ADD COLUMN v3 int; +# repreparation with other mode cause an error +--error ER_PARSE_ERROR +execute stmt; +ALTER TABLE t1 drop COLUMN v3; deallocate prepare stmt; --echo '' --echo '# Post-STATEMENT SELECT @@sql_mode; +--echo check the same behaviour in normal set +SET sql_mode='ansi'; +PREPARE stmt FROM 'SELECT "t1".* FROM t1'; +SET sql_mode=default; +execute stmt; +ALTER TABLE t1 ADD COLUMN v3 int; +# repreparation with other mode cause an error +--error ER_PARSE_ERROR +execute stmt; +ALTER TABLE t1 drop COLUMN v3; +deallocate prepare stmt; +# the above test about SP +SELECT @@sql_mode; +SET sql_mode='ansi'; +SELECT @@sql_mode; +DELIMITER |; + CREATE PROCEDURE p6() BEGIN + SELECT @@sql_mode; + SELECT "t1".* FROM t1; + END| +DELIMITER ;| +SET sql_mode=default; +call p6; +ALTER TABLE t1 ADD COLUMN v3 int; +--echo # no reparsing for now You can still force re-parsing by somehow flushing the SP cache. E.g. you can start a new connection and run the SP there, try that, please.
I found that creating/dropping view flushes the cache and used it [skip]
if (v->var->is_default()) o= new set_var(v->type, v->var, &v->base, NULL); else @@ -2727,6 +2732,11 @@ static bool do_execute_sp(THD *thd, sp_head *sp) my_error(ER_WRONG_ARGUMENTS, MYF(0), "SET"); goto error; } + if (lex->sql_command == SQLCOM_COMPOUND) + { + /* mode might be changed by SET STATEMENT */ + lex->sphead->m_sql_mode= thd->variables.sql_mode; + } In fact, it might be that you don't need that and you can remove my fix for MDEV-6609 and simply put this assignment into 'case SQLCOM_COMPOUND:'
I did so and removed yours fix. [skip]
participants (2)
-
Oleksandr Byelkin
-
Sergei Golubchik