From 4d62eb39be4c4f2ffb9e5a7a14e48da193286c12 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Apr 2007 19:05:19 +0200 Subject: [PATCH 01/74] The fix for Bug#18946: Test case rpl_ndb_ddl disabled pushed around end of March 2007 enabled this testcase. It was later disabled because the test failed with timeout on one testing box. The reason for this failing test could not be found because we do not have informations about the conditions on the box during this test. Jeb and I tried this test on other boxes and it passed. My experience is that - tests using NDB need in general often significant more runtime than comparable tests of other storage engines - the actual load of the box where the test is running and the filesystem (nfs could be extreme slow) where the tests are executed might have a huge impact on the test performance (runtime * 2 till 3) - there are sometimes problems with the ports most probably caused by OS properties (NDB+RPL need many ports) or parallel tests accidently running with the same ports. AFAIK these are the reasons why the NDB tests fail sometimes with timeout. Conclusion: We enable rpl_ndb_ddl again because the failure happens in rare cases and seems not to be caused by errors within the server or test code. mysql-test/t/disabled.def: Enable t/rpl_ndb_ddl.test again --- mysql-test/t/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index ad2c7a6c08c..ba00b8fa3b1 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -23,7 +23,6 @@ rpl_ndb_circular_simplex : BUG#27972 2007-04-20 mats Slave cannot start where it rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not replicated rpl_ndb_2myisam : BUG#19227 Seems to pass currently rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD -rpl_ndb_ddl : BUG#18946 result file needs update + test needs to checked rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK on master rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement From 779d13a0cd23c8f8b116c80133287966893b1006 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Apr 2007 11:23:41 +0200 Subject: [PATCH 02/74] The combination NDB and statement based replication is extreme slow and this fails usually because of testing timeout. mysql-test/t/rpl_ndb_ddl.test: Avoid execution of this test with statement based replication because it is far way too slow. --- mysql-test/t/rpl_ndb_ddl.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/rpl_ndb_ddl.test b/mysql-test/t/rpl_ndb_ddl.test index ca7a4ce4968..f49cd3c1f88 100644 --- a/mysql-test/t/rpl_ndb_ddl.test +++ b/mysql-test/t/rpl_ndb_ddl.test @@ -24,6 +24,7 @@ # --source include/master-slave.inc +--source include/have_binlog_format_mixed_or_row.inc --source include/have_ndb.inc let $engine_type= NDB; let $temp_engine_type= MEMORY; From df22909536a7f054a224a5937b0991139a1954cf Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Apr 2007 17:49:50 +0200 Subject: [PATCH 03/74] Minor improvement to save some testing runtime (~ 2 minutes). Reason: This test executes DML statements on a NDB table to detect if some SQL statements of special interest commits the ongoing transaction. When running in MIXED mode, automatic switching from statement-based to row-based replication takes place when a DML statement updates an NDB table. That means running this test on NDB with binlog-format=mixed and binlog-format=row mostly checks the same routines twice. Therefore we skip the variant with binlog-format=mixed. mysql-test/t/rpl_ndb_ddl.test: Prevent the execution of this test if replication format is statement or mixed. --- mysql-test/t/rpl_ndb_ddl.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/rpl_ndb_ddl.test b/mysql-test/t/rpl_ndb_ddl.test index f49cd3c1f88..66db755de15 100644 --- a/mysql-test/t/rpl_ndb_ddl.test +++ b/mysql-test/t/rpl_ndb_ddl.test @@ -24,7 +24,7 @@ # --source include/master-slave.inc ---source include/have_binlog_format_mixed_or_row.inc +--source include/have_binlog_format_row.inc --source include/have_ndb.inc let $engine_type= NDB; let $temp_engine_type= MEMORY; From 9c2923fef4bbf671123f75236a2411cdfb66e2e4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 May 2007 13:18:07 +0500 Subject: [PATCH 04/74] Bug#27898 UPDATEXML Crashes the Server! Problem: when replacing the root element, UpdateXML erroneously tried to mix old XML content with the replacement string, which led to crash. Fix: don't use the old XML content in these cases, just return the replacement string. mysql-test/r/xml.result: Adding test case mysql-test/t/xml.test: Adding test case sql/item_xmlfunc.cc: Adding special code to handle replacements of the root element - the replacing content is just copied to the result, the previous content of the XML value is removed. --- mysql-test/r/xml.result | 7 +++++++ mysql-test/t/xml.test | 7 +++++++ sql/item_xmlfunc.cc | 10 ++++++++++ 3 files changed, 24 insertions(+) diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result index 236c50774bd..82f83e079e7 100644 --- a/mysql-test/r/xml.result +++ b/mysql-test/r/xml.result @@ -547,6 +547,13 @@ UpdateXML(@xml, '/a/b/@bb2', '') select UpdateXML(@xml, '/a/b/@bb2', 'bb3="bb3"'); UpdateXML(@xml, '/a/b/@bb2', 'bb3="bb3"') bb +select updatexml('
12
', +'/','12') as upd1; +upd1 +12 +select updatexml('', '/', '') as upd2; +upd2 + SET @xml= 'lesser wombat'; select extractvalue(@xml,'order/clerk'); extractvalue(@xml,'order/clerk') diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test index 8517dce111f..88ea519e610 100644 --- a/mysql-test/t/xml.test +++ b/mysql-test/t/xml.test @@ -231,6 +231,13 @@ select UpdateXML(@xml, '/a/b/@bb1', 'bb3="bb3"'); select UpdateXML(@xml, '/a/b/@bb2', ''); select UpdateXML(@xml, '/a/b/@bb2', 'bb3="bb3"'); +# +# Bug#27898 UPDATEXML Crashes the Server! +# +select updatexml('
12
', + '/','12') as upd1; +select updatexml('', '/', '') as upd2; + # # Bug#16234 XML: Crash if ExtractValue() # diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 26474990644..d29738429b7 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2768,6 +2768,16 @@ String *Item_func_xml_update::val_str(String *str) nodebeg+= fltbeg->num; + if (!nodebeg->level) + { + /* + Root element, without NameTest: + UpdateXML(xml, '/', 'replacement'); + Just return the replacement string. + */ + return rep; + } + tmp_value.length(0); tmp_value.set_charset(collation.collation); uint offs= nodebeg->type == MY_XML_NODE_TAG ? 1 : 0; From 70e94549824d87174cacc0e830004e7da093da54 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 4 May 2007 09:59:36 -0400 Subject: [PATCH 05/74] BUG#18980 : Test 'rpl_row_blob_innodb' fails randomly Failure was not reproduced under testing with the latest clone. This patch re-enables the test. mysql-test/t/disabled.def: BUG#18980 : Test 'rpl_row_blob_innodb' fails randomly This patch enables the test. --- mysql-test/t/disabled.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index ba00b8fa3b1..57c3e1b7aba 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -26,7 +26,7 @@ rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK on master rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement -rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly +#rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly rpl_udf : BUG#27564 2007-03-31 lars New test case for rpl of UDF shows valgrind failure synchronization : Bug#24529 Test 'synchronization' fails on Mac pushbuild; Also on Linux 64 bit. From 1fa1c7a8cecb9ceea3afa1b7b6da081dd2654ba0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 May 2007 20:43:19 -0400 Subject: [PATCH 06/74] BUG#17233 : LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed This patch corrects a bug involving a LOAD DATA INFILE operation on a transactional table. It corrects a problem in the error handler moving the transactional table check and autocommit_or_rollback operation to the end of the error handler. An additional test case was added to detect this condition. mysql-test/r/rpl_loaddata.result: BUG#17233 : LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed This patch adds the results for the additional test for properly handling the duplicate key error on LOAD DATA INFILE. mysql-test/t/rpl_loaddata.test: BUG#17233 : LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed This patch adds an additional test to rpl_loaddata for handling the duplicate key error on LOAD DATA INFILE. sql/sql_load.cc: BUG#17233 : LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed This patch moves the check for a transactional table and rollback in the error handler for mysql_load(). The patch moves the transactional table check to the end of the error handler matching the implementation for other similar operations (see sql_insert). --- mysql-test/r/rpl_loaddata.result | 4 ++++ mysql-test/t/rpl_loaddata.test | 12 ++++++++++++ sql/sql_load.cc | 6 +++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index d69786c00a1..b4b8d8b9a07 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -80,3 +80,7 @@ ERROR 23000: Duplicate entry '2003-03-22' for key 1 drop table t2; drop table t2; drop table t1; +CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB; +LOAD DATA INFILE "../std_data_ln/words.dat" INTO TABLE t1; +ERROR 23000: Duplicate entry 'Aarhus' for key 1 +DROP TABLE IF EXISTS t1; diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test index 5ebdec6f761..27fa7fb95a6 100644 --- a/mysql-test/t/rpl_loaddata.test +++ b/mysql-test/t/rpl_loaddata.test @@ -12,6 +12,7 @@ # Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986) source include/master-slave.inc; +source include/have_innodb.inc; connection slave; reset master; @@ -150,5 +151,16 @@ drop table t2; connection master; drop table t2; drop table t1; + +# BUG#17233 LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed +CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB; + +--error 1062 +LOAD DATA INFILE "../std_data_ln/words.dat" INTO TABLE t1; + +--disable warnings +DROP TABLE IF EXISTS t1; +--enable warnings + sync_with_master; # End of 4.1 tests diff --git a/sql/sql_load.cc b/sql/sql_load.cc index ee6d2d0a572..104d599fa1c 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -414,9 +414,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, if (error) { - if (transactional_table) - ha_autocommit_or_rollback(thd,error); - if (read_file_from_client) while (!read_info.next_line()) ; @@ -460,6 +457,9 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, } } #endif /*!EMBEDDED_LIBRARY*/ + if (transactional_table) + ha_autocommit_or_rollback(thd,error); + error= -1; // Error on read goto err; } From 8ce067caead824123c16f190d606f8e0b061a6c0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 May 2007 13:32:29 +0500 Subject: [PATCH 07/74] Bug#26518 XPath and variables problem Problem: XPath variables didn't work. Fix: adding variables support, both user-defined and sp local variables are now supported by XPath. mysql-test/r/xml.result: Adding test case mysql-test/t/xml.test: Adding test case sql/item_xmlfunc.cc: Adding variables support: - SP variables with standard XPath syntax: $i - User variables with non-standard syntax: $@i --- mysql-test/r/xml.result | 115 ++++++++++++++++++++++++++++++++++++++++ mysql-test/t/xml.test | 72 +++++++++++++++++++++++++ sql/item_xmlfunc.cc | 75 ++++++++++++++++++++++---- 3 files changed, 253 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result index 236c50774bd..f5ef919fd93 100644 --- a/mysql-test/r/xml.result +++ b/mysql-test/r/xml.result @@ -884,3 +884,118 @@ test select ExtractValue('test', '/a/self'); ExtractValue('test', '/a/self') test +set @i=1; +select ExtractValue('b1b2','/a/b[$@i]'); +ExtractValue('b1b2','/a/b[$@i]') +b1 +set @i=2; +select ExtractValue('b1b2','/a/b[$@i]'); +ExtractValue('b1b2','/a/b[$@i]') +b2 +set @i=NULL; +select ExtractValue('b1b2','/a/b[$@i]'); +ExtractValue('b1b2','/a/b[$@i]') + +CREATE PROCEDURE spxml(xml VARCHAR(128)) +BEGIN +DECLARE c INT; +DECLARE i INT DEFAULT 1; +SET c= ExtractValue(xml,'count(/a/b)'); +SET @i= c; +WHILE i <= c DO +BEGIN +SELECT i, @i, ExtractValue(xml,'/a/b[$i]'), ExtractValue(xml,'/a/b[$@i]'); +SET i= i + 1; +SET @i= @i - 1; +END; +END WHILE; +END| +call spxml('b1b2b3'); +i @i ExtractValue(xml,'/a/b[$i]') ExtractValue(xml,'/a/b[$@i]') +1 3 b1 b3 +i @i ExtractValue(xml,'/a/b[$i]') ExtractValue(xml,'/a/b[$@i]') +2 2 b2 b2 +i @i ExtractValue(xml,'/a/b[$i]') ExtractValue(xml,'/a/b[$@i]') +3 1 b3 b1 +drop procedure spxml; +Multiple matches, but no index specification +SELECT ExtractValue('b1b2','/a/b'); +ExtractValue('b1b2','/a/b') +b1 b2 +No matches +SELECT ExtractValue('b1b2','/a/c'); +ExtractValue('b1b2','/a/c') + +Index out of range +SELECT ExtractValue('b1b2','/a/b[-1]'); +ExtractValue('b1b2','/a/b[-1]') + +SELECT ExtractValue('b1b2','/a/b[10]'); +ExtractValue('b1b2','/a/b[10]') + +With string-to-number conversion +SELECT ExtractValue('b1b2','/a/b["1"]'); +ExtractValue('b1b2','/a/b["1"]') +b1 +SELECT ExtractValue('b1b2','/a/b["1 and string"]'); +ExtractValue('b1b2','/a/b["1 and string"]') +b1 +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '1 and string"]' +Warning 1292 Truncated incorrect INTEGER value: '1 and string"]' +SELECT ExtractValue('b1b2','/a/b["string and 1"]'); +ExtractValue('b1b2','/a/b["string and 1"]') + +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'string and 1"]' +Warning 1292 Truncated incorrect INTEGER value: 'string and 1"]' +SELECT ExtractValue('b1b2','/a/b["string"]'); +ExtractValue('b1b2','/a/b["string"]') + +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'string"]' +Warning 1292 Truncated incorrect INTEGER value: 'string"]' +String-to-number conversion from a user variable +SET @i='1'; +SELECT ExtractValue('b1b2','/a/b[$@i]'); +ExtractValue('b1b2','/a/b[$@i]') +b1 +SET @i='1 and string'; +SELECT ExtractValue('b1b2','/a/b[$@i]'); +ExtractValue('b1b2','/a/b[$@i]') +b1 +SET @i='string and 1'; +SELECT ExtractValue('b1b2','/a/b[$@i]'); +ExtractValue('b1b2','/a/b[$@i]') + +SET @i='string'; +SELECT ExtractValue('b1b2','/a/b[$@i]'); +ExtractValue('b1b2','/a/b[$@i]') + +String-to-number conversion with a CHAR SP variable +CREATE PROCEDURE spxml(xml VARCHAR(128), i CHAR(16)) +BEGIN +SELECT ExtractValue(xml,'/a/b[$i]'); +END| +CALL spxml('b1b2', '1'); +ExtractValue(xml,'/a/b[$i]') +b1 +CALL spxml('b1b2', '1 and string'); +ExtractValue(xml,'/a/b[$i]') +b1 +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '1 and string ' +Warning 1292 Truncated incorrect INTEGER value: '1 and string ' +CALL spxml('b1b2', 'string and 1'); +ExtractValue(xml,'/a/b[$i]') + +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'string and 1 ' +Warning 1292 Truncated incorrect INTEGER value: 'string and 1 ' +CALL spxml('b1b2', 'string'); +ExtractValue(xml,'/a/b[$i]') + +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'string ' +Warning 1292 Truncated incorrect INTEGER value: 'string ' +DROP PROCEDURE spxml; diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test index 8517dce111f..94b45fa249f 100644 --- a/mysql-test/t/xml.test +++ b/mysql-test/t/xml.test @@ -444,3 +444,75 @@ select ExtractValue('test', '/a/parent'); select ExtractValue('test', '/a/preceding'); select ExtractValue('test', '/a/preceding-sibling'); select ExtractValue('test', '/a/self'); + +# +# Bug#26518 XPath and variables problem +# Check with user defined variables +# +set @i=1; +select ExtractValue('b1b2','/a/b[$@i]'); +set @i=2; +select ExtractValue('b1b2','/a/b[$@i]'); +set @i=NULL; +select ExtractValue('b1b2','/a/b[$@i]'); + +# +# Check variables in a stored procedure - both local and user variables +# Make sure that SP and local variables with the same name work together. +# +DELIMITER |; +CREATE PROCEDURE spxml(xml VARCHAR(128)) +BEGIN + DECLARE c INT; + DECLARE i INT DEFAULT 1; + SET c= ExtractValue(xml,'count(/a/b)'); + SET @i= c; + WHILE i <= c DO + BEGIN + SELECT i, @i, ExtractValue(xml,'/a/b[$i]'), ExtractValue(xml,'/a/b[$@i]'); + SET i= i + 1; + SET @i= @i - 1; + END; + END WHILE; +END| +DELIMITER ;| + +call spxml('b1b2b3'); +drop procedure spxml; + +# +# Additional tests for bug#26518 +--echo Multiple matches, but no index specification +SELECT ExtractValue('b1b2','/a/b'); +--echo No matches +SELECT ExtractValue('b1b2','/a/c'); +--echo Index out of range +SELECT ExtractValue('b1b2','/a/b[-1]'); +SELECT ExtractValue('b1b2','/a/b[10]'); +--echo With string-to-number conversion +SELECT ExtractValue('b1b2','/a/b["1"]'); +SELECT ExtractValue('b1b2','/a/b["1 and string"]'); +SELECT ExtractValue('b1b2','/a/b["string and 1"]'); +SELECT ExtractValue('b1b2','/a/b["string"]'); +--echo String-to-number conversion from a user variable +SET @i='1'; +SELECT ExtractValue('b1b2','/a/b[$@i]'); +SET @i='1 and string'; +SELECT ExtractValue('b1b2','/a/b[$@i]'); +SET @i='string and 1'; +SELECT ExtractValue('b1b2','/a/b[$@i]'); +SET @i='string'; +SELECT ExtractValue('b1b2','/a/b[$@i]'); + +--echo String-to-number conversion with a CHAR SP variable +DELIMITER |; +CREATE PROCEDURE spxml(xml VARCHAR(128), i CHAR(16)) +BEGIN + SELECT ExtractValue(xml,'/a/b[$i]'); +END| +DELIMITER ;| +CALL spxml('b1b2', '1'); +CALL spxml('b1b2', '1 and string'); +CALL spxml('b1b2', 'string and 1'); +CALL spxml('b1b2', 'string'); +DROP PROCEDURE spxml; diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 26474990644..52962b3558e 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -19,7 +19,7 @@ #include "mysql_priv.h" #include "my_xml.h" - +#include "sp_pcontext.h" /* TODO: future development directions: @@ -2412,21 +2412,78 @@ my_xpath_parse_QName(MY_XPATH *xpath) } -/* +/** Scan Variable reference - SYNOPSYS + @details Implements parsing of two syntax structures: - [36] VariableReference ::= '$' QName - RETURN - 1 - success - 0 - failure + 1. Standard XPath syntax [36], for SP variables: + + VariableReference ::= '$' QName + + Finds a SP variable with the given name. + If outside of a SP context, or variable with + the given name doesn't exists, then error is returned. + + 2. Non-standard syntax - MySQL extension for user variables: + + VariableReference ::= '$' '@' QName + + Item, corresponding to the variable, is returned + in xpath->item in both cases. + + @param xpath pointer to XPath structure + + @return Operation status + @retval 1 Success + @retval 0 Failure */ + static int my_xpath_parse_VariableReference(MY_XPATH *xpath) { - return my_xpath_parse_term(xpath, MY_XPATH_LEX_DOLLAR) && - my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT); + LEX_STRING name; + int user_var; + const char *dollar_pos; + if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_DOLLAR) || + (!(dollar_pos= xpath->prevtok.beg)) || + (!((user_var= my_xpath_parse_term(xpath, MY_XPATH_LEX_AT) && + my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))) && + !my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))) + return 0; + + name.length= xpath->prevtok.end - xpath->prevtok.beg; + name.str= (char*) xpath->prevtok.beg; + + if (user_var) + xpath->item= new Item_func_get_user_var(name); + else + { + sp_variable_t *spv; + sp_pcontext *spc; + LEX *lex; + if ((lex= current_thd->lex) && + (spc= lex->spcont) && + (spv= spc->find_variable(&name))) + { + Item_splocal *splocal= new Item_splocal(name, spv->offset, spv->type, 0); +#ifndef DBUG_OFF + if (splocal) + splocal->m_sp= lex->sphead; +#endif + xpath->item= (Item*) splocal; + } + else + { + xpath->item= NULL; + DBUG_ASSERT(xpath->query.end > dollar_pos); + uint len= xpath->query.end - dollar_pos; + set_if_smaller(len, 32); + my_printf_error(ER_UNKNOWN_ERROR, "Unknown XPATH variable at: '%.*s'", + MYF(0), len, dollar_pos); + } + } + return xpath->item ? 1 : 0; } From 7dec2749f4d4fdd8c4d72f81958fbaa08057494c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 May 2007 17:04:56 +0500 Subject: [PATCH 08/74] Fixing crash when compiled using -DNEW_HASH_FUNCTIONS (an experimental feature). --- heap/hp_hash.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/heap/hp_hash.c b/heap/hp_hash.c index c5a30a3ef65..d8eee9c794c 100644 --- a/heap/hp_hash.c +++ b/heap/hp_hash.c @@ -379,7 +379,13 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) { - register ulong nr=0; + /* + Note, if a key consists of a combination of numeric and + a text columns, it most likely won't work well. + Making text columns work with NEW_HASH_FUNCTION + needs also changes in strings/ctype-xxx.c. + */ + ulong nr= 1, nr2= 4; HA_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) @@ -401,14 +407,15 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) } if (seg->type == HA_KEYTYPE_TEXT) { - seg->charset->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,NULL); + seg->charset->coll->hash_sort(seg->charset, pos, ((uchar*)key)-pos, + &nr, &nr2); } else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ { uint pack_length= 2; /* Key packing is constant */ uint length= uint2korr(pos); - seg->charset->hash_sort(seg->charset, pos+pack_length, length, &nr, - NULL); + seg->charset->coll->hash_sort(seg->charset, pos+pack_length, length, + &nr, &nr2); key+= pack_length; } else @@ -428,7 +435,7 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) { - register ulong nr=0; + ulong nr= 1, nr2= 4; HA_KEYSEG *seg,*endseg; for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) @@ -444,14 +451,16 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) } if (seg->type == HA_KEYTYPE_TEXT) { - seg->charset->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,NULL); + uint char_length= seg->length; /* TODO: fix to use my_charpos() */ + seg->charset->coll->hash_sort(seg->charset, pos, char_length, + &nr, &nr2); } else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ { uint pack_length= seg->bit_start; uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos)); - seg->charset->hash_sort(seg->charset, pos+pack_length, - length, &nr, NULL); + seg->charset->coll->hash_sort(seg->charset, pos+pack_length, + length, &nr, &nr2); } else { From f508249f8b476646f2423bd33e76946ae36a5eca Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 May 2007 10:17:00 -0400 Subject: [PATCH 09/74] BUG#17233 : LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed This patch corrects a bug involving a LOAD DATA INFILE operation on a transactional table. It corrects a problem in the error handler by moving the transactional table check and autocommit_or_rollback operation to the end of the error handler. The problem was an assert was thrown after the operation completed. The assert found a non-sunk event in the transaction cache. The events in the transaction cache were added after commit_or_rollack and thereafter nothing removed them. An additional test case was added to detect this condition. mysql-test/extra/rpl_tests/rpl_loaddata.test: BUG#17233 : LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed This patch adds an additional test to rpl_loaddata for handling the duplicate key error on LOAD DATA INFILE. mysql-test/r/rpl_loaddata.result: BUG#17233 : LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed This patch adds the results for the additional test for properly handling the duplicate key error on LOAD DATA INFILE. sql/sql_load.cc: BUG#17233 : LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed This patch moves the check for a transactional table and rollback in the error handler for mysql_load(). The patch moves the transactional table check to the end of the error handler matching the implementation for other similar operations (see sql_insert). --- mysql-test/extra/rpl_tests/rpl_loaddata.test | 12 ++++++++++++ mysql-test/r/rpl_loaddata.result | 4 ++++ sql/sql_load.cc | 6 +++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test index 111b66ff7fe..dea83f65898 100644 --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test @@ -15,6 +15,7 @@ # Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986) -- source include/master-slave.inc +source include/have_innodb.inc; connection slave; reset master; @@ -156,4 +157,15 @@ drop table t2; connection master; drop table t2; drop table t1; + +# BUG#17233 LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed +CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB; + +--error ER_DUP_ENTRY_WITH_KEY_NAME +LOAD DATA INFILE "../std_data_ln/words.dat" INTO TABLE t1; + +--disable warnings +DROP TABLE IF EXISTS t1; +--enable warnings + # End of 4.1 tests diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index cabc20b7057..680796a4be6 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -86,3 +86,7 @@ ERROR 23000: Duplicate entry '2003-03-22' for key 'day' drop table t2; drop table t2; drop table t1; +CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB; +LOAD DATA INFILE "../std_data_ln/words.dat" INTO TABLE t1; +ERROR 23000: Duplicate entry 'Aarhus' for key 'PRIMARY' +DROP TABLE IF EXISTS t1; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 71cc4c0507c..40962d82bc4 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -413,9 +413,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, if (error) { - if (transactional_table) - ha_autocommit_or_rollback(thd,error); - if (read_file_from_client) while (!read_info.next_line()) ; @@ -463,6 +460,9 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, } } #endif /*!EMBEDDED_LIBRARY*/ + if (transactional_table) + ha_autocommit_or_rollback(thd,error); + error= -1; // Error on read goto err; } From c63086259a51677800d4c4380f54846bf0bdecdc Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 11 May 2007 11:48:34 +0400 Subject: [PATCH 10/74] WL#3702 --- mysql-test/mysql-test-run.pl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 7f775bd0942..a0517b71251 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3851,13 +3851,15 @@ sub mysqld_arguments ($$$$) { } else { - mtr_add_arg($args, "%s--master-user=root", $prefix); - mtr_add_arg($args, "%s--master-connect-retry=1", $prefix); - mtr_add_arg($args, "%s--master-host=127.0.0.1", $prefix); - mtr_add_arg($args, "%s--master-password=", $prefix); - mtr_add_arg($args, "%s--master-port=%d", $prefix, - $master->[0]->{'port'}); # First master - + if ($mysql_version_id < 50200) + { + mtr_add_arg($args, "%s--master-user=root", $prefix); + mtr_add_arg($args, "%s--master-connect-retry=1", $prefix); + mtr_add_arg($args, "%s--master-host=127.0.0.1", $prefix); + mtr_add_arg($args, "%s--master-password=", $prefix); + mtr_add_arg($args, "%s--master-port=%d", $prefix, + $master->[0]->{'port'}); # First master + } my $slave_server_id= 2 + $idx; my $slave_rpl_rank= $slave_server_id; mtr_add_arg($args, "%s--server-id=%d", $prefix, $slave_server_id); From 199dab236da0713d575b421ddd632232905a1022 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 11 May 2007 14:13:20 -0400 Subject: [PATCH 11/74] BUG#17233 : LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed This patch enables the NDB test ndb_load that was previously disabled as a result of the LOAD DATA INFILE bug reported in BUG#17233. --- mysql-test/t/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index df56165950f..f57ead41926 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -10,5 +10,4 @@ # ############################################################################## -ndb_load : Bug#17233 user_limits : Bug#23921 random failure of user_limits.test From fda27597eef5315ae0334ce6354d0dfe807e6672 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 18 May 2007 12:29:06 +0400 Subject: [PATCH 12/74] Bug #27907 "Misleading error message when opening/locking tables" Adjust the check that defines the error message to be returned. mysql-test/r/sp-error.result: Update results (more accurate error code) mysql-test/r/sp-prelocking.result: Update results (more accurate error code) mysql-test/r/trigger.result: Update results (more accurate error code) mysql-test/t/sp-error.test: ER_NOT_LOCKED -> ER_NO_SUCH_TABLE mysql-test/t/sp-prelocking.test: Add a test case for Bug#27907 mysql-test/t/trigger.test: ER_NOT_LOCKED -> ER_NO_SUCH_TABLE sql/sql_base.cc: Adjust the check for where-we-are for a better error message. --- mysql-test/r/sp-error.result | 6 +++--- mysql-test/r/sp-prelocking.result | 13 +++++++++++++ mysql-test/r/trigger.result | 4 ++-- mysql-test/t/sp-error.test | 6 +++--- mysql-test/t/sp-prelocking.test | 31 +++++++++++++++++++++++++++++++ mysql-test/t/trigger.test | 4 ++-- sql/sql_base.cc | 13 ++++++++++--- 7 files changed, 64 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index bdcb51c4db8..7a2f812cde4 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1030,7 +1030,7 @@ select bug12329(); bug12329() 101 execute stmt1; -ERROR HY000: Table 't2' was not locked with LOCK TABLES +ERROR 42S02: Table 'test.t2' doesn't exist deallocate prepare stmt1; drop function bug12329; drop table t1, t2; @@ -1152,12 +1152,12 @@ create trigger t1_ai after insert on t1 for each row insert into t2 values (new. create view v1 as select * from t1; drop table t2; insert into v1 values (1); -ERROR HY000: Table 't2' was not locked with LOCK TABLES +ERROR 42S02: Table 'test.t2' doesn't exist drop trigger t1_ai; create function bug11555_1() returns int return (select max(i) from t2); create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1(); insert into v1 values (2); -ERROR HY000: Table 't2' was not locked with LOCK TABLES +ERROR 42S02: Table 'test.t2' doesn't exist drop function bug11555_1; drop table t1; drop view v1; diff --git a/mysql-test/r/sp-prelocking.result b/mysql-test/r/sp-prelocking.result index 7d8dd862748..5eac54803f0 100644 --- a/mysql-test/r/sp-prelocking.result +++ b/mysql-test/r/sp-prelocking.result @@ -254,4 +254,17 @@ execute stmt; deallocate prepare stmt; drop function bug19634; drop table t1, t2, t3; +drop table if exists bug_27907_logs; +drop table if exists bug_27907_t1; +create table bug_27907_logs (a int); +create table bug_27907_t1 (a int); +create trigger bug_27907_t1_ai after insert on bug_27907_t1 +for each row +begin +insert into bug_27907_logs (a) values (1); +end| +drop table bug_27907_logs; +insert into bug_27907_t1(a) values (1); +ERROR 42S02: Table 'test.bug_27907_logs' doesn't exist +drop table bug_27907_t1; End of 5.0 tests diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 3e6a901dc00..196a990c673 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -820,9 +820,9 @@ call p1(); drop trigger t1_bi; create trigger t1_bi after insert on t1 for each row insert into t3 values (new.id); execute stmt1; -ERROR HY000: Table 't3' was not locked with LOCK TABLES +ERROR 42S02: Table 'test.t3' doesn't exist call p1(); -ERROR HY000: Table 't3' was not locked with LOCK TABLES +ERROR 42S02: Table 'test.t3' doesn't exist deallocate prepare stmt1; drop procedure p1; drop table t1, t2, t3; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 9e5c795d586..ec91be13ba0 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -1454,7 +1454,7 @@ select bug12329(); # Until we implement proper mechanism for invalidation of PS/SP when table # or SP's are changed the following statement will fail with 'Table ... was # not locked' error (this mechanism should be based on the new TDC). ---error 1100 +--error ER_NO_SUCH_TABLE execute stmt1; deallocate prepare stmt1; drop function bug12329; @@ -1639,13 +1639,13 @@ create trigger t1_ai after insert on t1 for each row insert into t2 values (new. create view v1 as select * from t1; drop table t2; # Limitation, the desired error is ER_VIEW_INVALID ---error ER_TABLE_NOT_LOCKED +--error ER_NO_SUCH_TABLE insert into v1 values (1); drop trigger t1_ai; create function bug11555_1() returns int return (select max(i) from t2); create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1(); # Limitation, the desired error is ER_VIEW_INVALID ---error ER_TABLE_NOT_LOCKED +--error ER_NO_SUCH_TABLE insert into v1 values (2); drop function bug11555_1; drop table t1; diff --git a/mysql-test/t/sp-prelocking.test b/mysql-test/t/sp-prelocking.test index cc3e3b93e06..ec5b7fbad7c 100644 --- a/mysql-test/t/sp-prelocking.test +++ b/mysql-test/t/sp-prelocking.test @@ -301,5 +301,36 @@ deallocate prepare stmt; drop function bug19634; drop table t1, t2, t3; +# +# Bug #27907 Misleading error message when opening/locking tables +# + +--disable_warnings +drop table if exists bug_27907_logs; +drop table if exists bug_27907_t1; +--enable_warnings + +create table bug_27907_logs (a int); +create table bug_27907_t1 (a int); + +delimiter |; + +create trigger bug_27907_t1_ai after insert on bug_27907_t1 +for each row +begin + insert into bug_27907_logs (a) values (1); +end| + +delimiter ;| + +drop table bug_27907_logs; + +# +# was failing before with error ER_NOT_LOCKED +# +--error ER_NO_SUCH_TABLE +insert into bug_27907_t1(a) values (1); + +drop table bug_27907_t1; --echo End of 5.0 tests diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index 82de4dac111..43a582439fb 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -1000,9 +1000,9 @@ create trigger t1_bi after insert on t1 for each row insert into t3 values (new. # Until we implement proper mechanism for invalidation of PS/SP when table # or SP's are changed these two statements will fail with 'Table ... was # not locked' error (this mechanism should be based on the new TDC). ---error 1100 #ER_TABLE_NOT_LOCKED +--error ER_NO_SUCH_TABLE execute stmt1; ---error 1100 #ER_TABLE_NOT_LOCKED +--error ER_NO_SUCH_TABLE call p1(); deallocate prepare stmt1; drop procedure p1; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index ed48ca577fb..4f70d115e76 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1669,10 +1669,17 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, VOID(pthread_mutex_unlock(&LOCK_open)); } } - if ((thd->locked_tables) && (thd->locked_tables->lock_count > 0)) - my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias); - else + /* + No table in the locked tables list. In case of explicit LOCK TABLES + this can happen if a user did not include the able into the list. + In case of pre-locked mode locked tables list is generated automatically, + so we may only end up here if the table did not exist when + locked tables list was created. + */ + if (thd->prelocked_mode == PRELOCKED) my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias); + else + my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias); DBUG_RETURN(0); } From 755ae21b826d6e644560b0ad397eb46cd7191369 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 18 May 2007 12:44:03 +0200 Subject: [PATCH 13/74] Bug#26277 User variable returns one type in SELECT @v and other for CREATE as SELECT @v - Adding variable m_cached_result_type to keep the variable type consistent during the execution of a statement. - Before each result set is returned to the client the description of each column is sent as meta data. Previously the result type for a column could change if the hash variable entry changed between statements. This caused the result set of the query to alternate column types in certain cases which is not supported by MySQL client-server protocol. Example: Previously this sequence: SET @a:=1; SELECT @a:="text", @a; would return "text", "text"; After the change the SELECT returns "text", 0 The reson for this is that previously the result set from 'SELECT @a;' would always be of the type STRING, whereas now the type of the variable is taken from the last SET statement. However, 'SELECT @a:="text"' will return type of STRING since the right side of the assignment is used. mysql-test/r/ps_2myisam.result: Changed test result because SQL type of a user variable now more accurately represents its Item type: since Item type of a variable can be either STRING, INT, DECIMAL or DOUBLE, SQL type of the result set metadata now can be either MYSQL_TYPE_VARCHAR, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_NEWDECIMAL or MYSQL_TYPE_DOUBLE. Previously it was always MYSQL_TYPE_VARCHAR. In particular, integer variables now have changed from MYSQL_TYPE_VARCHAR to MYSQL_TYPE_LONGLONG. mysql-test/r/ps_3innodb.result: Changed test result because SQL type of a user variable now more accurately represents its Item type: since Item type of a variable can be either STRING, INT, DECIMAL or DOUBLE, SQL type of the result set metadata now can be either MYSQL_TYPE_VARCHAR, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_NEWDECIMAL or MYSQL_TYPE_DOUBLE. Previously it was always MYSQL_TYPE_VARCHAR. In particular, integer variables now have changed from MYSQL_TYPE_VARCHAR to MYSQL_TYPE_LONGLONG. mysql-test/r/ps_4heap.result: Changed test result because SQL type of a user variable now more accurately represents its Item type: since Item type of a variable can be either STRING, INT, DECIMAL or DOUBLE, SQL type of the result set metadata now can be either MYSQL_TYPE_VARCHAR, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_NEWDECIMAL or MYSQL_TYPE_DOUBLE. Previously it was always MYSQL_TYPE_VARCHAR. In particular, integer variables now have changed from MYSQL_TYPE_VARCHAR to MYSQL_TYPE_LONGLONG. mysql-test/r/ps_5merge.result: Changed test result because SQL type of a user variable now more accurately represents its Item type: since Item type of a variable can be either STRING, INT, DECIMAL or DOUBLE, SQL type of the result set metadata now can be either MYSQL_TYPE_VARCHAR, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_NEWDECIMAL or MYSQL_TYPE_DOUBLE. Previously it was always MYSQL_TYPE_VARCHAR. In particular, integer variables now have changed from MYSQL_TYPE_VARCHAR to MYSQL_TYPE_LONGLONG. mysql-test/r/ps_7ndb.result: Changed test result because SQL type of a user variable now more accurately represents its Item type: since Item type of a variable can be either STRING, INT, DECIMAL or DOUBLE, SQL type of the result set metadata now can be either MYSQL_TYPE_VARCHAR, MYSQL_TYPE_LONGLONG, MYSQL_TYPE_NEWDECIMAL or MYSQL_TYPE_DOUBLE. Previously it was always MYSQL_TYPE_VARCHAR. In particular, integer variables now have changed from MYSQL_TYPE_VARCHAR to MYSQL_TYPE_LONGLONG. mysql-test/r/sp-vars.result: Added test case. Previously variables could change their variable type during the execution of a statement. Which variable type to use in the statement is specified in any previous statement. mysql-test/r/type_date.result: This test case result is changed because it is no longer allowed for user variables to change their variable type during the execution of a statement. The determination of which variable type to use in the statement is specified in any previous statement. mysql-test/r/user_var.result: This test case result is changed because it is no longer allowed for user variables to change their variable type during the execution of a statement. The determination of which variable type to use in the statement is specified in any previous statement. mysql-test/t/sp-vars.test: Added test case. Previously variables could change their variable type during the execution of a statement. Which variable type to use in the statement is specified in any previous statement. mysql-test/t/type_date.test: This test case result is changed because it is no longer allowed for user variables to change their variable type during the execution of a statement. The determination of which variable type to use in the statement is specified in any previous statement. sql/item_func.cc: Adding variable m_cached_result_type to keep the variable type consistent during the execution of a statement. Previously the result type could change if the hash variable entry changed between statements. This caused the result set of the query to alternate column types in certain cases. sql/item_func.h: Adding variable m_cached_result_type to keep the variable type consistent during the execution of a statement. Previously the result type could change if the hash variable entry changed between statements. This caused the result set of the query to alternate column types in certain cases. --- mysql-test/r/ps_2myisam.result | 512 ++++++++-------- mysql-test/r/ps_3innodb.result | 512 ++++++++-------- mysql-test/r/ps_4heap.result | 512 ++++++++-------- mysql-test/r/ps_5merge.result | 1024 ++++++++++++++++---------------- mysql-test/r/ps_7ndb.result | 512 ++++++++-------- mysql-test/r/sp-vars.result | 26 + mysql-test/r/type_date.result | 27 +- mysql-test/r/user_var.result | 2 +- mysql-test/t/sp-vars.test | 36 ++ mysql-test/t/type_date.test | 9 +- sql/item_func.cc | 28 +- sql/item_func.h | 5 +- 12 files changed, 1641 insertions(+), 1564 deletions(-) diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 2ce35dae092..facea5470e9 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -1917,38 +1917,38 @@ from t9 where c1= 1 ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1964,38 +1964,38 @@ from t9 where c1= 0 ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -2014,38 +2014,38 @@ execute stmt1 using @my_key ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2054,38 +2054,38 @@ execute stmt1 using @my_key ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2102,38 +2102,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 1 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2146,38 +2146,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 0 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2192,76 +2192,76 @@ set @my_key= 1 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 70181ecccdc..97a78931332 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -1900,38 +1900,38 @@ from t9 where c1= 1 ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1947,38 +1947,38 @@ from t9 where c1= 0 ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -1997,38 +1997,38 @@ execute stmt1 using @my_key ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2037,38 +2037,38 @@ execute stmt1 using @my_key ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2085,38 +2085,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 1 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2129,38 +2129,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 0 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2175,76 +2175,76 @@ set @my_key= 1 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index 19be5a2707e..3f0900888cc 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -1901,38 +1901,38 @@ from t9 where c1= 1 ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 0 31 8 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 0 31 8 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 0 31 8 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 0 31 8 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 0 31 8 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 0 31 8 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 0 31 8 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 0 31 8 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1948,38 +1948,38 @@ from t9 where c1= 0 ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 0 31 8 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 0 31 8 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 0 31 8 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 0 31 8 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 0 31 8 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 0 31 8 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 0 31 8 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 0 31 8 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -1998,38 +1998,38 @@ execute stmt1 using @my_key ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 0 31 8 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 0 31 8 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 0 31 8 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 0 31 8 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 0 31 8 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 0 31 8 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 0 31 8 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 0 31 8 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2038,38 +2038,38 @@ execute stmt1 using @my_key ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 0 31 8 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 0 31 8 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 0 31 8 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 0 31 8 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 0 31 8 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 0 31 8 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 0 31 8 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 0 31 8 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2086,38 +2086,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 1 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 0 31 8 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 0 31 8 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 0 31 8 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 0 31 8 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 0 31 8 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 0 31 8 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 0 31 8 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 0 31 8 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2130,38 +2130,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 0 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 0 31 8 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 0 31 8 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 0 31 8 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 0 31 8 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 0 31 8 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 0 31 8 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 0 31 8 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 0 31 8 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2176,76 +2176,76 @@ set @my_key= 1 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 0 31 8 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 0 31 8 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 0 31 8 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 0 31 8 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 0 31 8 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 0 31 8 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 0 31 8 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 0 31 8 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 0 31 8 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 0 31 8 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 0 31 8 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 0 31 8 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 0 31 8 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 0 31 8 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 0 31 8 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 0 31 8 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index ebdc5c8c9fd..f96ae5ea7cd 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -1837,38 +1837,38 @@ from t9 where c1= 1 ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1884,38 +1884,38 @@ from t9 where c1= 0 ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -1934,38 +1934,38 @@ execute stmt1 using @my_key ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -1974,38 +1974,38 @@ execute stmt1 using @my_key ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2022,38 +2022,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 1 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2066,38 +2066,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 0 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2112,76 +2112,76 @@ set @my_key= 1 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; @@ -4858,38 +4858,38 @@ from t9 where c1= 1 ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -4905,38 +4905,38 @@ from t9 where c1= 0 ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -4955,38 +4955,38 @@ execute stmt1 using @my_key ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -4995,38 +4995,38 @@ execute stmt1 using @my_key ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -5043,38 +5043,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 1 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -5087,38 +5087,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 0 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -5133,76 +5133,76 @@ set @my_key= 1 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index 2cffb698fc0..52057c99120 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -1900,38 +1900,38 @@ from t9 where c1= 1 ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1947,38 +1947,38 @@ from t9 where c1= 0 ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -1997,38 +1997,38 @@ execute stmt1 using @my_key ; 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2037,38 +2037,38 @@ execute stmt1 using @my_key ; 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2085,38 +2085,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 1 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2129,38 +2129,38 @@ into @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, from t9 where c1= 0 ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2175,76 +2175,76 @@ set @my_key= 1 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 1 Y 128 0 63 -def @arg03 253 20 1 Y 128 0 63 -def @arg04 253 20 1 Y 128 0 63 -def @arg05 253 20 1 Y 128 0 63 -def @arg06 253 20 1 Y 128 0 63 -def @arg07 253 23 1 Y 128 31 63 -def @arg08 253 23 1 Y 128 31 63 -def @arg09 253 23 1 Y 128 31 63 -def @arg10 253 23 1 Y 128 31 63 -def @arg11 253 67 6 Y 128 30 63 -def @arg12 253 67 6 Y 128 30 63 -def @arg13 253 16777216 10 Y 128 31 63 -def @arg14 253 16777216 19 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 8 Y 128 31 63 -def @arg17 253 20 4 Y 128 0 63 -def @arg18 253 20 1 Y 128 0 63 -def @arg19 253 20 1 Y 128 0 63 -def @arg20 253 16777216 1 Y 0 31 8 -def @arg21 253 16777216 10 Y 0 31 8 -def @arg22 253 16777216 30 Y 0 31 8 -def @arg23 253 16777216 8 Y 128 31 63 -def @arg24 253 16777216 8 Y 0 31 8 -def @arg25 253 16777216 4 Y 128 31 63 -def @arg26 253 16777216 4 Y 0 31 8 -def @arg27 253 16777216 10 Y 128 31 63 -def @arg28 253 16777216 10 Y 0 31 8 -def @arg29 253 16777216 8 Y 128 31 63 -def @arg30 253 16777216 8 Y 0 31 8 -def @arg31 253 16777216 3 Y 0 31 8 -def @arg32 253 16777216 6 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 1 Y 32896 0 63 +def @arg03 8 20 1 Y 32896 0 63 +def @arg04 8 20 1 Y 32896 0 63 +def @arg05 8 20 1 Y 32896 0 63 +def @arg06 8 20 1 Y 32896 0 63 +def @arg07 5 23 1 Y 32896 31 63 +def @arg08 5 23 1 Y 32896 31 63 +def @arg09 5 23 1 Y 32896 31 63 +def @arg10 5 23 1 Y 32896 31 63 +def @arg11 246 67 6 Y 128 30 63 +def @arg12 246 67 6 Y 128 30 63 +def @arg13 251 16777216 10 Y 128 31 63 +def @arg14 251 16777216 19 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 8 Y 128 31 63 +def @arg17 8 20 4 Y 32928 0 63 +def @arg18 8 20 1 Y 32896 0 63 +def @arg19 8 20 1 Y 32896 0 63 +def @arg20 251 16777216 1 Y 0 31 8 +def @arg21 251 16777216 10 Y 0 31 8 +def @arg22 251 16777216 30 Y 0 31 8 +def @arg23 251 16777216 8 Y 128 31 63 +def @arg24 251 16777216 8 Y 0 31 8 +def @arg25 251 16777216 4 Y 128 31 63 +def @arg26 251 16777216 4 Y 0 31 8 +def @arg27 251 16777216 10 Y 128 31 63 +def @arg28 251 16777216 10 Y 0 31 8 +def @arg29 251 16777216 8 Y 128 31 63 +def @arg30 251 16777216 8 Y 0 31 8 +def @arg31 251 16777216 3 Y 0 31 8 +def @arg32 251 16777216 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; execute stmt1 using @my_key ; execute full_info ; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def @arg01 253 20 1 Y 128 0 63 -def @arg02 253 20 0 Y 128 0 63 -def @arg03 253 20 0 Y 128 0 63 -def @arg04 253 20 0 Y 128 0 63 -def @arg05 253 20 0 Y 128 0 63 -def @arg06 253 20 0 Y 128 0 63 -def @arg07 253 23 0 Y 128 31 63 -def @arg08 253 23 0 Y 128 31 63 -def @arg09 253 23 0 Y 128 31 63 -def @arg10 253 23 0 Y 128 31 63 -def @arg11 253 67 0 Y 128 30 63 -def @arg12 253 67 0 Y 128 30 63 -def @arg13 253 16777216 0 Y 128 31 63 -def @arg14 253 16777216 0 Y 128 31 63 -def @arg15 253 16777216 19 Y 128 31 63 -def @arg16 253 16777216 0 Y 128 31 63 -def @arg17 253 20 0 Y 128 0 63 -def @arg18 253 20 0 Y 128 0 63 -def @arg19 253 20 0 Y 128 0 63 -def @arg20 253 16777216 0 Y 0 31 8 -def @arg21 253 16777216 0 Y 0 31 8 -def @arg22 253 16777216 0 Y 0 31 8 -def @arg23 253 16777216 0 Y 128 31 63 -def @arg24 253 16777216 0 Y 0 31 8 -def @arg25 253 16777216 0 Y 128 31 63 -def @arg26 253 16777216 0 Y 0 31 8 -def @arg27 253 16777216 0 Y 128 31 63 -def @arg28 253 16777216 0 Y 0 31 8 -def @arg29 253 16777216 0 Y 128 31 63 -def @arg30 253 16777216 0 Y 0 31 8 -def @arg31 253 16777216 0 Y 0 31 8 -def @arg32 253 16777216 0 Y 0 31 8 +def @arg01 8 20 1 Y 32896 0 63 +def @arg02 8 20 0 Y 32896 0 63 +def @arg03 8 20 0 Y 32896 0 63 +def @arg04 8 20 0 Y 32896 0 63 +def @arg05 8 20 0 Y 32896 0 63 +def @arg06 8 20 0 Y 32896 0 63 +def @arg07 5 23 0 Y 32896 31 63 +def @arg08 5 23 0 Y 32896 31 63 +def @arg09 5 23 0 Y 32896 31 63 +def @arg10 5 23 0 Y 32896 31 63 +def @arg11 246 67 0 Y 128 30 63 +def @arg12 246 67 0 Y 128 30 63 +def @arg13 251 16777216 0 Y 128 31 63 +def @arg14 251 16777216 0 Y 128 31 63 +def @arg15 251 16777216 19 Y 128 31 63 +def @arg16 251 16777216 0 Y 128 31 63 +def @arg17 8 20 0 Y 32928 0 63 +def @arg18 8 20 0 Y 32896 0 63 +def @arg19 8 20 0 Y 32896 0 63 +def @arg20 251 16777216 0 Y 0 31 8 +def @arg21 251 16777216 0 Y 0 31 8 +def @arg22 251 16777216 0 Y 0 31 8 +def @arg23 251 16777216 0 Y 128 31 63 +def @arg24 251 16777216 0 Y 0 31 8 +def @arg25 251 16777216 0 Y 128 31 63 +def @arg26 251 16777216 0 Y 0 31 8 +def @arg27 251 16777216 0 Y 128 31 63 +def @arg28 251 16777216 0 Y 0 31 8 +def @arg29 251 16777216 0 Y 128 31 63 +def @arg30 251 16777216 0 Y 0 31 8 +def @arg31 251 16777216 0 Y 0 31 8 +def @arg32 251 16777216 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/sp-vars.result b/mysql-test/r/sp-vars.result index a9024156c6e..358e3ad3e47 100644 --- a/mysql-test/r/sp-vars.result +++ b/mysql-test/r/sp-vars.result @@ -1161,3 +1161,29 @@ CALL p1(); v_text abc|def DROP PROCEDURE p1; +drop function if exists f1; +drop table if exists t1; +create function f1() returns int +begin +if @a=1 then set @b='abc'; +else set @b=1; +end if; +set @a=1; +return 0; +end| +create table t1 (a int)| +insert into t1 (a) values (1), (2)| +set @b=1| +set @a=0| +select f1(), @b from t1| +f1() @b +0 1 +0 0 +set @b:='test'| +set @a=0| +select f1(), @b from t1| +f1() @b +0 1 +0 abc +drop function f1; +drop table t1; diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index 6d5218873ce..d6a01727813 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -110,15 +110,24 @@ select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_dat 1 1 drop table t1; -select @d:=1111, year(@d), month(@d), day(@d), cast(@d as date); -@d:=1111 year(@d) month(@d) day(@d) cast(@d as date) -1111 2000 11 11 2000-11-11 -select @d:=011111, year(@d), month(@d), day(@d), cast(@d as date); -@d:=011111 year(@d) month(@d) day(@d) cast(@d as date) -11111 2001 11 11 2001-11-11 -select @d:=1311, year(@d), month(@d), day(@d), cast(@d as date); -@d:=1311 year(@d) month(@d) day(@d) cast(@d as date) -1311 NULL NULL NULL NULL +select @d:=1111; +@d:=1111 +1111 +select year(@d), month(@d), day(@d), cast(@d as date); +year(@d) month(@d) day(@d) cast(@d as date) +2000 11 11 2000-11-11 +select @d:=011111; +@d:=011111 +11111 +select year(@d), month(@d), day(@d), cast(@d as date); +year(@d) month(@d) day(@d) cast(@d as date) +2001 11 11 2001-11-11 +select @d:=1311; +@d:=1311 +1311 +select year(@d), month(@d), day(@d), cast(@d as date); +year(@d) month(@d) day(@d) cast(@d as date) +NULL NULL NULL NULL Warnings: Warning 1292 Incorrect datetime value: '1311' Warning 1292 Incorrect datetime value: '1311' diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 3a70dcddd24..5e9c62a1fb3 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -91,7 +91,7 @@ NULL test test set @g=1; select @g,(@g:=c),@g from t1; @g (@g:=c) @g -1 test test +1 test 0 select @c, @d, @e, @f; @c @d @e @f 1 1 2 test diff --git a/mysql-test/t/sp-vars.test b/mysql-test/t/sp-vars.test index 0014dc1f6af..9f59c7fb680 100644 --- a/mysql-test/t/sp-vars.test +++ b/mysql-test/t/sp-vars.test @@ -1368,3 +1368,39 @@ CALL p1(); DROP PROCEDURE p1; # End of 5.0 tests. + +# +# Bug #26277 User variable returns one type in SELECT @v and other for CREATE as SELECT @v +# +--disable_warnings +drop function if exists f1; +drop table if exists t1; +--enable_warnings + +delimiter |; +create function f1() returns int +begin + if @a=1 then set @b='abc'; + else set @b=1; + end if; + set @a=1; + return 0; +end| + +create table t1 (a int)| +insert into t1 (a) values (1), (2)| + +set @b=1| +set @a=0| +select f1(), @b from t1| + +set @b:='test'| +set @a=0| +select f1(), @b from t1| + +delimiter ;| + +drop function f1; +drop table t1; +# End of 5.1 tests. + diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 02cd07e3c16..dcee4fd2ffc 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -128,9 +128,12 @@ drop table t1; # Bug #23093: Implicit conversion of 9912101 to date does not match # cast(9912101 as date) # -select @d:=1111, year(@d), month(@d), day(@d), cast(@d as date); -select @d:=011111, year(@d), month(@d), day(@d), cast(@d as date); -select @d:=1311, year(@d), month(@d), day(@d), cast(@d as date); +select @d:=1111; +select year(@d), month(@d), day(@d), cast(@d as date); +select @d:=011111; +select year(@d), month(@d), day(@d), cast(@d as date); +select @d:=1311; +select year(@d), month(@d), day(@d), cast(@d as date); create table t1 (d date , dt datetime , ts timestamp); insert into t1 values (9912101,9912101,9912101); insert into t1 values (11111,11111,11111); diff --git a/sql/item_func.cc b/sql/item_func.cc index 840c5afbebd..76c30cace6c 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -36,7 +36,6 @@ #define sp_restore_security_context(A,B) while (0) {} #endif - bool check_reserved_words(LEX_STRING *name) { if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") || @@ -4339,7 +4338,7 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command, > set @a:=1; > insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1); We have to write to binlog value @a= 1. - + We allocate the user_var_event on user_var_events_alloc pool, not on the this-statement-execution pool because in SPs user_var_event objects may need to be valid after current [SP] statement execution pool is @@ -4349,7 +4348,7 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command, if (!(user_var_event= (BINLOG_USER_VAR_EVENT *) alloc_root(thd->user_var_events_alloc, size))) goto err; - + user_var_event->value= (char*) user_var_event + ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)); user_var_event->user_var_event= var_entry; @@ -4371,7 +4370,7 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command, var_entry->used_query_id= thd->query_id; if (insert_dynamic(&thd->user_var_events, (gptr) &user_var_event)) goto err; - + *out_entry= var_entry; return 0; @@ -4380,7 +4379,6 @@ err: return 1; } - void Item_func_get_user_var::fix_length_and_dec() { THD *thd=current_thd; @@ -4391,10 +4389,19 @@ void Item_func_get_user_var::fix_length_and_dec() error= get_var_with_binlog(thd, thd->lex->sql_command, name, &var_entry); + /* + If the variable didn't exist it has been created as a STRING-type. + 'var_entry' is NULL only if there occured an error during the call to + get_var_with_binlog. + */ if (var_entry) { + m_cached_result_type= var_entry->type; + unsigned_flag= var_entry->unsigned_flag; + max_length= var_entry->length; + collation.set(var_entry->collation); - switch (var_entry->type) { + switch(m_cached_result_type) { case REAL_RESULT: max_length= DBL_DIG + 8; break; @@ -4419,6 +4426,8 @@ void Item_func_get_user_var::fix_length_and_dec() { collation.set(&my_charset_bin, DERIVATION_IMPLICIT); null_value= 1; + m_cached_result_type= STRING_RESULT; + max_length= MAX_BLOB_WIDTH; } if (error) @@ -4436,12 +4445,7 @@ bool Item_func_get_user_var::const_item() const enum Item_result Item_func_get_user_var::result_type() const { - user_var_entry *entry; - if (!(entry = (user_var_entry*) hash_search(¤t_thd->user_vars, - (byte*) name.str, - name.length))) - return STRING_RESULT; - return entry->type; + return m_cached_result_type; } diff --git a/sql/item_func.h b/sql/item_func.h index 6457013b160..23ff735c858 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1247,11 +1247,12 @@ class Item_func_get_user_var :public Item_func, private Settable_routine_parameter { user_var_entry *var_entry; + Item_result m_cached_result_type; public: LEX_STRING name; // keep it public Item_func_get_user_var(LEX_STRING a): - Item_func(), name(a) {} + Item_func(), name(a), m_cached_result_type(STRING_RESULT) {} enum Functype functype() const { return GUSERVAR_FUNC; } LEX_STRING get_name() { return name; } double val_real(); @@ -1265,13 +1266,11 @@ public: We must always return variables as strings to guard against selects of type select @t1:=1,@t1,@t:="hello",@t from foo where (@t1:= t2.b) */ - enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; } const char *func_name() const { return "get_user_var"; } bool const_item() const; table_map used_tables() const { return const_item() ? 0 : RAND_TABLE_BIT; } bool eq(const Item *item, bool binary_cmp) const; - private: bool set_value(THD *thd, sp_rcontext *ctx, Item **it); From 1a60685cbaf6bcd919189ac19f01f65c50d79b54 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 19 May 2007 10:49:56 +0400 Subject: [PATCH 14/74] Patch changing how ALTER TABLE implementation handles table locking and invalidation in the most general case (non-temporary table and not simple RENAME or ENABLE/DISABLE KEYS or partitioning command). See comment for sql/sql_table.cc for more information. These changes are prerequisite for 5.1 version of fix for bug #23667 "CREATE TABLE LIKE is not isolated from alteration by other connections" mysql-test/include/mix1.inc: Extended coverage for behavior of ALTER TABLE statement under LOCK TABLES, which should be consistent across all platforms and for all engines. mysql-test/r/alter_table-big.result: Changed test for bug #25044 to use @@debug and injected sleeps infrastructure. Extended test coverage for ALTER TABLE's behavior under concurrency. mysql-test/r/alter_table.result: Extended coverage for behavior of ALTER TABLE statement under LOCK TABLES, which should be consistent across all platforms and for all engines. mysql-test/r/innodb_mysql.result: Extended coverage for behavior of ALTER TABLE statement under LOCK TABLES, which should be consistent across all platforms and for all engines. mysql-test/t/alter_table-big.test: Changed test for bug #25044 to use @@debug and injected sleeps infrastructure. Extended test coverage for ALTER TABLE's behavior under concurrency. mysql-test/t/alter_table.test: Extended coverage for behavior of ALTER TABLE statement under LOCK TABLES, which should be consistent across all platforms and for all engines. sql/mysql_priv.h: Made functions reopen_table() and close_handle_and_leave_table_as_lock() available outside of sql_base.cc file. Changed close_data_tables() in such way that after closing handler for the table it leaves TABLE object for it in table cache not as placeholder for ordinary name-lock but as placeholder for an exclusive name-lock. Renamed this routine to close_data_files_and_morph_locks(). sql/sql_base.cc: Made functions reopen_table() and close_handle_and_leave_table_as_lock() available outside of sql_base.cc file. Changed close_data_tables() in such way that after closing handler for the table it leaves TABLE object for it in table cache not as placeholder for ordinary name-lock but as placeholder for an exclusive name-lock. Renamed this routine to close_data_files_and_morph_locks(). Also adjusted it so it can work properly not only in LOCK TABLES mode. sql/sql_table.cc: Changed the way in which ALTER TABLE implementation handles table locking and invalidation in the most general case (non-temporary table and not simple RENAME or ENABLE/DISABLE KEYS or partitioning command) Now after preparing new version of the table we: 1) Wait until all other threads close old version of table. 2) Close instances of table open by this thread and replace them with exclusive name-locks. 3) Rename the old table to a temp name, rename the new one to the old name. 4) If we are under LOCK TABLES and don't do ALTER TABLE ... RENAME we reopen new version of table. 5) Write statement to the binary log. 6) If we are under LOCK TABLES and do ALTER TABLE ... RENAME we remove name-locks from list of open tables and table cache. 7) If we are not not under LOCK TABLES we rely on close_thread_tables() call to remove name-locks from table cache and list of open table. Such approach: a) Eliminates possibility for concurrent statement to sneak in and get access to the new version of the table before ALTER TABLE gets logged into binary log. b) Ensures that ALTER TABLE behaves under LOCK TABLES in the same way on all platforms and for all engines (in 5.0 this was not true) c) Preserves nice invariant that if table is open in some connection there is a guarantee that .FRM file for this table exists and is properly named. --- mysql-test/include/mix1.inc | 29 ++++ mysql-test/r/alter_table-big.result | 41 ++++- mysql-test/r/alter_table.result | 53 +++++++ mysql-test/r/innodb_mysql.result | 24 +++ mysql-test/t/alter_table-big.test | 90 ++++++++--- mysql-test/t/alter_table.test | 53 ++++++- sql/mysql_priv.h | 5 +- sql/sql_base.cc | 49 ++++-- sql/sql_table.cc | 228 +++++++++++----------------- 9 files changed, 399 insertions(+), 173 deletions(-) diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index 3919e4918c8..bf21c6fad09 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -762,4 +762,33 @@ alter table t2 modify i int default 4, rename t1; unlock tables; drop table t1; + +# +# Some more tests for ALTER TABLE and LOCK TABLES for transactional tables. +# +# Table which is altered under LOCK TABLES should stay in list of locked +# tables and be available after alter takes place unless ALTER contains +# RENAME clause. We should see the new definition of table, of course. +# Before 5.1 this behavior was inconsistent across the platforms and +# different engines. See also tests in alter_table.test +# +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (i int); +insert into t1 values (); +lock table t1 write; +# Example of so-called 'fast' ALTER TABLE +alter table t1 modify i int default 1; +insert into t1 values (); +select * from t1; +# And now full-blown ALTER TABLE +alter table t1 change i c char(10) default "Two"; +insert into t1 values (); +select * from t1; +unlock tables; +select * from t1; +drop tables t1; + + --echo End of 5.1 tests diff --git a/mysql-test/r/alter_table-big.result b/mysql-test/r/alter_table-big.result index a9d0515d6bb..9761754a02f 100644 --- a/mysql-test/r/alter_table-big.result +++ b/mysql-test/r/alter_table-big.result @@ -5,14 +5,53 @@ key (n2, n3, n1), key (n3, n1, n2)); create table t2 (i int); alter table t1 disable keys; +insert into t1 values (RAND()*1000, RAND()*1000, RAND()*1000); reset master; +set session debug="+d,sleep_alter_enable_indexes"; alter table t1 enable keys;; insert into t2 values (1); insert into t1 values (1, 1, 1); -show binlog events in 'master-bin.000001' from 102; +set session debug="-d,sleep_alter_enable_indexes"; +show binlog events in 'master-bin.000001' from 106; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; insert into t2 values (1) master-bin.000001 # Query 1 # use `test`; alter table t1 enable keys master-bin.000001 # Query 1 # use `test`; insert into t1 values (1, 1, 1) drop tables t1, t2; End of 5.0 tests +drop table if exists t1, t2, t3; +create table t1 (i int); +reset master; +set session debug="+d,sleep_alter_before_main_binlog"; +alter table t1 change i c char(10) default 'Test1';; +insert into t1 values (); +select * from t1; +c +Test1 +alter table t1 change c vc varchar(100) default 'Test2';; +rename table t1 to t2; +drop table t2; +create table t1 (i int); +alter table t1 change i c char(10) default 'Test3', rename to t2;; +insert into t2 values (); +select * from t2; +c +Test3 +alter table t2 change c vc varchar(100) default 'Test2', rename to t1;; +rename table t1 to t3; +drop table t3; +set session debug="-d,sleep_alter_before_main_binlog"; +show binlog events in 'master-bin.000001' from 106; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query 1 # use `test`; alter table t1 change i c char(10) default 'Test1' +master-bin.000001 # Query 1 # use `test`; insert into t1 values () +master-bin.000001 # Query 1 # use `test`; alter table t1 change c vc varchar(100) default 'Test2' +master-bin.000001 # Query 1 # use `test`; rename table t1 to t2 +master-bin.000001 # Query 1 # use `test`; drop table t2 +master-bin.000001 # Query 1 # use `test`; create table t1 (i int) +master-bin.000001 # Query 1 # use `test`; alter table t1 change i c char(10) default 'Test3', rename to t2 +master-bin.000001 # Query 1 # use `test`; insert into t2 values () +master-bin.000001 # Query 1 # use `test`; alter table t2 change c vc varchar(100) default 'Test2', rename to t1 +master-bin.000001 # Query 1 # use `test`; rename table t1 to t3 +master-bin.000001 # Query 1 # use `test`; drop table t3 +End of 5.1 tests diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 4481b56791f..63dc13a4b6d 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -977,6 +977,59 @@ SELECT * FROM t1; v b abc 5 DROP TABLE t1; +End of 5.0 tests +drop table if exists t1, t2, t3; +create table t1 (i int); +create table t3 (j int); +insert into t1 values (); +insert into t3 values (); +lock table t1 write, t3 read; +alter table t1 modify i int default 1; +insert into t1 values (); +select * from t1; +i +NULL +1 +alter table t1 change i c char(10) default "Two"; +insert into t1 values (); +select * from t1; +c +NULL +1 +Two +alter table t1 modify c char(10) default "Three", rename to t2; +select * from t1; +ERROR HY000: Table 't1' was not locked with LOCK TABLES +select * from t2; +ERROR HY000: Table 't2' was not locked with LOCK TABLES +select * from t3; +j +NULL +unlock tables; +insert into t2 values (); +select * from t2; +c +NULL +1 +Three +lock table t2 write, t3 read; +alter table t2 change c vc varchar(100) default "Four", rename to t1; +select * from t1; +ERROR HY000: Table 't1' was not locked with LOCK TABLES +select * from t2; +ERROR HY000: Table 't2' was not locked with LOCK TABLES +select * from t3; +j +NULL +unlock tables; +insert into t1 values (); +select * from t1; +vc +NULL +1 +Three +Four +drop tables t1, t3; DROP TABLE IF EXISTS `t+1`, `t+2`; CREATE TABLE `t+1` (c1 INT); ALTER TABLE `t+1` RENAME `t+2`; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index dc9564b21a2..c8aea5ebb61 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -796,4 +796,28 @@ lock table t2 write; alter table t2 modify i int default 4, rename t1; unlock tables; drop table t1; +drop table if exists t1; +create table t1 (i int); +insert into t1 values (); +lock table t1 write; +alter table t1 modify i int default 1; +insert into t1 values (); +select * from t1; +i +NULL +1 +alter table t1 change i c char(10) default "Two"; +insert into t1 values (); +select * from t1; +c +NULL +1 +Two +unlock tables; +select * from t1; +c +NULL +1 +Two +drop tables t1; End of 5.1 tests diff --git a/mysql-test/t/alter_table-big.test b/mysql-test/t/alter_table-big.test index befe6e14977..5d2c0ba0bb6 100644 --- a/mysql-test/t/alter_table-big.test +++ b/mysql-test/t/alter_table-big.test @@ -1,7 +1,12 @@ -# In order to be more or less robust test for bug#25044 has to take -# significant time (e.g. about 9 seconds on my (Dmitri's) computer) -# so we probably want execute it only in --big-test mode. +# +# Tests for various concurrency-related aspects of ALTER TABLE implemetation +# +# This test takes rather long time so let us run it only in --big-test mode --source include/big_test.inc +# We are using some debug-only features in this test +--source include/have_debug.inc +# Also we are using SBR to check that statements are executed +# in proper order. --source include/have_binlog_format_mixed_or_statement.inc @@ -22,27 +27,20 @@ create table t1 (n1 int, n2 int, n3 int, key (n3, n1, n2)); create table t2 (i int); -# Populating 't1' table with keys disabled, so ALTER TABLE .. ENABLE KEYS -# will run for some time +# Starting from 5.1 we have runtime settable @@debug variable, +# which can be used for introducing delays at certain points of +# statement execution, so we don't need many rows in 't1' to make +# this test repeatable. alter table t1 disable keys; ---disable_query_log -insert into t1 values (RAND()*1000,RAND()*1000,RAND()*1000); -let $1=19; -while ($1) -{ - eval insert into t1 select RAND()*1000,RAND()*1000,RAND()*1000 from t1; - dec $1; -} ---enable_query_log +insert into t1 values (RAND()*1000, RAND()*1000, RAND()*1000); # Later we use binlog to check the order in which statements are # executed so let us reset it first. reset master; +set session debug="+d,sleep_alter_enable_indexes"; --send alter table t1 enable keys; connection addconroot; -let $show_type= PROCESSLIST; -let $show_pattern= '%Repair by sorting%alter table t1 enable keys%'; ---source include/wait_show_pattern.inc +--sleep 2 # This statement should not be blocked by in-flight ALTER and therefore # should be executed and written to binlog before ALTER TABLE ... ENABLE KEYS # finishes. @@ -51,12 +49,68 @@ insert into t2 values (1); insert into t1 values (1, 1, 1); connection default; --reap +set session debug="-d,sleep_alter_enable_indexes"; # Check that statements were executed/binlogged in correct order. --replace_column 2 # 5 # -show binlog events in 'master-bin.000001' from 102; +show binlog events in 'master-bin.000001' from 106; # Clean up drop tables t1, t2; --echo End of 5.0 tests + +# +# Additional coverage for the main ALTER TABLE case +# +# We should be sure that table being altered is properly +# locked during statement execution and in particular that +# no DDL or DML statement can sneak in and get access to +# the table when real operation has already taken place +# but this fact has not been noted in binary log yet. +--disable_warnings +drop table if exists t1, t2, t3; +--enable_warnings +create table t1 (i int); +# We are going to check that statements are logged in correct order +reset master; +set session debug="+d,sleep_alter_before_main_binlog"; +--send alter table t1 change i c char(10) default 'Test1'; +connection addconroot; +--sleep 2 +insert into t1 values (); +select * from t1; +connection default; +--reap +--send alter table t1 change c vc varchar(100) default 'Test2'; +connection addconroot; +--sleep 2 +rename table t1 to t2; +connection default; +--reap +drop table t2; +# And now tests for ALTER TABLE with RENAME clause. In this +# case target table name should be properly locked as well. +create table t1 (i int); +--send alter table t1 change i c char(10) default 'Test3', rename to t2; +connection addconroot; +--sleep 2 +insert into t2 values (); +select * from t2; +connection default; +--reap +--send alter table t2 change c vc varchar(100) default 'Test2', rename to t1; +connection addconroot; +--sleep 2 +rename table t1 to t3; +connection default; +--reap +drop table t3; +set session debug="-d,sleep_alter_before_main_binlog"; + +# Check that all statements were logged in correct order +--replace_column 2 # 5 # +show binlog events in 'master-bin.000001' from 106; + + +--echo End of 5.1 tests diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 965528642bf..7d3e9bba533 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -727,7 +727,58 @@ ALTER TABLE t1 MODIFY COLUMN v VARCHAR(4); SELECT * FROM t1; DROP TABLE t1; -# End of 5.0 tests +--echo End of 5.0 tests + +# +# Extended test coverage for ALTER TABLE behaviour under LOCK TABLES +# It should be consistent across all platforms and for all engines +# (Before 5.1 this was not true as behavior was different between +# Unix/Windows and transactional/non-transactional tables). +# See also innodb_mysql.test +# +--disable_warnings +drop table if exists t1, t2, t3; +--enable_warnings +create table t1 (i int); +create table t3 (j int); +insert into t1 values (); +insert into t3 values (); +# Table which is altered under LOCK TABLES it should stay in list of locked +# tables and be available after alter takes place unless ALTER contains RENAME +# clause. We should see the new definition of table, of course. +lock table t1 write, t3 read; +# Example of so-called 'fast' ALTER TABLE +alter table t1 modify i int default 1; +insert into t1 values (); +select * from t1; +# And now full-blown ALTER TABLE +alter table t1 change i c char(10) default "Two"; +insert into t1 values (); +select * from t1; +# If table is renamed then it should be removed from the list +# of locked tables. 'Fast' ALTER TABLE with RENAME clause: +alter table t1 modify c char(10) default "Three", rename to t2; +--error ER_TABLE_NOT_LOCKED +select * from t1; +--error ER_TABLE_NOT_LOCKED +select * from t2; +select * from t3; +unlock tables; +insert into t2 values (); +select * from t2; +lock table t2 write, t3 read; +# Full ALTER TABLE with RENAME +alter table t2 change c vc varchar(100) default "Four", rename to t1; +--error ER_TABLE_NOT_LOCKED +select * from t1; +--error ER_TABLE_NOT_LOCKED +select * from t2; +select * from t3; +unlock tables; +insert into t1 values (); +select * from t1; +drop tables t1, t3; + # # Bug#18775 - Temporary table from alter table visible to other threads diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b9d5d9f9b34..e5e70f81bff 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1032,8 +1032,11 @@ TABLE *table_cache_insert_placeholder(THD *thd, const char *key, bool lock_table_name_if_not_cached(THD *thd, const char *db, const char *table_name, TABLE **table); TABLE *find_locked_table(THD *thd, const char *db,const char *table_name); +bool reopen_table(TABLE *table); bool reopen_tables(THD *thd,bool get_locks,bool in_refresh); -bool close_data_tables(THD *thd,const char *db, const char *table_name); +void close_data_files_and_morph_locks(THD *thd, const char *db, + const char *table_name); +void close_handle_and_leave_table_as_lock(TABLE *table); bool wait_for_tables(THD *thd); bool table_is_used(TABLE *table, bool wait_for_name_lock); TABLE *drop_locked_tables(THD *thd,const char *db, const char *table_name); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 14edd460bc4..82ac662c0d7 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -99,7 +99,6 @@ static bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias, TABLE_LIST *table_desc, MEM_ROOT *mem_root); static void close_old_data_files(THD *thd, TABLE *table, bool morph_locks, bool send_refresh); -static bool reopen_table(TABLE *table); static bool has_two_write_locked_tables_with_auto_increment(TABLE_LIST *tables); @@ -681,7 +680,7 @@ TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name) */ -static void close_handle_and_leave_table_as_lock(TABLE *table) +void close_handle_and_leave_table_as_lock(TABLE *table) { TABLE_SHARE *share, *old_share= table->s; char *key_buff; @@ -2705,7 +2704,7 @@ TABLE *find_locked_table(THD *thd, const char *db,const char *table_name) 1 error. The old table object is not changed. */ -static bool reopen_table(TABLE *table) +bool reopen_table(TABLE *table) { TABLE tmp; bool error= 1; @@ -2788,27 +2787,55 @@ static bool reopen_table(TABLE *table) } -/* - Used with ALTER TABLE: - Close all instanses of table when LOCK TABLES is in used; - Close first all instances of table and then reopen them +/** + @brief Close all instances of a table open by this thread and replace + them with exclusive name-locks. + + @param thd Thread context + @param db Database name for the table to be closed + @param table_name Name of the table to be closed + + @note This function assumes that if we are not under LOCK TABLES, + then there is only one table open and locked. This means that + the function probably has to be adjusted before it can be used + anywhere outside ALTER TABLE. */ -bool close_data_tables(THD *thd,const char *db, const char *table_name) +void close_data_files_and_morph_locks(THD *thd, const char *db, + const char *table_name) { TABLE *table; - DBUG_ENTER("close_data_tables"); + DBUG_ENTER("close_data_files_and_morph_locks"); + safe_mutex_assert_owner(&LOCK_open); + + if (thd->lock) + { + /* + If we are not under LOCK TABLES we should have only one table + open and locked so it makes sense to remove the lock at once. + */ + mysql_unlock_tables(thd, thd->lock); + thd->lock= 0; + } + + /* + Note that open table list may contain a name-lock placeholder + for target table name if we process ALTER TABLE ... RENAME. + So loop below makes sense even if we are not under LOCK TABLES. + */ for (table=thd->open_tables; table ; table=table->next) { if (!strcmp(table->s->table_name.str, table_name) && !strcmp(table->s->db.str, db)) { - mysql_lock_remove(thd, thd->locked_tables,table); + if (thd->locked_tables) + mysql_lock_remove(thd, thd->locked_tables, table); + table->open_placeholder= 1; close_handle_and_leave_table_as_lock(table); } } - DBUG_RETURN(0); // For the future + DBUG_VOID_RETURN; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index df336545460..149c746a1de 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5406,7 +5406,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, HA_CREATE_INFO *create_info; frm_type_enum frm_type; uint need_copy_table= 0; - bool no_table_reopen= FALSE, varchar= FALSE; + bool varchar= FALSE; #ifdef WITH_PARTITION_STORAGE_ENGINE uint fast_alter_partition= 0; bool partition_changed= FALSE; @@ -5665,6 +5665,7 @@ view_err: VOID(pthread_mutex_lock(&LOCK_open)); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); VOID(pthread_mutex_unlock(&LOCK_open)); + DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000);); error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); /* COND_refresh will be signaled in close_thread_tables() */ break; @@ -6580,9 +6581,19 @@ view_err: } /* - Data is copied. Now we rename the old table to a temp name, - rename the new one to the old name, remove all entries about the old table - from the cache, free all locks, close the old table and remove it. + Data is copied. Now we: + 1) Wait until all other threads close old version of table. + 2) Close instances of table open by this thread and replace them + with exclusive name-locks. + 3) Rename the old table to a temp name, rename the new one to the + old name. + 4) If we are under LOCK TABLES and don't do ALTER TABLE ... RENAME + we reopen new version of table. + 5) Write statement to the binary log. + 6) If we are under LOCK TABLES and do ALTER TABLE ... RENAME we + remove name-locks from list of open tables and table cache. + 7) If we are not not under LOCK TABLES we rely on close_thread_tables() + call to remove name-locks from table cache and list of open table. */ thd->proc_info="rename result table"; @@ -6591,38 +6602,8 @@ view_err: if (lower_case_table_names) my_casedn_str(files_charset_info, old_name); -#if !defined( __WIN__) - if (table->file->has_transactions()) -#endif - { - /* - Win32 and InnoDB can't drop a table that is in use, so we must - close the original table before doing the rename - */ - close_cached_table(thd, table); - table=0; // Marker that table is closed - no_table_reopen= TRUE; - } -#if !defined( __WIN__) - else - table->file->extra(HA_EXTRA_FORCE_REOPEN); // Don't use this file anymore -#endif - - if (new_name != table_name || new_db != db) - { - /* - Check that there is no table with target name. See the - comment describing code for 'simple' ALTER TABLE ... RENAME. - */ - if (!access(new_name_buff,F_OK)) - { - error=1; - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff); - VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP)); - VOID(pthread_mutex_unlock(&LOCK_open)); - goto err; - } - } + wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE); + close_data_files_and_morph_locks(thd, db, table_name); error=0; save_old_db_type= old_db_type; @@ -6667,121 +6648,64 @@ view_err: if (error) { - /* - This shouldn't happen. We solve this the safe way by - closing the locked table. - */ - if (table) - { - close_cached_table(thd,table); - } - VOID(pthread_mutex_unlock(&LOCK_open)); - goto err; + /* This shouldn't happen. But let us play it safe. */ + goto err_with_placeholders; } + if (! need_copy_table) { - bool needs_unlink= FALSE; - if (! table) + /* + Now we have to inform handler that new .FRM file is in place. + To do this we need to obtain a handler object for it. + */ + TABLE *t_table; + if (new_name != table_name || new_db != db) { - if (new_name != table_name || new_db != db) - { - table_list->alias= new_name; - table_list->table_name= new_name; - table_list->table_name_length= strlen(new_name); - table_list->db= new_db; - table_list->db_length= strlen(new_db); - } - else - { - /* - TODO: Creation of name-lock placeholder here is a temporary - work-around. Long term we should change close_cached_table() call - which we invoke before table renaming operation in such way that - it will leave placeholders for table in table cache/THD::open_tables - list. By doing this we will be able easily reopen and relock these - tables later and therefore behave under LOCK TABLES in the same way - on all platforms. - */ - char key[MAX_DBKEY_LENGTH]; - uint key_length; - key_length= create_table_def_key(thd, key, table_list, 0); - if (!(name_lock= table_cache_insert_placeholder(thd, key, - key_length))) - { - VOID(pthread_mutex_unlock(&LOCK_open)); - goto err; - } - name_lock->next= thd->open_tables; - thd->open_tables= name_lock; - } + table_list->alias= new_name; + table_list->table_name= new_name; + table_list->table_name_length= strlen(new_name); + table_list->db= new_db; + table_list->db_length= strlen(new_db); table_list->table= name_lock; if (reopen_name_locked_table(thd, table_list, FALSE)) - { - VOID(pthread_mutex_unlock(&LOCK_open)); - goto err; - } - table= table_list->table; - /* - We can't rely on later close_cached_table() calls to close - this instance of the table since it was not properly locked. - */ - needs_unlink= TRUE; + goto err_with_placeholders; + t_table= table_list->table; + } + else + { + if (reopen_table(table)) + goto err_with_placeholders; + t_table= table; } /* Tell the handler that a new frm file is in place. */ - if (table->file->create_handler_files(path, NULL, CHF_INDEX_FLAG, - create_info)) + if (t_table->file->create_handler_files(path, NULL, CHF_INDEX_FLAG, + create_info)) + goto err_with_placeholders; + if (thd->locked_tables && new_name == table_name && new_db == db) { - VOID(pthread_mutex_unlock(&LOCK_open)); - goto err; - } - if (needs_unlink) - { - unlink_open_table(thd, table, FALSE); - table= name_lock= 0; + /* + We are going to reopen table down on the road, so we have to restore + state of the TABLE object which we used for obtaining of handler + object to make it suitable for reopening. + */ + DBUG_ASSERT(t_table == table); + table->open_placeholder= 1; + close_handle_and_leave_table_as_lock(table); } } - if (thd->lock || new_name != table_name || no_table_reopen) // True if WIN32 + VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP)); + + if (thd->locked_tables && new_name == table_name && new_db == db) { - /* - Not table locking or alter table with rename. - Free locks and remove old table - */ - if (table) - { - close_cached_table(thd,table); - } - VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP)); - } - else - { - /* - Using LOCK TABLES without rename. - This code is never executed on WIN32! - Remove old renamed table, reopen table and get new locks - */ - if (table) - { - VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file - /* Mark in-use copies old */ - remove_table_from_cache(thd,db,table_name,RTFC_NO_FLAG); - /* end threads waiting on lock */ - mysql_lock_abort(thd,table, TRUE); - } - VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP)); - if (close_data_tables(thd,db,table_name) || - reopen_tables(thd,1,0)) - { // This shouldn't happen - if (table) - { - close_cached_table(thd,table); // Remove lock for table - } - VOID(pthread_mutex_unlock(&LOCK_open)); - goto err; - } + thd->in_lock_tables= 1; + error= reopen_tables(thd, 1, 0); + thd->in_lock_tables= 0; + if (error) + goto err_with_placeholders; } VOID(pthread_mutex_unlock(&LOCK_open)); - broadcast_refresh(); + /* The ALTER TABLE is always in its own transaction. Commit must not be called while LOCK_open is locked. It could call @@ -6798,6 +6722,8 @@ view_err: } thd->proc_info="end"; + DBUG_EXECUTE_IF("sleep_alter_before_main_binlog", my_sleep(6000000);); + ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE, thd->query, thd->query_length, db, table_name); @@ -6815,12 +6741,13 @@ view_err: shutdown. */ char path[FN_REFLEN]; + TABLE *t_table; build_table_filename(path, sizeof(path), new_db, table_name, "", 0); - table=open_temporary_table(thd, path, new_db, tmp_name,0); - if (table) + t_table= open_temporary_table(thd, path, new_db, tmp_name, 0); + if (t_table) { - intern_close_table(table); - my_free((char*) table, MYF(0)); + intern_close_table(t_table); + my_free((char*) t_table, MYF(0)); } else sql_print_warning("Could not open table %s.%s after rename\n", @@ -6830,9 +6757,16 @@ view_err: table_list->table=0; // For query cache query_cache_invalidate3(thd, table_list, 0); - if (name_lock) + if (thd->locked_tables && (new_name != table_name || new_db != db)) { + /* + If are we under LOCK TABLES and did ALTER TABLE with RENAME we need + to remove placeholders for the old table and for the target table + from the list of open tables and table cache. If we are not under + LOCK TABLES we can rely on close_thread_tables() doing this job. + */ pthread_mutex_lock(&LOCK_open); + unlink_open_table(thd, table, FALSE); unlink_open_table(thd, name_lock, FALSE); pthread_mutex_unlock(&LOCK_open); } @@ -6863,6 +6797,18 @@ err: pthread_mutex_unlock(&LOCK_open); } DBUG_RETURN(TRUE); + +err_with_placeholders: + /* + An error happened while we were holding exclusive name-lock on table + being altered. To be safe under LOCK TABLES we should remove placeholders + from list of open tables list and table cache. + */ + unlink_open_table(thd, table, FALSE); + if (name_lock) + unlink_open_table(thd, name_lock, FALSE); + VOID(pthread_mutex_unlock(&LOCK_open)); + DBUG_RETURN(TRUE); } /* mysql_alter_table */ From 3da4eef70072d713700219fb061cc497235477a3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 21 May 2007 10:51:11 +0200 Subject: [PATCH 15/74] Fix for bug#28075 COM_DEBUG crashes mysqld Uninitialized in the constructor member variables were pointing to nirvana and causing a crash when debug information of the Event Scheduler was dumped in result to COM_DEBUG packet sent to the server. sql/event_queue.cc: Initialize member variables or they will point to nirvana and could possible cause a crash during dumping of debug information. sql/event_queue.h: remove unneeded line sql/event_scheduler.cc: Initialize member variables or they will point to nirvana and could possible cause a crash during dumping of debug information. sql/event_scheduler.h: remove unneeded state --- sql/event_queue.cc | 15 +++++++++++---- sql/event_queue.h | 1 - sql/event_scheduler.cc | 9 +++++++-- sql/event_scheduler.h | 3 +-- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/sql/event_queue.cc b/sql/event_queue.cc index 5593e80b41b..40cb9040eef 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -70,10 +70,14 @@ event_queue_element_compare_q(void *vptr, byte* a, byte *b) */ Event_queue::Event_queue() - :mutex_last_locked_at_line(0), mutex_last_unlocked_at_line(0), + :next_activation_at(0), + mutex_last_locked_at_line(0), + mutex_last_unlocked_at_line(0), + mutex_last_locked_in_func("n/a"), + mutex_last_unlocked_in_func("n/a"), + mutex_last_attempted_lock_in_func("n/a"), mutex_last_attempted_lock_at_line(0), mutex_queue_data_locked(FALSE), - next_activation_at(0), mutex_queue_data_attempting_lock(FALSE) { mutex_last_unlocked_in_func= mutex_last_locked_in_func= @@ -739,8 +743,11 @@ Event_queue::dump_internal_status() MYSQL_TIME time; my_tz_UTC->gmt_sec_to_TIME(&time, next_activation_at); - printf("Next activation : %04d-%02d-%02d %02d:%02d:%02d\n", - time.year, time.month, time.day, time.hour, time.minute, time.second); + if (time.year != 1970) + printf("Next activation : %04d-%02d-%02d %02d:%02d:%02d\n", + time.year, time.month, time.day, time.hour, time.minute, time.second); + else + printf("Next activation : never"); DBUG_VOID_RETURN; } diff --git a/sql/event_queue.h b/sql/event_queue.h index 04bb8b93b06..ac4a4f2bfd7 100644 --- a/sql/event_queue.h +++ b/sql/event_queue.h @@ -104,7 +104,6 @@ private: bool mutex_queue_data_locked; bool mutex_queue_data_attempting_lock; bool waiting_on_cond; - }; #endif /* _EVENT_QUEUE_H_ */ diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 5844fecc227..478ae0098da 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -42,7 +42,6 @@ Event_db_repository *Event_worker_thread::db_repository; static const LEX_STRING scheduler_states_names[] = { - { C_STRING_WITH_LEN("UNINITIALIZED") }, { C_STRING_WITH_LEN("INITIALIZED") }, { C_STRING_WITH_LEN("RUNNING") }, { C_STRING_WITH_LEN("STOPPING") } @@ -331,9 +330,15 @@ end: Event_scheduler::Event_scheduler(Event_queue *queue_arg) - :state(UNINITIALIZED), + :state(INITIALIZED), scheduler_thd(NULL), queue(queue_arg), + mutex_last_locked_at_line(0), + mutex_last_unlocked_at_line(0), + mutex_last_locked_in_func("n/a"), + mutex_last_unlocked_in_func("n/a"), + mutex_scheduler_data_locked(FALSE), + waiting_on_cond(FALSE), started_events(0) { pthread_mutex_init(&LOCK_scheduler_state, MY_MUTEX_INIT_FAST); diff --git a/sql/event_scheduler.h b/sql/event_scheduler.h index 70635196745..eba66c68d42 100644 --- a/sql/event_scheduler.h +++ b/sql/event_scheduler.h @@ -111,8 +111,7 @@ private: enum enum_state { - UNINITIALIZED = 0, - INITIALIZED, + INITIALIZED = 0, RUNNING, STOPPING }; From b626d5d78e512b349673cdaebe6eb099d99c925d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 May 2007 10:50:32 -0400 Subject: [PATCH 16/74] BUG#17654 : --read-from-remote-server causes core This patch corrects a problem encountered when reading the binlog from a remote host. The application was crashing because the buffer variable (temp_buf) in log_event was not pointing to the incoming data. For a normal file read, this buffer is allocated by a previous call of read_log_event. However, when reading from a remote host, the first call to read_log_event is not executed therefore no buffer is allocated. Furthermore, there is no need to allocate a new buffer because the incoming stream is what needs to be read. This patch adds the call to initialize the temp_buf variable if reading from a remote host. It also adds a check at destroy time to ensure the temp_buf is not freed if reading from a remote host. client/mysqlbinlog.cc: BUG#17654 : --read-from-remote-server causes core This patch corrects a problem when reading from a remote host. The temp_buf variable of the log_event class is undefined. This patch assigns the temp_buf variable to the address of the incoming stream. This allows the print functions to print the binlog events correctly. mysql-test/r/rpl_row_mysqlbinlog.result: BUG#17654 : --read-from-remote-server causes core This patch adds the results for the test that were disabled when the bug report was investigated. The patch also adds an additional test was added to ensure the output of reading from a remote host is the same as reading from a local file. mysql-test/t/rpl_row_mysqlbinlog.test: BUG#17654 : --read-from-remote-server causes core This patch enables the portions of the test that were disabled when the bug report was investigated. The patch also adds an additional test was added to ensure the output of reading from a remote host is the same as reading from a local file. --- client/mysqlbinlog.cc | 14 ++++ mysql-test/r/rpl_row_mysqlbinlog.result | 76 +++++++++++++++++ mysql-test/t/rpl_row_mysqlbinlog.test | 107 +++++++++++++++--------- 3 files changed, 157 insertions(+), 40 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 033c55707fc..d2357aa10ec 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -682,8 +682,16 @@ Begin_load_query event for file_id: %u\n", exlq->file_id); end: rec_count++; + /* + Destroy the log_event object. If reading from a remote host, + set the temp_buf to NULL so that memory isn't freed twice. + */ if (ev) + { + if (remote_opt) + ev->temp_buf= 0; delete ev; + } DBUG_RETURN(0); } @@ -1172,6 +1180,12 @@ could be out of memory"); error= 1; goto err; } + /* + If reading from a remote host, ensure the temp_buf for the + Log_event class is pointing to the incoming stream. + */ + if (remote_opt) + ev->register_temp_buf((char*) net->read_pos + 1); Log_event_type type= ev->get_type_code(); if (glob_description_event->binlog_version >= 3 || diff --git a/mysql-test/r/rpl_row_mysqlbinlog.result b/mysql-test/r/rpl_row_mysqlbinlog.result index c9f46e73cfd..e2df1459ac0 100644 --- a/mysql-test/r/rpl_row_mysqlbinlog.result +++ b/mysql-test/r/rpl_row_mysqlbinlog.result @@ -190,6 +190,75 @@ DELIMITER ; ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +--- Test 4 Second Remote test -- +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +stop slave; +reset master; +reset slave; +start slave; +SELECT COUNT(*) from t1; +COUNT(*) +352 +SELECT COUNT(*) from t2; +COUNT(*) +500 +SELECT COUNT(*) from t3; +COUNT(*) +500 +SELECT * FROM t1 ORDER BY word LIMIT 5; +word +Aarhus +Aarhus +Aarhus +Aarhus +Aarhus +SELECT * FROM t2 ORDER BY id LIMIT 5; +id +1 +2 +3 +4 +5 +SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5; +c1 c3 c4 c5 +1 2006-02-22 00:00:00 Tested in Texas 2.2 +2 2006-02-22 00:00:00 Tested in Texas 4.4 +3 2006-02-22 00:00:00 Tested in Texas 6.6 +4 2006-02-22 00:00:00 Tested in Texas 8.8 +5 2006-02-22 00:00:00 Tested in Texas 11 +SELECT COUNT(*) from t1; +COUNT(*) +352 +SELECT COUNT(*) from t2; +COUNT(*) +500 +SELECT COUNT(*) from t3; +COUNT(*) +500 +SELECT * FROM t1 ORDER BY word LIMIT 5; +word +Aarhus +Aarhus +Aarhus +Aarhus +Aarhus +SELECT * FROM t2 ORDER BY id LIMIT 5; +id +1 +2 +3 +4 +5 +SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5; +c1 c3 c4 c5 +1 2006-02-22 00:00:00 Tested in Texas 2.2 +2 2006-02-22 00:00:00 Tested in Texas 4.4 +3 2006-02-22 00:00:00 Tested in Texas 6.6 +4 2006-02-22 00:00:00 Tested in Texas 8.8 +5 2006-02-22 00:00:00 Tested in Texas 11 + --- Test 5 LOAD DATA -- /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; @@ -273,4 +342,11 @@ HEX(f) 835C --- Test cleanup -- +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT NOT NULL KEY, b INT); +INSERT INTO t1 VALUES(1,1); +SELECT * FROM t1; +a b +1 1 +FLUSH LOGS; DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5; diff --git a/mysql-test/t/rpl_row_mysqlbinlog.test b/mysql-test/t/rpl_row_mysqlbinlog.test index f7158107e4c..9b451ed7a8b 100644 --- a/mysql-test/t/rpl_row_mysqlbinlog.test +++ b/mysql-test/t/rpl_row_mysqlbinlog.test @@ -181,67 +181,67 @@ select "--- Test 3 First Remote test --" as ""; --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 # This part is disabled due to bug #17654 -################### Start Bug 17654 ###################### -#--disable_query_log -#select "--- Test 4 Second Remote test --" as ""; -#--enable_query_log -#--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 > $MYSQLTEST_VARDIR/tmp/remote.sql -#--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 >> $MYSQLTEST_VARDIR/tmp/remote.sql +--disable_query_log +select "--- Test 4 Second Remote test --" as ""; +--enable_query_log +--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 > $MYSQLTEST_VARDIR/tmp/remote.sql + +--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 >> $MYSQLTEST_VARDIR/tmp/remote.sql # Now that we have our file, lets get rid of the current database. # Cleanup the master and the slave and try to recreate. -#DROP TABLE t1; -#DROP TABLE t2; -#DROP TABLE t3; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; -#sync_slave_with_master; +sync_slave_with_master; #we expect STOP SLAVE to produce a warning as the slave is stopped #(the server was started with skip-slave-start) -#--disable_warnings -#stop slave; -#--enable_warnings -#--require r/slave-stopped.result -#show status like 'Slave_running'; -#connection master; -#reset master; -#connection slave; -#reset slave; -#start slave; -#--require r/slave-running.result -#show status like 'Slave_running'; -#connection master; +--disable_warnings +stop slave; +--enable_warnings +--require r/slave-stopped.result +show status like 'Slave_running'; +connection master; +reset master; +connection slave; +reset slave; +start slave; +--require r/slave-running.result +show status like 'Slave_running'; +connection master; # We should be clean at this point, now we will run in the file from above. -#--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/remote.sql" +--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/remote.sql" # Lets Check the tables on the Master -#SELECT COUNT(*) from t1; -#SELECT COUNT(*) from t2; -#SELECT COUNT(*) from t3; -#SELECT * FROM t1 ORDER BY word LIMIT 5; -#SELECT * FROM t2 ORDER BY id LIMIT 5; -#SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5; +SELECT COUNT(*) from t1; +SELECT COUNT(*) from t2; +SELECT COUNT(*) from t3; +SELECT * FROM t1 ORDER BY word LIMIT 5; +SELECT * FROM t2 ORDER BY id LIMIT 5; +SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5; # Should have the same on the slave; -#sync_slave_with_master; -#SELECT COUNT(*) from t1; -#SELECT COUNT(*) from t2; -#SELECT COUNT(*) from t3; -#SELECT * FROM t1 ORDER BY word LIMIT 5; -#SELECT * FROM t2 ORDER BY id LIMIT 5; -#SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5; -#connection master; +sync_slave_with_master; +SELECT COUNT(*) from t1; +SELECT COUNT(*) from t2; +SELECT COUNT(*) from t3; +SELECT * FROM t1 ORDER BY word LIMIT 5; +SELECT * FROM t2 ORDER BY id LIMIT 5; +SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5; +connection master; # We should be gold by the time, so I will get rid of our file. -#--exec rm $MYSQLTEST_VARDIR/tmp/remote.sql +--exec rm $MYSQLTEST_VARDIR/tmp/remote.sql ################### End Bug 17654 ###################### # LOAD DATA @@ -313,7 +313,34 @@ select "--- Test cleanup --" as ""; --enable_query_log # clean up connection master; -DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5; sync_slave_with_master; +connection master; + +# BUG#17654 also test mysqlbinlog to ensure it can read the binlog from a remote server +# and ensure that the results are the same as if read from a file (the same file). + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (a INT NOT NULL KEY, b INT); + +INSERT INTO t1 VALUES(1,1); + +SELECT * FROM t1; + +FLUSH LOGS; + +--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 > $MYSQLTEST_VARDIR/tmp/remote.sql +--exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/local.sql + +--diff_files $MYSQLTEST_VARDIR/tmp/local.sql $MYSQLTEST_VARDIR/tmp/remote.sql + +--exec rm $MYSQLTEST_VARDIR/tmp/remote.sql + +--exec rm $MYSQLTEST_VARDIR/tmp/local.sql + +DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5; + # End of 4.1 tests From 79a6e53ea036c8fb13434dc79e473b169c5ecf9a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 May 2007 18:18:39 +0200 Subject: [PATCH 17/74] Test case for bug#28075 tests/mysql_client_test.c: Add a test case for bug#28075 - just send COM_DEBUG and check whether the server is still alive. --- tests/mysql_client_test.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 0b3007dba06..306e9db8cae 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16073,6 +16073,28 @@ static void test_bug24179() } +/* + Bug#28075 "COM_DEBUG crashes mysqld" +*/ + +static void test_bug28075() +{ + int rc; + MYSQL_STMT *stmt; + + DBUG_ENTER("test_bug28075"); + myheader("test_bug28075"); + + rc= mysql_dump_debug_info(mysql); + DIE_UNLESS(rc == 0); + + rc= mysql_ping(mysql); + DIE_UNLESS(rc == 0); + + DBUG_VOID_RETURN; +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -16357,6 +16379,7 @@ static struct my_tests_st my_tests[]= { { "test_status", test_status }, { "test_bug24179", test_bug24179 }, { "test_ps_query_cache", test_ps_query_cache }, + { "test_bug28075", test_bug28075 }, { 0, 0 } }; From bb64e39e0aa6d209a47dea7ed48753752ec003f2 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 May 2007 13:41:40 -0600 Subject: [PATCH 18/74] Bug#21554 (sp_cache.cc: violates C++ aliasing rules) The problem reported is a compile bug, reported by the development GCC team with GCC 4.2. The original issue can no longer be reproduced in MySQL 5.1, since the configure script no longer define HAVE_ATOMIC_ADD, which caused the Linux atomic functions to be used (and cause a problem with an invalid cast). This patch implements some code cleanup for 5.1 only, which was identified during the investigation of this issue. With this patch, statistics maintained in THD::status_var are by definition owned by the running thread, and do not need to be protected against race conditions. These statistics are maintained by the status_var_* helpers, which do not require any lock. include/my_global.h: General cleanup of thread_safe_increment / statistic_increment include/my_pthread.h: General cleanup of thread_safe_increment / statistic_increment sql/filesort.cc: General cleanup of thread_safe_increment / statistic_increment sql/handler.cc: General cleanup of thread_safe_increment / statistic_increment sql/sql_insert.cc: General cleanup of thread_safe_increment / statistic_increment sql/sql_parse.cc: General cleanup of thread_safe_increment / statistic_increment sql/sql_prepare.cc: General cleanup of thread_safe_increment / statistic_increment sql/sql_select.cc: General cleanup of thread_safe_increment / statistic_increment --- include/my_global.h | 15 ++++-------- include/my_pthread.h | 55 +++++++++++++++++++++++++++++++++----------- sql/filesort.cc | 7 +++--- sql/handler.cc | 19 ++++++++------- sql/sql_insert.cc | 2 +- sql/sql_parse.cc | 41 +++++++++++++-------------------- sql/sql_prepare.cc | 12 +++++----- sql/sql_select.cc | 20 ++++++---------- 8 files changed, 87 insertions(+), 84 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index b78c7120565..178c6a77026 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -441,17 +441,7 @@ C_MODE_END #ifdef HAVE_ALLOCA_H #include #endif -#ifdef HAVE_ATOMIC_ADD -#define new my_arg_new -#define need_to_restore_new 1 -C_MODE_START -#include -C_MODE_END -#ifdef need_to_restore_new /* probably safer than #ifdef new */ -#undef new -#undef need_to_restore_new -#endif -#endif + #include /* Recommended by debian */ /* We need the following to go around a problem with openssl on solaris */ #if defined(HAVE_CRYPT_H) @@ -1449,10 +1439,13 @@ do { doubleget_union _tmp; \ #ifndef THREAD #define thread_safe_increment(V,L) (V)++ +#define thread_safe_decrement(V,L) (V)-- #define thread_safe_add(V,C,L) (V)+=(C) #define thread_safe_sub(V,C,L) (V)-=(C) #define statistic_increment(V,L) (V)++ +#define statistic_decrement(V,L) (V)-- #define statistic_add(V,C,L) (V)+=(C) +#define statistic_sub(V,C,L) (V)-=(C) #endif #ifdef HAVE_CHARSET_utf8 diff --git a/include/my_pthread.h b/include/my_pthread.h index 340dc32981a..ef52bbcb16c 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -710,33 +710,60 @@ extern uint my_thread_end_wait_time; extern uint thd_lib_detected; - /* statistics_xxx functions are for not essential statistic */ +/* + thread_safe_xxx functions are for critical statistic or counters. + The implementation is guaranteed to be thread safe, on all platforms. + Note that the calling code should *not* assume the counter is protected + by the mutex given, as the implementation of these helpers may change + to use my_atomic operations instead. +*/ -#ifndef thread_safe_increment -#ifdef HAVE_ATOMIC_ADD -#define thread_safe_increment(V,L) atomic_inc((atomic_t*) &V) -#define thread_safe_decrement(V,L) atomic_dec((atomic_t*) &V) -#define thread_safe_add(V,C,L) atomic_add((C),(atomic_t*) &V) -#define thread_safe_sub(V,C,L) atomic_sub((C),(atomic_t*) &V) -#else +/* + Warning: + When compiling without threads, this file is not included. + See the *other* declarations of thread_safe_xxx in include/my_global.h +*/ +#ifdef THREAD #define thread_safe_increment(V,L) \ (pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L))) #define thread_safe_decrement(V,L) \ (pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L))) -#define thread_safe_add(V,C,L) (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L))) +#define thread_safe_add(V,C,L) \ + (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L))) #define thread_safe_sub(V,C,L) \ (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L))) -#endif /* HAVE_ATOMIC_ADD */ +#endif + +/* + statistics_xxx functions are for non critical statistic, + maintained in global variables. + When compiling with SAFE_STATISTICS: + - race conditions can not occur. + - some locking occurs, which may cause performance degradation. + + When compiling without SAFE_STATISTICS: + - race conditions can occur, making the result slightly inaccurate. + - the lock given is not honored. +*/ #ifdef SAFE_STATISTICS -#define statistic_increment(V,L) thread_safe_increment((V),(L)) -#define statistic_decrement(V,L) thread_safe_decrement((V),(L)) -#define statistic_add(V,C,L) thread_safe_add((V),(C),(L)) +#define statistic_increment(V,L) thread_safe_increment((V),(L)) +#define statistic_decrement(V,L) thread_safe_decrement((V),(L)) +#define statistic_add(V,C,L) thread_safe_add((V),(C),(L)) +#define statistic_sub(V,C,L) thread_safe_sub((V),(C),(L)) #else #define statistic_decrement(V,L) (V)-- #define statistic_increment(V,L) (V)++ #define statistic_add(V,C,L) (V)+=(C) +#define statistic_sub(V,C,L) (V)-=(C) #endif /* SAFE_STATISTICS */ -#endif /* thread_safe_increment */ + +/* + No locking needed, the counter is owned by the thread +*/ +#define status_var_increment(V) (V)++ +#define status_var_decrement(V) (V)-- +#define status_var_add(V,C) (V)+=(C) +#define status_var_sub(V,C) (V)-=(C) #ifdef __cplusplus } diff --git a/sql/filesort.cc b/sql/filesort.cc index a80e4a0fa54..fff57bfc229 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -171,11 +171,11 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, if (select && select->quick) { - statistic_increment(thd->status_var.filesort_range_count, &LOCK_status); + status_var_increment(thd->status_var.filesort_range_count); } else { - statistic_increment(thd->status_var.filesort_scan_count, &LOCK_status); + status_var_increment(thd->status_var.filesort_scan_count); } #ifdef CAN_TRUST_RANGE if (select && select->quick && select->quick->records > 0L) @@ -1120,8 +1120,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, THD::killed_state not_killable; DBUG_ENTER("merge_buffers"); - statistic_increment(current_thd->status_var.filesort_merge_passes, - &LOCK_status); + status_var_increment(current_thd->status_var.filesort_merge_passes); if (param->not_killable) { killed= ¬_killable; diff --git a/sql/handler.cc b/sql/handler.cc index 48600c68daf..83785ec579b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -639,7 +639,7 @@ int ha_prepare(THD *thd) for (; *ht; ht++) { int err; - statistic_increment(thd->status_var.ha_prepare_count,&LOCK_status); + status_var_increment(thd->status_var.ha_prepare_count); if ((*ht)->prepare) { if ((err= (*(*ht)->prepare)(*ht, thd, all))) @@ -734,7 +734,7 @@ int ha_commit_trans(THD *thd, bool all) my_error(ER_ERROR_DURING_COMMIT, MYF(0), err); error= 1; } - statistic_increment(thd->status_var.ha_prepare_count,&LOCK_status); + status_var_increment(thd->status_var.ha_prepare_count); } DBUG_EXECUTE_IF("crash_commit_after_prepare", abort();); if (error || (is_real_trans && xid && @@ -781,7 +781,7 @@ int ha_commit_one_phase(THD *thd, bool all) my_error(ER_ERROR_DURING_COMMIT, MYF(0), err); error=1; } - statistic_increment(thd->status_var.ha_commit_count,&LOCK_status); + status_var_increment(thd->status_var.ha_commit_count); *ht= 0; } trans->nht=0; @@ -837,7 +837,7 @@ int ha_rollback_trans(THD *thd, bool all) my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err); error=1; } - statistic_increment(thd->status_var.ha_rollback_count,&LOCK_status); + status_var_increment(thd->status_var.ha_rollback_count); *ht= 0; } trans->nht=0; @@ -1252,8 +1252,7 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv) my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err); error=1; } - statistic_increment(thd->status_var.ha_savepoint_rollback_count, - &LOCK_status); + status_var_increment(thd->status_var.ha_savepoint_rollback_count); trans->no_2pc|=(*ht)->prepare == 0; } /* @@ -1268,7 +1267,7 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv) my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err); error=1; } - statistic_increment(thd->status_var.ha_rollback_count,&LOCK_status); + status_var_increment(thd->status_var.ha_rollback_count); *ht=0; // keep it conveniently zero-filled } DBUG_RETURN(error); @@ -1301,7 +1300,7 @@ int ha_savepoint(THD *thd, SAVEPOINT *sv) my_error(ER_GET_ERRNO, MYF(0), err); error=1; } - statistic_increment(thd->status_var.ha_savepoint_count,&LOCK_status); + status_var_increment(thd->status_var.ha_savepoint_count); } sv->nht=trans->nht; #endif /* USING_TRANSACTIONS */ @@ -1489,7 +1488,7 @@ handler *handler::clone(MEM_ROOT *mem_root) void handler::ha_statistic_increment(ulong SSV::*offset) const { - statistic_increment(table->in_use->status_var.*offset, &LOCK_status); + status_var_increment(table->in_use->status_var.*offset); } void **handler::ha_data(THD *thd) const @@ -2836,7 +2835,7 @@ int ha_discover(THD *thd, const char *db, const char *name, error= 0; if (!error) - statistic_increment(thd->status_var.ha_discover_count,&LOCK_status); + status_var_increment(thd->status_var.ha_discover_count); DBUG_RETURN(error); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a4da752feb6..0268e1d3a41 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2538,7 +2538,7 @@ bool Delayed_insert::handle_inserts(void) if (table->s->blob_fields) free_delayed_insert_blobs(table); - thread_safe_sub(delayed_rows_in_use,1,&LOCK_delayed_status); + thread_safe_decrement(delayed_rows_in_use,&LOCK_delayed_status); thread_safe_increment(delayed_insert_writes,&LOCK_delayed_status); pthread_mutex_lock(&mutex); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 06419010a24..3fbb38bf18c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -721,8 +721,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_INIT_DB: { LEX_STRING tmp; - statistic_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB], - &LOCK_status); + status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]); thd->convert_string(&tmp, system_charset_info, packet, packet_length-1, thd->charset()); if (!mysql_change_db(thd, &tmp, FALSE)) @@ -757,7 +756,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } - statistic_increment(thd->status_var.com_other, &LOCK_status); + status_var_increment(thd->status_var.com_other); thd->enable_slow_log= opt_log_slow_admin_statements; db.str= thd->alloc(db_len + tbl_len + 2); db.length= db_len; @@ -773,7 +772,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_CHANGE_USER: { - statistic_increment(thd->status_var.com_other, &LOCK_status); + status_var_increment(thd->status_var.com_other); char *user= (char*) packet, *packet_end= packet+ packet_length; char *passwd= strend(user)+1; @@ -956,8 +955,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* used as fields initializator */ lex_start(thd); - statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS], - &LOCK_status); + status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]); bzero((char*) &table_list,sizeof(table_list)); if (thd->copy_db_to(&table_list.db, &dummy)) break; @@ -1023,8 +1021,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, LEX_STRING db, alias; HA_CREATE_INFO create_info; - statistic_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB], - &LOCK_status); + status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]); if (thd->LEX_STRING_make(&db, packet, packet_length -1) || thd->LEX_STRING_make(&alias, db.str, db.length) || check_db_name(&db)) @@ -1043,8 +1040,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_DROP_DB: // QQ: To be removed { - statistic_increment(thd->status_var.com_stat[SQLCOM_DROP_DB], - &LOCK_status); + status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]); LEX_STRING db; if (thd->LEX_STRING_make(&db, packet, packet_length - 1) || @@ -1073,7 +1069,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ushort flags; uint32 slave_server_id; - statistic_increment(thd->status_var.com_other,&LOCK_status); + status_var_increment(thd->status_var.com_other); thd->enable_slow_log= opt_log_slow_admin_statements; if (check_global_access(thd, REPL_SLAVE_ACL)) break; @@ -1099,8 +1095,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_REFRESH: { bool not_used; - statistic_increment(thd->status_var.com_stat[SQLCOM_FLUSH], - &LOCK_status); + status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]); ulong options= (ulong) (uchar) packet[0]; if (check_global_access(thd,RELOAD_ACL)) break; @@ -1112,7 +1107,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #ifndef EMBEDDED_LIBRARY case COM_SHUTDOWN: { - statistic_increment(thd->status_var.com_other, &LOCK_status); + status_var_increment(thd->status_var.com_other); if (check_global_access(thd,SHUTDOWN_ACL)) break; /* purecov: inspected */ /* @@ -1164,8 +1159,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #endif general_log_print(thd, command, NullS); - statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS], - &LOCK_status); + status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]); calc_sum_of_all_status(¤t_global_status_var); if (!(uptime= (ulong) (thd->start_time - server_start_time))) queries_per_second1000= 0; @@ -1201,12 +1195,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } case COM_PING: - statistic_increment(thd->status_var.com_other, &LOCK_status); + status_var_increment(thd->status_var.com_other); send_ok(thd); // Tell client we are alive break; case COM_PROCESS_INFO: - statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST], - &LOCK_status); + status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]); if (!thd->security_ctx->priv_user[0] && check_global_access(thd, PROCESS_ACL)) break; @@ -1217,15 +1210,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; case COM_PROCESS_KILL: { - statistic_increment(thd->status_var.com_stat[SQLCOM_KILL], &LOCK_status); + status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]); ulong id=(ulong) uint4korr(packet); sql_kill(thd,id,false); break; } case COM_SET_OPTION: { - statistic_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION], - &LOCK_status); + status_var_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION]); uint opt_command= uint2korr(packet); switch (opt_command) { @@ -1244,7 +1236,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } case COM_DEBUG: - statistic_increment(thd->status_var.com_other, &LOCK_status); + status_var_increment(thd->status_var.com_other); if (check_global_access(thd, SUPER_ACL)) break; /* purecov: inspected */ mysql_print_status(); @@ -1783,8 +1775,7 @@ mysql_execute_command(THD *thd) #ifdef HAVE_REPLICATION } /* endif unlikely slave */ #endif - statistic_increment(thd->status_var.com_stat[lex->sql_command], - &LOCK_status); + status_var_increment(thd->status_var.com_stat[lex->sql_command]); switch (lex->sql_command) { case SQLCOM_SHOW_EVENTS: diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 21d0308a830..cb01d14258b 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2430,7 +2430,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) /* First of all clear possible warnings from the previous command */ mysql_reset_thd_for_next_command(thd); - statistic_increment(thd->status_var.com_stmt_fetch, &LOCK_status); + status_var_increment(thd->status_var.com_stmt_fetch); if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_fetch"))) DBUG_VOID_RETURN; @@ -2494,7 +2494,7 @@ void mysql_stmt_reset(THD *thd, char *packet) /* First of all clear possible warnings from the previous command */ mysql_reset_thd_for_next_command(thd); - statistic_increment(thd->status_var.com_stmt_reset, &LOCK_status); + status_var_increment(thd->status_var.com_stmt_reset); if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset"))) DBUG_VOID_RETURN; @@ -2598,7 +2598,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) #endif DBUG_ENTER("mysql_stmt_get_longdata"); - statistic_increment(thd->status_var.com_stmt_send_long_data, &LOCK_status); + status_var_increment(thd->status_var.com_stmt_send_long_data); #ifndef EMBEDDED_LIBRARY /* Minimal size of long data packet is 6 bytes */ if (packet_length <= MYSQL_LONG_DATA_HEADER) @@ -2849,7 +2849,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) However, it seems handy if com_stmt_prepare is increased always, no matter what kind of prepare is processed. */ - statistic_increment(thd->status_var.com_stmt_prepare, &LOCK_status); + status_var_increment(thd->status_var.com_stmt_prepare); /* alloc_query() uses thd->memroot && thd->query, so we should call @@ -2972,7 +2972,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) Query_arena *old_stmt_arena; bool error= TRUE; - statistic_increment(thd->status_var.com_stmt_execute, &LOCK_status); + status_var_increment(thd->status_var.com_stmt_execute); /* Check if we got an error when sending long data */ if (state == Query_arena::ERROR) @@ -3094,7 +3094,7 @@ error: bool Prepared_statement::deallocate() { /* We account deallocate in the same manner as mysql_stmt_close */ - statistic_increment(thd->status_var.com_stmt_close, &LOCK_status); + status_var_increment(thd->status_var.com_stmt_close); if (flags & (uint) IS_IN_USE) { my_error(ER_PS_NO_RECURSION, MYF(0)); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ea78e126d9c..588827f66ec 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6282,8 +6282,7 @@ make_join_readinfo(JOIN *join, ulonglong options) join->thd->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED; tab->read_first_record= join_init_quick_read_record; if (statistics) - statistic_increment(join->thd->status_var.select_range_check_count, - &LOCK_status); + status_var_increment(join->thd->status_var.select_range_check_count); } else { @@ -6293,15 +6292,13 @@ make_join_readinfo(JOIN *join, ulonglong options) if (tab->select && tab->select->quick) { if (statistics) - statistic_increment(join->thd->status_var.select_range_count, - &LOCK_status); + status_var_increment(join->thd->status_var.select_range_count); } else { join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED; if (statistics) - statistic_increment(join->thd->status_var.select_scan_count, - &LOCK_status); + status_var_increment(join->thd->status_var.select_scan_count); } } else @@ -6309,15 +6306,13 @@ make_join_readinfo(JOIN *join, ulonglong options) if (tab->select && tab->select->quick) { if (statistics) - statistic_increment(join->thd->status_var.select_full_range_join_count, - &LOCK_status); + status_var_increment(join->thd->status_var.select_full_range_join_count); } else { join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED; if (statistics) - statistic_increment(join->thd->status_var.select_full_join_count, - &LOCK_status); + status_var_increment(join->thd->status_var.select_full_join_count); } } if (!table->no_keyread) @@ -9377,7 +9372,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, (int) distinct, (int) save_sum_fields, (ulong) rows_limit,test(group))); - statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status); + status_var_increment(thd->status_var.created_tmp_tables); if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES)) temp_pool_slot = bitmap_lock_set_next(&temp_pool); @@ -10249,8 +10244,7 @@ static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param, table->db_stat=0; goto err; } - statistic_increment(table->in_use->status_var.created_tmp_disk_tables, - &LOCK_status); + status_var_increment(table->in_use->status_var.created_tmp_disk_tables); share->db_record_offset= 1; DBUG_RETURN(0); err: From e5fe02615e71ac59d2f9577e199a0c95d5021408 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 May 2007 16:19:36 -0600 Subject: [PATCH 19/74] build break cleanup include/config-win.h: cleanup, windows build break include/my_pthread.h: cleanup, windows build break sql/event_queue.cc: warnings cleanup, unititialized waiting_on_cond tests/mysql_client_test.c: warnings cleanup --- include/config-win.h | 9 --------- include/my_pthread.h | 8 ++++++++ sql/event_queue.cc | 8 +++----- tests/mysql_client_test.c | 1 - 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/include/config-win.h b/include/config-win.h index 8d6f8885626..db5f516a59b 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -411,16 +411,7 @@ inline double ulonglong2double(ulonglong value) #ifdef __NT__ /* This should also work on Win98 but .. */ #define thread_safe_add(V,C,L) InterlockedExchangeAdd((long*) &(V),(C)) #define thread_safe_sub(V,C,L) InterlockedExchangeAdd((long*) &(V),-(long) (C)) -#define statistic_add(V,C,L) thread_safe_add((V),(C),(L)) -#else -#define thread_safe_add(V,C,L) \ - pthread_mutex_lock((L)); (V)+=(C); pthread_mutex_unlock((L)); -#define thread_safe_sub(V,C,L) \ - pthread_mutex_lock((L)); (V)-=(C); pthread_mutex_unlock((L)); -#define statistic_add(V,C,L) (V)+=(C) #endif -#define statistic_increment(V,L) thread_safe_increment((V),(L)) -#define statistic_decrement(V,L) thread_safe_decrement((V),(L)) #define shared_memory_buffer_length 16000 #define default_shared_memory_base_name "MYSQL" diff --git a/include/my_pthread.h b/include/my_pthread.h index ef52bbcb16c..e282d16fa12 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -722,17 +722,25 @@ extern uint thd_lib_detected; Warning: When compiling without threads, this file is not included. See the *other* declarations of thread_safe_xxx in include/my_global.h + + Second warning: + See include/config-win.h, for yet another implementation. */ #ifdef THREAD +#ifndef thread_safe_increment #define thread_safe_increment(V,L) \ (pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L))) #define thread_safe_decrement(V,L) \ (pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L))) +#endif + +#ifndef thread_safe_add #define thread_safe_add(V,C,L) \ (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L))) #define thread_safe_sub(V,C,L) \ (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L))) #endif +#endif /* statistics_xxx functions are for non critical statistic, diff --git a/sql/event_queue.cc b/sql/event_queue.cc index 40cb9040eef..6cf5da383ea 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -73,16 +73,14 @@ Event_queue::Event_queue() :next_activation_at(0), mutex_last_locked_at_line(0), mutex_last_unlocked_at_line(0), + mutex_last_attempted_lock_at_line(0), mutex_last_locked_in_func("n/a"), mutex_last_unlocked_in_func("n/a"), mutex_last_attempted_lock_in_func("n/a"), - mutex_last_attempted_lock_at_line(0), mutex_queue_data_locked(FALSE), - mutex_queue_data_attempting_lock(FALSE) + mutex_queue_data_attempting_lock(FALSE), + waiting_on_cond(FALSE) { - mutex_last_unlocked_in_func= mutex_last_locked_in_func= - mutex_last_attempted_lock_in_func= ""; - pthread_mutex_init(&LOCK_event_queue, MY_MUTEX_INIT_FAST); pthread_cond_init(&COND_queue_state, NULL); } diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 306e9db8cae..53224cccc2d 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16080,7 +16080,6 @@ static void test_bug24179() static void test_bug28075() { int rc; - MYSQL_STMT *stmt; DBUG_ENTER("test_bug28075"); myheader("test_bug28075"); From 1da8ea2ee06f67b3e498520fe22900c748b31dcf Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 May 2007 12:34:47 +0500 Subject: [PATCH 20/74] Bug#28558 UpdateXML called with garbage crashes server Problem: Memory overrun happened in attempts to generate error messages (e.g. in case of incorrect XPath syntax). Reason: set_if_bigger() was used instead of set_if_smaller(). Change: replacing wrong set_if_bigger() to set_if_smaller(), and making minor additional code clean-ups. mysql-test/r/xml.result: Adding test cases for all pieces of code with set_if_smaller() followed by my_printf_error(). mysql-test/t/xml.test: Adding test cases for all pieces of code with set_if_smaller() followed by my_printf_error(). sql/item_xmlfunc.cc: - fixing incorrect set_if_bigger to set_if_smaller in two places - getting read of unnesessary "char context[32]" variable and using '%.*s' instead if '%s' in the error format. --- mysql-test/r/xml.result | 6 ++++++ mysql-test/t/xml.test | 10 ++++++++++ sql/item_xmlfunc.cc | 12 +++++------- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/xml.result b/mysql-test/r/xml.result index 77764e1bc1a..f71b8cadabb 100644 --- a/mysql-test/r/xml.result +++ b/mysql-test/r/xml.result @@ -1006,3 +1006,9 @@ Warnings: Warning 1292 Truncated incorrect INTEGER value: 'string ' Warning 1292 Truncated incorrect INTEGER value: 'string ' DROP PROCEDURE spxml; +select UpdateXML('a',repeat('a b ',1000),''); +ERROR HY000: XPATH syntax error: 'b a b a b a b a b a b a b a b a ' +select ExtractValue('a', '/a[@x=@y0123456789_0123456789_0123456789_0123456789]'); +ERROR HY000: XPATH error: comparison of two nodesets is not supported: '=@y0123456789_0123456789_0123456' +select ExtractValue('a', '/a[@x=$y0123456789_0123456789_0123456789_0123456789]'); +ERROR HY000: Unknown XPATH variable at: '$y0123456789_0123456789_01234567' diff --git a/mysql-test/t/xml.test b/mysql-test/t/xml.test index 28abd3475d2..1d16652ab1e 100644 --- a/mysql-test/t/xml.test +++ b/mysql-test/t/xml.test @@ -523,3 +523,13 @@ CALL spxml('b1b2', '1 and string'); CALL spxml('b1b2', 'string and 1'); CALL spxml('b1b2', 'string'); DROP PROCEDURE spxml; + +# +# Bug#28558 UpdateXML called with garbage crashes server +# +--error 1105 +select UpdateXML('a',repeat('a b ',1000),''); +--error 1105 +select ExtractValue('a', '/a[@x=@y0123456789_0123456789_0123456789_0123456789]'); +--error 1105 +select ExtractValue('a', '/a[@x=$y0123456789_0123456789_0123456789_0123456789]'); diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 147c2bc8212..428bffa6879 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -923,8 +923,8 @@ static Item *create_comparator(MY_XPATH *xpath, else if (a->type() == Item::XPATH_NODESET && b->type() == Item::XPATH_NODESET) { - uint len= context->end - context->beg; - set_if_bigger(len, 32); + uint len= xpath->query.end - context->beg; + set_if_smaller(len, 32); my_printf_error(ER_UNKNOWN_ERROR, "XPATH error: " "comparison of two nodesets is not supported: '%.*s'", @@ -2591,12 +2591,10 @@ void Item_xml_str_func::fix_length_and_dec() if (!rc) { - char context[32]; uint clen= xpath.query.end - xpath.lasttok.beg; - set_if_bigger(clen, sizeof(context) - 1); - strmake(context, xpath.lasttok.beg, clen); - my_printf_error(ER_UNKNOWN_ERROR, "XPATH syntax error: '%s'", - MYF(0), context); + set_if_smaller(clen, 32); + my_printf_error(ER_UNKNOWN_ERROR, "XPATH syntax error: '%.*s'", + MYF(0), clen, xpath.lasttok.beg); return; } From 548070849a4ca440b5d0619496db22cd69ae2d04 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 May 2007 12:54:15 +0200 Subject: [PATCH 21/74] - This patch addesses the performance issues with invalidating the entire cache by changing the behavior of the query cache resize-method. - set query_cache_size=; is significantly faster than RESET QUERY CACHE as it simply destroys and recreates the query cache, whereas RESET QUERY CACHE keeps its internal structure aligned with server load profile. sql/set_var.cc: Refactored behavior of function. Instead of setting the global variable from within the class method scope we return the new cache size as a result of the method call. sql/sql_cache.cc: - Changed behavior of resize-method. Now, the cache will be cleared as one single block of data instead of an iteration over all cached statements. --- sql/set_var.cc | 15 ++++++--- sql/sql_cache.cc | 79 ++++++++++++++++++++---------------------------- 2 files changed, 43 insertions(+), 51 deletions(-) diff --git a/sql/set_var.cc b/sql/set_var.cc index ea2888aec56..e7588632595 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1275,12 +1275,19 @@ static void fix_net_retry_count(THD *thd __attribute__((unused)), static void fix_query_cache_size(THD *thd, enum_var_type type) { #ifdef HAVE_QUERY_CACHE - ulong requested= query_cache_size; - query_cache.resize(query_cache_size); - if (requested != query_cache_size) + ulong new_cache_size= query_cache.resize(query_cache_size); + + /* + Note: query_cache_size is a global variable reflecting the + requested cache size. See also query_cache_size_arg + */ + + if (query_cache_size != new_cache_size) push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_QC_RESIZE, ER(ER_WARN_QC_RESIZE), - requested, query_cache_size); + query_cache_size, new_cache_size); + + query_cache_size= new_cache_size; #endif } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 89b7a25033f..d7689c195f9 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -632,7 +632,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length) DUMP(&query_cache); BLOCK_LOCK_WR(query_block); - DBUG_PRINT("qcache", ("insert packet %lu bytes long",length)); + DBUG_PRINT("qcache", ("insert parequestedcket %lu bytes long",length)); /* On success STRUCT_UNLOCK(&query_cache.structure_guard_mutex) will be @@ -799,12 +799,26 @@ ulong Query_cache::resize(ulong query_cache_size_arg) DBUG_PRINT("qcache", ("from %lu to %lu",query_cache_size, query_cache_size_arg)); DBUG_ASSERT(initialized); + STRUCT_LOCK(&structure_guard_mutex); - free_cache(); - query_cache_size= query_cache_size_arg; - ::query_cache_size= init_cache(); + while (flush_in_progress) + pthread_cond_wait(&COND_flush_finished, &structure_guard_mutex); + flush_in_progress= TRUE; STRUCT_UNLOCK(&structure_guard_mutex); - DBUG_RETURN(::query_cache_size); + + free_cache(); + + query_cache_size= query_cache_size_arg; + ulong new_query_cache_size= init_cache(); + + DBUG_EXECUTE("check_querycache",check_integrity(0);); + + STRUCT_LOCK(&structure_guard_mutex); + flush_in_progress= FALSE; + pthread_cond_signal(&COND_flush_finished); + STRUCT_UNLOCK(&structure_guard_mutex); + + DBUG_RETURN(new_query_cache_size); } @@ -1575,6 +1589,7 @@ ulong Query_cache::init_cache() int align; DBUG_ENTER("Query_cache::init_cache"); + approx_additional_data_size = (sizeof(Query_cache) + sizeof(gptr)*(def_query_hash_size+ def_table_hash_size)); @@ -1753,58 +1768,28 @@ void Query_cache::make_disabled() mem_bin_num= mem_bin_steps= 0; queries_in_cache= 0; first_block= 0; + total_blocks= 0; + tables_blocks= 0; DBUG_VOID_RETURN; } -/* - free_cache() - free all resources allocated by the cache. - - SYNOPSIS - free_cache() - - DESCRIPTION - This function frees all resources allocated by the cache. You - have to call init_cache() before using the cache again. +/** + @class Query_cache + @brief Free all resources allocated by the cache. + @details This function frees all resources allocated by the cache. You + have to call init_cache() before using the cache again. This function requires + the structure_guard_mutex to be locked. */ void Query_cache::free_cache() { DBUG_ENTER("Query_cache::free_cache"); - if (query_cache_size > 0) - flush_cache(); - /* - There may be two free_cache() calls in progress, because we - release 'structure_guard_mutex' in flush_cache(). When the second - flush_cache() wakes up from the wait on 'COND_flush_finished', the - first call to free_cache() has done its job. So we have to test - 'query_cache_size > 0' the second time to see if the cache wasn't - reset by other thread, or if it was reset and was re-enabled then. - If the cache was reset, then we have nothing to do here. - */ - if (query_cache_size > 0) - { -#ifndef DBUG_OFF - if (bins[0].free_blocks == 0) - { - wreck(__LINE__,"no free memory found in (bins[0].free_blocks"); - DBUG_VOID_RETURN; - } -#endif - /* Becasue we did a flush, all cache memory must be in one this block */ - bins[0].free_blocks->destroy(); - total_blocks--; -#ifndef DBUG_OFF - if (free_memory != query_cache_size) - DBUG_PRINT("qcache", ("free memory %lu (should be %lu)", - free_memory , query_cache_size)); -#endif - my_free((gptr) cache, MYF(MY_ALLOW_ZERO_PTR)); - make_disabled(); - hash_free(&queries); - hash_free(&tables); - } + my_free((gptr) cache, MYF(MY_ALLOW_ZERO_PTR)); + make_disabled(); + hash_free(&queries); + hash_free(&tables); DBUG_VOID_RETURN; } From 7f35d66d79f3376e07b84f8aa5b76ac7d83f66f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 May 2007 13:04:49 +0200 Subject: [PATCH 22/74] - Corrected type misstake in debug statement. --- sql/sql_cache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 926faa3f474..1ae0e861313 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -632,7 +632,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length) DUMP(&query_cache); BLOCK_LOCK_WR(query_block); - DBUG_PRINT("qcache", ("insert parequestedcket %lu bytes long",length)); + DBUG_PRINT("qcache", ("insert packet %lu bytes long",length)); /* On success STRUCT_UNLOCK(&query_cache.structure_guard_mutex) will be From f9d7642e7b46d911cda5512ac0bcb55dd85dcd95 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 May 2007 15:22:13 +0400 Subject: [PATCH 23/74] 5.0 version of fix for: Bug #23667 "CREATE TABLE LIKE is not isolated from alteration by other connections" Bug #18950 "CREATE TABLE LIKE does not obtain LOCK_open" As well as: Bug #25578 "CREATE TABLE LIKE does not require any privileges on source table". The first and the second bugs resulted in various errors and wrong binary log order when one tried to execute concurrently CREATE TABLE LIKE statement and DDL statements on source table or DML/DDL statements on its target table. The problem was caused by incomplete protection/table-locking against concurrent statements implemented in mysql_create_like_table() routine. We solve it by simply implementing such protection in proper way (see comment for sql_table.cc for details). The third bug allowed user who didn't have any privileges on table create its copy and therefore circumvent privilege check for SHOW CREATE TABLE. This patch solves this problem by adding privilege check, which was missing. Finally it also removes some duplicated code from mysql_create_like_table(). Note that, altough tests covering concurrency-related aspects of CREATE TABLE LIKE behaviour will only be introduced in 5.1, they were run manually for this patch as well. mysql-test/r/grant2.result: Added test for bug#25578 "CREATE TABLE LIKE does not require any privileges on source table". mysql-test/t/grant2.test: Added test for bug#25578 "CREATE TABLE LIKE does not require any privileges on source table". sql/handler.h: Introduced new flag for HA_CREATE_INFO::options in order to be able to distinguish CREATE TABLE ... LIKE from other types of CREATE TABLE. sql/mysql_priv.h: mysql_create_like_table() now takes source table name not as a Table_ident object but as regular table list element. sql/sql_parse.cc: CREATE TABLE ... LIKE implementation now uses statement's table list for storing information about the source table. We also use flag in LEX::create_info.options for distinguishing it from other types of CREATE TABLE. Finally CREATE TABLE ... LIKE now requires the same privileges on the source tables as SHOW CREATE TABLE. Moved this privilege check to check_show_create_table_access() function. sql/sql_table.cc: mysql_create_like_table(): - Provided proper protection from concurrent statements. This is achieved by keeping name-lock on the source table and holding LOCK_open mutex during whole operation. This gives protection against concurrent DDL on source table. Also holding this mutex makes copying of .frm file, call to ha_create_table() and binlogging atomic against concurrent DML and DDL operations on target table. - Get rid of duplicated code related to source database/table name handling. All these operations are already done in st_select_lex::add_table_to_list(), so we achieve the same effect by including source table into the statement's table list. sql/sql_yacc.yy: Now we use special flag in LEX::create_info::options for distinguishing CREATE TABLE ... LIKE from other types of CREATE TABLE and store name of source table as regular element in statement's table list. --- mysql-test/r/grant2.result | 24 ++++++++++ mysql-test/t/grant2.test | 44 ++++++++++++++++++ sql/handler.h | 1 + sql/mysql_priv.h | 5 +-- sql/sql_parse.cc | 37 ++++++++++++---- sql/sql_table.cc | 91 ++++++++++++++++++-------------------- sql/sql_yacc.yy | 21 ++------- 7 files changed, 146 insertions(+), 77 deletions(-) diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index ff9b7bc6f1f..93098e68070 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -380,3 +380,27 @@ drop function f2; drop table t2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost; drop user `a@`@localhost; +drop database if exists mysqltest_1; +drop database if exists mysqltest_2; +drop user mysqltest_u1@localhost; +create database mysqltest_1; +create database mysqltest_2; +grant all on mysqltest_1.* to mysqltest_u1@localhost; +use mysqltest_2; +create table t1 (i int); +show create table mysqltest_2.t1; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +create table t1 like mysqltest_2.t1; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +grant select on mysqltest_2.t1 to mysqltest_u1@localhost; +show create table mysqltest_2.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create table t1 like mysqltest_2.t1; +use test; +drop database mysqltest_1; +drop database mysqltest_2; +drop user mysqltest_u1@localhost; +End of 5.0 tests diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index d08a9e3f83d..4a3324b1833 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -513,3 +513,47 @@ disconnect bug13310; connection default; REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost; drop user `a@`@localhost; + + +# +# Bug#25578 "CREATE TABLE LIKE does not require any privileges on source table" +# +--disable_warnings +drop database if exists mysqltest_1; +drop database if exists mysqltest_2; +--enable_warnings +--error 0,ER_CANNOT_USER +drop user mysqltest_u1@localhost; + +create database mysqltest_1; +create database mysqltest_2; +grant all on mysqltest_1.* to mysqltest_u1@localhost; +use mysqltest_2; +create table t1 (i int); + +# Connect as user with all rights on mysqltest_1 but with no rights on mysqltest_2. +connect (user1,localhost,mysqltest_u1,,mysqltest_1); +connection user1; +# As expected error is emitted +--error ER_TABLEACCESS_DENIED_ERROR +show create table mysqltest_2.t1; +# This should emit error as well +--error ER_TABLEACCESS_DENIED_ERROR +create table t1 like mysqltest_2.t1; + +# Now let us check that SELECT privilege on the source is enough +connection default; +grant select on mysqltest_2.t1 to mysqltest_u1@localhost; +connection user1; +show create table mysqltest_2.t1; +create table t1 like mysqltest_2.t1; + +# Clean-up +connection default; +use test; +drop database mysqltest_1; +drop database mysqltest_2; +drop user mysqltest_u1@localhost; + +--echo End of 5.0 tests + diff --git a/sql/handler.h b/sql/handler.h index 9863d541b5f..a59b7a09740 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -162,6 +162,7 @@ #define HA_LEX_CREATE_TMP_TABLE 1 #define HA_LEX_CREATE_IF_NOT_EXISTS 2 +#define HA_LEX_CREATE_TABLE_LIKE 4 #define HA_OPTION_NO_CHECKSUM (1L << 17) #define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18) #define HA_MAX_REC_LENGTH 65535 diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f03ef487154..3d061c9eb9e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -816,9 +816,8 @@ bool mysql_alter_table(THD *thd, char *new_db, char *new_name, Alter_info *alter_info, uint order_num, ORDER *order, bool ignore); bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list); -bool mysql_create_like_table(THD *thd, TABLE_LIST *table, - HA_CREATE_INFO *create_info, - Table_ident *src_table); +bool mysql_create_like_table(THD *thd, TABLE_LIST *table, TABLE_LIST *src_table, + HA_CREATE_INFO *create_info); bool mysql_rename_table(enum db_type base, const char *old_db, const char * old_name, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7e58b36a939..6277a6c0c10 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -75,6 +75,7 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables); static void remove_escape(char *name); static bool append_file_to_dir(THD *thd, const char **filename_ptr, const char *table_name); +static bool check_show_create_table_access(THD *thd, TABLE_LIST *table); const char *any_db="*any*"; // Special symbol for check_access @@ -3080,9 +3081,9 @@ mysql_execute_command(THD *thd) else { /* regular create */ - if (lex->name) - res= mysql_create_like_table(thd, create_table, &create_info, - (Table_ident *)lex->name); + if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE) + res= mysql_create_like_table(thd, create_table, select_tables, + &create_info); else { res= mysql_create_table(thd, create_table->db, @@ -3319,11 +3320,7 @@ end_with_restore_list: first_table->skip_temporary= 1; if (check_db_used(thd, all_tables) || - check_access(thd, SELECT_ACL | EXTRA_ACL, first_table->db, - &first_table->grant.privilege, 0, 0, - test(first_table->schema_table))) - goto error; - if (grant_option && check_grant(thd, SELECT_ACL, all_tables, 2, UINT_MAX, 0)) + check_show_create_table_access(thd, first_table)) goto error; res= mysqld_show_create(thd, first_table); break; @@ -7519,6 +7516,25 @@ bool insert_precheck(THD *thd, TABLE_LIST *tables) } +/** + @brief Check privileges for SHOW CREATE TABLE statement. + + @param thd Thread context + @param table Target table + + @retval TRUE Failure + @retval FALSE Success +*/ + +static bool check_show_create_table_access(THD *thd, TABLE_LIST *table) +{ + return check_access(thd, SELECT_ACL | EXTRA_ACL, table->db, + &table->grant.privilege, 0, 0, + test(table->schema_table)) || + grant_option && check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0); +} + + /* CREATE TABLE query pre-check @@ -7583,6 +7599,11 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, if (tables && check_table_access(thd, SELECT_ACL, tables,0)) goto err; } + else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE) + { + if (check_show_create_table_access(thd, tables)) + goto err; + } error= FALSE; err: diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 079cc0d6456..4a9f6074b59 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2718,7 +2718,8 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables) SYNOPSIS mysql_create_like_table() thd Thread object - table Table list (one table only) + table Table list element for target table + src_table Table list element for source table create_info Create info table_ident Src table_ident @@ -2727,61 +2728,52 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables) TRUE error */ -bool mysql_create_like_table(THD* thd, TABLE_LIST* table, - HA_CREATE_INFO *create_info, - Table_ident *table_ident) +bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST *src_table, + HA_CREATE_INFO *create_info) { TABLE **tmp_table; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char *db= table->db; char *table_name= table->table_name; - char *src_db; - char *src_table= table_ident->table.str; int err; bool res= TRUE; db_type not_used; - - TABLE_LIST src_tables_list; DBUG_ENTER("mysql_create_like_table"); - DBUG_ASSERT(table_ident->db.str); /* Must be set in the parser */ - src_db= table_ident->db.str; /* - Validate the source table + By taking name-lock on the source table and holding LOCK_open mutex we + ensure that no concurrent DDL operation will mess with this table. Note + that holding only name-lock is not enough for this, because it won't block + other DDL statements that only take name-locks on the table and don't + open it (simple name-locks are not exclusive between each other). + + Unfortunately, simply opening this table is not enough for our purproses, + since in 5.0 ALTER TABLE may change .FRM files on disk even if there are + connections that still have old version of table open. This 'optimization' + was removed in 5.1 so there we open the source table instead of taking + name-lock on it. + + We also have to acquire LOCK_open to make copying of .frm file, call to + ha_create_table() and binlogging atomic against concurrent DML and DDL + operations on the target table. */ - if (table_ident->table.length > NAME_LEN || - (table_ident->table.length && - check_table_name(src_table,table_ident->table.length))) - { - my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); - DBUG_RETURN(TRUE); - } - if (!src_db || check_db_name(src_db)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), src_db ? src_db : "NULL"); - DBUG_RETURN(-1); - } - - bzero((gptr)&src_tables_list, sizeof(src_tables_list)); - src_tables_list.db= src_db; - src_tables_list.table_name= src_table; - - if (lock_and_wait_for_table_name(thd, &src_tables_list)) + if (lock_and_wait_for_table_name(thd, src_table)) goto err; - if ((tmp_table= find_temporary_table(thd, src_db, src_table))) + pthread_mutex_lock(&LOCK_open); + + if ((tmp_table= find_temporary_table(thd, src_table->db, + src_table->table_name))) strxmov(src_path, (*tmp_table)->s->path, reg_ext, NullS); else { - strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table, - reg_ext, NullS); + strxmov(src_path, mysql_data_home, "/", src_table->db, "/", + src_table->table_name, reg_ext, NullS); /* Resolve symlinks (for windows) */ fn_format(src_path, src_path, "", "", MYF(MY_UNPACK_FILENAME)); - if (lower_case_table_names) - my_casedn_str(files_charset_info, src_path); if (access(src_path, F_OK)) { - my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table); + my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table->table_name); goto err; } } @@ -2791,10 +2783,13 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, */ if (mysql_frm_type(thd, src_path, ¬_used) != FRMTYPE_TABLE) { - my_error(ER_WRONG_OBJECT, MYF(0), src_db, src_table, "BASE TABLE"); + my_error(ER_WRONG_OBJECT, MYF(0), src_table->db, src_table->table_name, + "BASE TABLE"); goto err; } + DBUG_EXECUTE_IF("sleep_create_like_before_check_if_exists", my_sleep(6000000);); + /* Validate the destination table @@ -2810,27 +2805,22 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, } else { - bool exists; strxmov(dst_path, mysql_data_home, "/", db, "/", table_name, reg_ext, NullS); fn_format(dst_path, dst_path, "", "", MYF(MY_UNPACK_FILENAME)); /* - Note that this critical section should actually cover most - of mysql_create_like_table() function. See bugs #18950 and - #23667 for more information. - Also note that starting from 5.1 we obtain name-lock on - target table instead of inspecting table cache for presence + Note that starting from 5.1 we obtain name-lock on target + table instead of inspecting table cache for presence of open placeholders (see comment in mysql_create_table()). */ - pthread_mutex_lock(&LOCK_open); - exists= (table_cache_has_open_placeholder(thd, db, table_name) || - !access(dst_path, F_OK)); - pthread_mutex_unlock(&LOCK_open); - if (exists) + if (table_cache_has_open_placeholder(thd, db, table_name) || + !access(dst_path, F_OK)) goto table_exists; } + DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000);); + /* Create a new table by copying from source table */ @@ -2843,6 +2833,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, goto err; } + DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000);); + /* As mysql_truncate don't work on a new table at this stage of creation, instead create the table directly (for both normal @@ -2867,6 +2859,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, goto err; /* purecov: inspected */ } + DBUG_EXECUTE_IF("sleep_create_like_before_binlogging", my_sleep(6000000);); + // Must be written before unlock if (mysql_bin_log.is_open()) { @@ -2891,8 +2885,7 @@ table_exists: my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); err: - pthread_mutex_lock(&LOCK_open); - unlock_table_name(thd, &src_tables_list); + unlock_table_name(thd, src_table); pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(res); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c1da870960b..b970bcaedd6 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1483,7 +1483,6 @@ create: lex->create_info.options=$2 | $4; lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type; lex->create_info.default_table_charset= NULL; - lex->name=0; } create2 { Lex->current_select= &Lex->select_lex; } @@ -2763,27 +2762,15 @@ create2: | opt_create_table_options create3 {} | LIKE table_ident { - LEX *lex=Lex; - THD *thd= lex->thd; - if (!(lex->name= (char *)$2)) + Lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE; + if (!Lex->select_lex.add_table_to_list(YYTHD, $2, NULL, 0, TL_READ)) MYSQL_YYABORT; - if ($2->db.str == NULL && - thd->copy_db_to(&($2->db.str), &($2->db.length))) - { - MYSQL_YYABORT; - } } | '(' LIKE table_ident ')' { - LEX *lex=Lex; - THD *thd= lex->thd; - if (!(lex->name= (char *)$3)) + Lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE; + if (!Lex->select_lex.add_table_to_list(YYTHD, $3, NULL, 0, TL_READ)) MYSQL_YYABORT; - if ($3->db.str == NULL && - thd->copy_db_to(&($3->db.str), &($3->db.length))) - { - MYSQL_YYABORT; - } } ; From 206a6bb1764cef00452f0e8afb83480cc0ee65c1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 May 2007 15:26:16 +0400 Subject: [PATCH 24/74] 5.1 version of fix for: Bug #23667 "CREATE TABLE LIKE is not isolated from alteration by other connections" Bug #18950 "CREATE TABLE LIKE does not obtain LOCK_open" As well as: Bug #25578 "CREATE TABLE LIKE does not require any privileges on source table". The first and the second bugs resulted in various errors and wrong binary log order when one tried to execute concurrently CREATE TABLE LIKE statement and DDL statements on source table or DML/DDL statements on its target table. The problem was caused by incomplete protection/table-locking against concurrent statements implemented in mysql_create_like_table() routine. We solve it by simply implementing such protection in proper way. Most of actual work for 5.1 was already done by fix for bug 20662 and preliminary patch changing locking in ALTER TABLE. The third bug allowed user who didn't have any privileges on table create its copy and therefore circumvent privilege check for SHOW CREATE TABLE. This patch solves this problem by adding privilege check, which was missing. Finally it also removes some duplicated code from mysql_create_like_table() and thus fixes bug #26869 "TABLE_LIST::table_name_length inconsistent with TABLE_LIST::table_name". mysql-test/r/create-big.result: Added test coverage for concurrency-related issues with CREATE TABLE LIKE. mysql-test/r/create.result: Adjusted error-code in the test case after refactoring code that implements CREATE TABLE ... LIKE. mysql-test/r/grant2.result: Added test for bug#25578 "CREATE TABLE LIKE does not require any privileges on source table". mysql-test/t/create-big.test: Added test coverage for concurrency-related issues with CREATE TABLE LIKE. mysql-test/t/create.test: Adjusted error-code in the test case after refactoring code that implements CREATE TABLE ... LIKE. mysql-test/t/disabled.def: Recent code changes ensured that CREATE TABLE LIKE statement is properly isolated against other statements, so synchronization.test should no longer fail (see fix for bug 20662 and preliminary patch for bug 23667 changing ALTER TABLE locking). mysql-test/t/grant2.test: Added test for bug#25578 "CREATE TABLE LIKE does not require any privileges on source table". sql/handler.h: Introduced new flag for HA_CREATE_INFO::options in order to be able to distinguish CREATE TABLE ... LIKE from other types of CREATE TABLE. sql/mysql_priv.h: mysql_create_like_table() now takes source table name not as a Table_ident object but as regular table list element. sql/sql_lex.h: Removed LEX::like_name member. Now we use special flag in LEX::create_info::options for distinguishing CREATE TABLE ... LIKE from other types of CREATE TABLE and store name of source table as regular element in statement's table list. sql/sql_parse.cc: CREATE TABLE ... LIKE implementation now uses statement's table list for storing information about the source table. We also use flag in LEX::create_info.options for distinguishing it from other types of CREATE TABLE. Finally CREATE TABLE ... LIKE now requires the same privileges on the source tables as SHOW CREATE TABLE. Moved this privilege check to check_show_create_table_access() function. sql/sql_partition.cc: Now we use special flag in LEX::create_info::options for distinguishing CREATE TABLE ... LIKE from other types of CREATE TABLE and store name of source table as regular element in statement's table list. sql/sql_table.cc: mysql_create_like_table(): - Commented and cleaned-up a bit code which is responsible for achieving isolation from concurrent statements. Most of actual work was done by fix for bug 20662 and preliminary patch changing locking locking in ALTER TABLE, so here we do minor things like relaxing locking on source table (we don't need lock on it, to have it open is enough) and adjusting code to make it more friendly against code implementing I_S. - Get rid of duplicated code related to source database/table name handling. All these operations are already done in st_select_lex::add_table_to_list(), so we achieve the same effect by including source table into the statement's table list. sql/sql_yacc.yy: Now we use special flag in LEX::create_info::options for distinguishing CREATE TABLE ... LIKE from other types of CREATE TABLE and store name of source table as regular element in statement's table list. --- ...te_select-big.result => create-big.result} | 83 +++++++++++ mysql-test/r/create.result | 2 +- mysql-test/r/grant2.result | 23 +++ ...create_select-big.test => create-big.test} | 132 ++++++++++++++++- mysql-test/t/create.test | 2 +- mysql-test/t/disabled.def | 1 - mysql-test/t/grant2.test | 41 ++++++ sql/handler.h | 1 + sql/mysql_priv.h | 5 +- sql/sql_lex.h | 1 - sql/sql_parse.cc | 38 +++-- sql/sql_partition.cc | 17 +-- sql/sql_table.cc | 137 ++++++------------ sql/sql_yacc.yy | 22 +-- 14 files changed, 364 insertions(+), 141 deletions(-) rename mysql-test/r/{create_select-big.result => create-big.result} (55%) rename mysql-test/t/{create_select-big.test => create-big.test} (64%) diff --git a/mysql-test/r/create_select-big.result b/mysql-test/r/create-big.result similarity index 55% rename from mysql-test/r/create_select-big.result rename to mysql-test/r/create-big.result index 1c393bd2224..eb57bf59084 100644 --- a/mysql-test/r/create_select-big.result +++ b/mysql-test/r/create-big.result @@ -162,3 +162,86 @@ t1 CREATE TABLE `t1` ( `j` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1, t2, t3; +drop table if exists t1,t2; +create table t1 (i int); +set session debug="+d,sleep_create_like_before_check_if_exists"; +reset master; +create table t2 like t1;; +insert into t1 values (1); +drop table t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `i` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t2; +show binlog events in 'master-bin.000001' from 106; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query 1 # use `test`; insert into t1 values (1) +master-bin.000001 # Query 1 # use `test`; create table t2 like t1 +master-bin.000001 # Query 1 # use `test`; drop table t1 +master-bin.000001 # Query 1 # use `test`; drop table t2 +create table t1 (i int); +set session debug="-d,sleep_create_like_before_check_if_exists:+d,sleep_create_like_before_copy"; +create table t2 like t1;; +create table if not exists t2 (j int); +Warnings: +Note 1050 Table 't2' already exists +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `i` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t2; +reset master; +create table t2 like t1;; +drop table t1; +drop table t2; +show binlog events in 'master-bin.000001' from 106; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query 1 # use `test`; create table t2 like t1 +master-bin.000001 # Query 1 # use `test`; drop table t1 +master-bin.000001 # Query 1 # use `test`; drop table t2 +create table t1 (i int); +set session debug="-d,sleep_create_like_before_copy:+d,sleep_create_like_before_ha_create"; +reset master; +create table t2 like t1;; +insert into t2 values (1); +drop table t2; +create table t2 like t1;; +drop table t2; +create table t2 like t1;; +drop table t1; +drop table t2; +show binlog events in 'master-bin.000001' from 106; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query 1 # use `test`; create table t2 like t1 +master-bin.000001 # Query 1 # use `test`; insert into t2 values (1) +master-bin.000001 # Query 1 # use `test`; drop table t2 +master-bin.000001 # Query 1 # use `test`; create table t2 like t1 +master-bin.000001 # Query 1 # use `test`; drop table t2 +master-bin.000001 # Query 1 # use `test`; create table t2 like t1 +master-bin.000001 # Query 1 # use `test`; drop table t1 +master-bin.000001 # Query 1 # use `test`; drop table t2 +create table t1 (i int); +set session debug="-d,sleep_create_like_before_ha_create:+d,sleep_create_like_before_binlogging"; +reset master; +create table t2 like t1;; +insert into t2 values (1); +drop table t2; +create table t2 like t1;; +drop table t2; +create table t2 like t1;; +drop table t1; +drop table t2; +show binlog events in 'master-bin.000001' from 106; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query 1 # use `test`; create table t2 like t1 +master-bin.000001 # Query 1 # use `test`; insert into t2 values (1) +master-bin.000001 # Query 1 # use `test`; drop table t2 +master-bin.000001 # Query 1 # use `test`; create table t2 like t1 +master-bin.000001 # Query 1 # use `test`; drop table t2 +master-bin.000001 # Query 1 # use `test`; create table t2 like t1 +master-bin.000001 # Query 1 # use `test`; drop table t1 +master-bin.000001 # Query 1 # use `test`; drop table t2 +set session debug="-d,sleep_create_like_before_binlogging"; diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index ef22b21e9fb..f570f6eb75c 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -371,7 +371,7 @@ ERROR 42S01: Table 't3' already exists create table non_existing_database.t1 like t1; ERROR 42000: Unknown database 'non_existing_database' create table t3 like non_existing_table; -ERROR 42S02: Unknown table 'non_existing_table' +ERROR 42S02: Table 'test.non_existing_table' doesn't exist create temporary table t3 like t1; ERROR 42S01: Table 't3' already exists drop table t1, t2, t3; diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 03019bd5c1f..f2722ee052e 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -381,3 +381,26 @@ drop table t2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost; drop user `a@`@localhost; SET GLOBAL log_bin_trust_function_creators = 0; +drop database if exists mysqltest_1; +drop database if exists mysqltest_2; +drop user mysqltest_u1@localhost; +create database mysqltest_1; +create database mysqltest_2; +grant all on mysqltest_1.* to mysqltest_u1@localhost; +use mysqltest_2; +create table t1 (i int); +show create table mysqltest_2.t1; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +create table t1 like mysqltest_2.t1; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +grant select on mysqltest_2.t1 to mysqltest_u1@localhost; +show create table mysqltest_2.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +create table t1 like mysqltest_2.t1; +use test; +drop database mysqltest_1; +drop database mysqltest_2; +drop user mysqltest_u1@localhost; diff --git a/mysql-test/t/create_select-big.test b/mysql-test/t/create-big.test similarity index 64% rename from mysql-test/t/create_select-big.test rename to mysql-test/t/create-big.test index 3fa655c5501..6cd6326cdb8 100644 --- a/mysql-test/t/create_select-big.test +++ b/mysql-test/t/create-big.test @@ -1,12 +1,17 @@ -# Tests for various aspects of CREATE TABLE ... SELECT implementation +# Tests for various concurrency-related aspects of CREATE TABLE ... SELECT +# and CREATE TABLE like implementation. # -# Note that we don't test general CREATE TABLE ... SELECT functionality here as -# it is already covered by create.test. We are more interested in extreme cases. +# Note that we don't test general CREATE TABLE ... SELECT/LIKE functionality +# here as it is already covered by create.test. We are more interested in +# extreme cases. # # This test takes rather long time so let us run it only in --big-test mode --source include/big_test.inc # We are using some debug-only features in this test --source include/have_debug.inc +# Some of tests below also use binlog to check that statements are +# executed and logged in correct order +--source include/have_binlog_format_mixed_or_statement.inc # Create auxilliary connections connect (addconroot1, localhost, root,,); @@ -20,7 +25,7 @@ drop table if exists t1,t2,t3,t4,t5; # -# Tests for concurrency problems. +# Tests for concurrency problems in CREATE TABLE ... SELECT # # We introduce delays between various stages of table creation # and check that other statements dealing with this table cannot @@ -266,3 +271,122 @@ connection default; select * from t1; show create table t1; drop table t1, t2, t3; + + +# Tests for possible concurrency issues with CREATE TABLE ... LIKE +# +# Bug #18950 "create table like does not obtain LOCK_open" +# Bug #23667 "CREATE TABLE LIKE is not isolated from alteration by other +# connections" +# +# Again the idea of this test is that we introduce artificial delays on +# various stages of table creation and check that concurrent statements +# for tables from CREATE TABLE ... LIKE are not interfering. + +--disable_warnings +drop table if exists t1,t2; +--enable_warnings + +# What happens if some statements sneak in right after we have +# opened source table ? +create table t1 (i int); +set session debug="+d,sleep_create_like_before_check_if_exists"; +# Reset binlog to have clear start +reset master; +--send create table t2 like t1; +connection addconroot1; +--sleep 2 +# DML on source table should be allowed to run concurrently +insert into t1 values (1); +# And DDL should wait +drop table t1; +connection default; +--reap +show create table t2; +drop table t2; +# Let us check that statements were executed/binlogged in correct order +--replace_column 2 # 5 # +show binlog events in 'master-bin.000001' from 106; + +# Now let us check the gap between check for target table +# existance and copying of .frm file. +create table t1 (i int); +set session debug="-d,sleep_create_like_before_check_if_exists:+d,sleep_create_like_before_copy"; +# It should be impossible to create target table concurrently +--send create table t2 like t1; +connection addconroot1; +--sleep 2 +create table if not exists t2 (j int); +connection default; +--reap +show create table t2; +drop table t2; +# And concurrent DDL on the source table should be still disallowed +reset master; +--send create table t2 like t1; +connection addconroot1; +--sleep 2 +drop table t1; +connection default; +--reap +drop table t2; +--replace_column 2 # 5 # +show binlog events in 'master-bin.000001' from 106; + +# And now he gap between copying of .frm file and ha_create_table() call. +create table t1 (i int); +set session debug="-d,sleep_create_like_before_copy:+d,sleep_create_like_before_ha_create"; +# Both DML and DDL on target table should wait till operation completes +reset master; +--send create table t2 like t1; +connection addconroot1; +--sleep 2 +insert into t2 values (1); +connection default; +--reap +drop table t2; +--send create table t2 like t1; +connection addconroot1; +--sleep 2 +drop table t2; +connection default; +--reap +# Concurrent DDL on the source table still waits +--send create table t2 like t1; +connection addconroot1; +--sleep 2 +drop table t1; +connection default; +--reap +drop table t2; +--replace_column 2 # 5 # +show binlog events in 'master-bin.000001' from 106; + +# Finally we check the gap between ha_create_table() and binlogging +create table t1 (i int); +set session debug="-d,sleep_create_like_before_ha_create:+d,sleep_create_like_before_binlogging"; +reset master; +--send create table t2 like t1; +connection addconroot1; +--sleep 2 +insert into t2 values (1); +connection default; +--reap +drop table t2; +--send create table t2 like t1; +connection addconroot1; +--sleep 2 +drop table t2; +connection default; +--reap +--send create table t2 like t1; +connection addconroot1; +--sleep 2 +drop table t1; +connection default; +--reap +drop table t2; +--replace_column 2 # 5 # +show binlog events in 'master-bin.000001' from 106; + +set session debug="-d,sleep_create_like_before_binlogging"; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 243cdea009e..fb589a5d11e 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -306,7 +306,7 @@ create table t3 like t1; create table t3 like mysqltest.t3; --error 1049 create table non_existing_database.t1 like t1; ---error 1051 +--error ER_NO_SUCH_TABLE create table t3 like non_existing_table; --error 1050 create temporary table t3 like t1; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index e3d72f1f7e0..12c5f38c680 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -30,7 +30,6 @@ rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after C rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly -synchronization : Bug#24529 Test 'synchronization' fails on Mac pushbuild; Also on Linux 64 bit. # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open #ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index 866c5a8a4b3..9b83cd5aab7 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -513,3 +513,44 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM `a@`@localhost; drop user `a@`@localhost; SET GLOBAL log_bin_trust_function_creators = 0; + + +# +# Bug#25578 "CREATE TABLE LIKE does not require any privileges on source table" +# +--disable_warnings +drop database if exists mysqltest_1; +drop database if exists mysqltest_2; +--enable_warnings +--error 0,ER_CANNOT_USER +drop user mysqltest_u1@localhost; + +create database mysqltest_1; +create database mysqltest_2; +grant all on mysqltest_1.* to mysqltest_u1@localhost; +use mysqltest_2; +create table t1 (i int); + +# Connect as user with all rights on mysqltest_1 but with no rights on mysqltest_2. +connect (user1,localhost,mysqltest_u1,,mysqltest_1); +connection user1; +# As expected error is emitted +--error ER_TABLEACCESS_DENIED_ERROR +show create table mysqltest_2.t1; +# This should emit error as well +--error ER_TABLEACCESS_DENIED_ERROR +create table t1 like mysqltest_2.t1; + +# Now let us check that SELECT privilege on the source is enough +connection default; +grant select on mysqltest_2.t1 to mysqltest_u1@localhost; +connection user1; +show create table mysqltest_2.t1; +create table t1 like mysqltest_2.t1; + +# Clean-up +connection default; +use test; +drop database mysqltest_1; +drop database mysqltest_2; +drop user mysqltest_u1@localhost; diff --git a/sql/handler.h b/sql/handler.h index 052c245b801..216620a6882 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -223,6 +223,7 @@ #define HA_LEX_CREATE_TMP_TABLE 1 #define HA_LEX_CREATE_IF_NOT_EXISTS 2 +#define HA_LEX_CREATE_TABLE_LIKE 4 #define HA_OPTION_NO_CHECKSUM (1L << 17) #define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18) #define HA_MAX_REC_LENGTH 65535 diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index e5e70f81bff..0b843d5610d 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -978,9 +978,8 @@ bool mysql_alter_table(THD *thd, char *new_db, char *new_name, uint order_num, ORDER *order, bool ignore, ALTER_INFO *alter_info, bool do_send_ok); bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok); -bool mysql_create_like_table(THD *thd, TABLE_LIST *table, - HA_CREATE_INFO *create_info, - Table_ident *src_table); +bool mysql_create_like_table(THD *thd, TABLE_LIST *table, TABLE_LIST *src_table, + HA_CREATE_INFO *create_info); bool mysql_rename_table(handlerton *base, const char *old_db, const char * old_name, const char *new_db, const char * new_name, uint flags); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 3dca1d15b88..ddd7c752e11 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1066,7 +1066,6 @@ typedef struct st_lex : public Query_tables_list char *length,*dec,*change; LEX_STRING name; - Table_ident *like_name; char *help_arg; char *backup_dir; /* For RESTORE/BACKUP */ char* to_log; /* For PURGE MASTER LOGS TO */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 06419010a24..ed4fefe1e19 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -39,6 +39,7 @@ "FUNCTION" : "PROCEDURE") static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables); +static bool check_show_create_table_access(THD *thd, TABLE_LIST *table); const char *any_db="*any*"; // Special symbol for check_access @@ -2240,9 +2241,9 @@ mysql_execute_command(THD *thd) if (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) thd->options|= OPTION_KEEP_LOG; /* regular create */ - if (lex->like_name) - res= mysql_create_like_table(thd, create_table, &lex->create_info, - lex->like_name); + if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE) + res= mysql_create_like_table(thd, create_table, select_tables, + &lex->create_info); else { res= mysql_create_table(thd, create_table->db, @@ -2432,12 +2433,7 @@ end_with_restore_list: /* Ignore temporary tables if this is "SHOW CREATE VIEW" */ if (lex->only_view) first_table->skip_temporary= 1; - - if (check_access(thd, SELECT_ACL | EXTRA_ACL, first_table->db, - &first_table->grant.privilege, 0, 0, - test(first_table->schema_table))) - goto error; - if (grant_option && check_grant(thd, SELECT_ACL, all_tables, 2, UINT_MAX, 0)) + if (check_show_create_table_access(thd, first_table)) goto error; res= mysqld_show_create(thd, first_table); break; @@ -6854,6 +6850,25 @@ bool insert_precheck(THD *thd, TABLE_LIST *tables) } +/** + @brief Check privileges for SHOW CREATE TABLE statement. + + @param thd Thread context + @param table Target table + + @retval TRUE Failure + @retval FALSE Success +*/ + +static bool check_show_create_table_access(THD *thd, TABLE_LIST *table) +{ + return check_access(thd, SELECT_ACL | EXTRA_ACL, table->db, + &table->grant.privilege, 0, 0, + test(table->schema_table)) || + grant_option && check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0); +} + + /* CREATE TABLE query pre-check @@ -6919,6 +6934,11 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, if (tables && check_table_access(thd, SELECT_ACL, tables,0)) goto err; } + else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE) + { + if (check_show_create_table_access(thd, tables)) + goto err; + } error= FALSE; err: diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index e49c2642924..9b929900143 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -3776,20 +3776,15 @@ bool mysql_unpack_partition(THD *thd, ha_legacy_type(default_db_type))); if (is_create_table_ind && old_lex->sql_command == SQLCOM_CREATE_TABLE) { - if (old_lex->like_name) + if (old_lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE) { /* - This code is executed when we do a CREATE TABLE t1 LIKE t2 - old_lex->like_name contains the t2 and the table we are opening has - name t1. + This code is executed when we create table in CREATE TABLE t1 LIKE t2. + old_lex->query_tables contains table list element for t2 and the table + we are opening has name t1. */ - Table_ident *table_ident= old_lex->like_name; - char *src_db= table_ident->db.str ? table_ident->db.str : thd->db; - char *src_table= table_ident->table.str; - char buf[FN_REFLEN]; - build_table_filename(buf, sizeof(buf), src_db, src_table, "", 0); - if (partition_default_handling(table, part_info, - FALSE, buf)) + if (partition_default_handling(table, part_info, FALSE, + old_lex->query_tables->table->s->path.str)) { result= TRUE; goto end; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 149c746a1de..2727b014db0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4665,114 +4665,51 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables) SYNOPSIS mysql_create_like_table() thd Thread object - table Table list (one table only) + table Table list element for target table + src_table Table list element for source table create_info Create info - table_ident Src table_ident RETURN VALUES FALSE OK TRUE error */ -bool mysql_create_like_table(THD* thd, TABLE_LIST* table, - HA_CREATE_INFO *lex_create_info, - Table_ident *table_ident) +bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, + HA_CREATE_INFO *lex_create_info) { - TABLE *tmp_table, *name_lock= 0; + TABLE *name_lock= 0; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; - char src_table_name_buff[FN_REFLEN], src_db_name_buff[FN_REFLEN]; uint dst_path_length; char *db= table->db; char *table_name= table->table_name; - char *src_db; - char *src_table= table_ident->table.str; int err; bool res= TRUE; - enum legacy_db_type not_used; + uint not_used; HA_CREATE_INFO *create_info; #ifdef WITH_PARTITION_STORAGE_ENGINE char tmp_path[FN_REFLEN]; #endif char ts_name[FN_LEN]; - TABLE_LIST src_tables_list; DBUG_ENTER("mysql_create_like_table"); if (!(create_info= copy_create_info(lex_create_info))) { DBUG_RETURN(TRUE); } - DBUG_ASSERT(table_ident->db.str); /* Must be set in the parser */ - src_db= table_ident->db.str; + + /* CREATE TABLE ... LIKE is not allowed for views. */ + src_table->required_type= FRMTYPE_TABLE; /* - Validate the source table + By opening source table we guarantee that it exists and no concurrent + DDL operation will mess with it. Later we also take an exclusive + name-lock on target table name, which makes copying of .frm file, + call to ha_create_table() and binlogging atomic against concurrent DML + and DDL operations on target table. Thus by holding both these "locks" + we ensure that our statement is properly isolated from all concurrent + operations which matter. */ - if (check_string_char_length(&table_ident->table, "", NAME_CHAR_LEN, - system_charset_info, 1) || - (table_ident->table.length && - check_table_name(src_table,table_ident->table.length))) - { - my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); - DBUG_RETURN(TRUE); - } - if (!src_db || check_db_name(&table_ident->db)) - { - my_error(ER_WRONG_DB_NAME, MYF(0), src_db ? src_db : "NULL"); - DBUG_RETURN(-1); - } - - if ((tmp_table= find_temporary_table(thd, src_db, src_table))) - strxmov(src_path, tmp_table->s->path.str, reg_ext, NullS); - else - { - build_table_filename(src_path, sizeof(src_path), - src_db, src_table, reg_ext, 0); - /* Resolve symlinks (for windows) */ - unpack_filename(src_path, src_path); - if (lower_case_table_names) - my_casedn_str(files_charset_info, src_path); - if (access(src_path, F_OK)) - { - my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table); - goto err; - } - } - - /* - create like should be not allowed for Views, Triggers, ... - */ - if (mysql_frm_type(thd, src_path, ¬_used) != FRMTYPE_TABLE) - { - my_error(ER_WRONG_OBJECT, MYF(0), src_db, src_table, "BASE TABLE"); - goto err; - } - - if (lower_case_table_names) - { - if (src_db) - { - strmake(src_db_name_buff, src_db, - min(sizeof(src_db_name_buff) - 1, table_ident->db.length)); - my_casedn_str(files_charset_info, src_db_name_buff); - src_db= src_db_name_buff; - } - if (src_table) - { - strmake(src_table_name_buff, src_table, - min(sizeof(src_table_name_buff) - 1, table_ident->table.length)); - my_casedn_str(files_charset_info, src_table_name_buff); - src_table= src_table_name_buff; - } - } - - bzero((gptr)&src_tables_list, sizeof(src_tables_list)); - src_tables_list.db= src_db; - src_tables_list.db_length= table_ident->db.length; - src_tables_list.lock_type= TL_READ; - src_tables_list.table_name= src_table; - src_tables_list.alias= src_table; - - if (simple_open_n_lock_tables(thd, &src_tables_list)) + if (open_tables(thd, &src_table, ¬_used, 0)) DBUG_RETURN(TRUE); /* @@ -4781,17 +4718,19 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, Add something to get possible tablespace info from src table, it can get valid tablespace name only for disk-base ndb table */ - if ((src_tables_list.table->file->get_tablespace_name(thd, ts_name, FN_LEN))) + if ((src_table->table->file->get_tablespace_name(thd, ts_name, FN_LEN))) { create_info->tablespace= ts_name; create_info->storage_media= HA_SM_DISK; } - /* - Validate the destination table + strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS); - skip the destination table name checking as this is already - validated. + DBUG_EXECUTE_IF("sleep_create_like_before_check_if_exists", my_sleep(6000000);); + + /* + Check that destination tables does not exist. Note that its name + was already checked when it was added to the table list. */ if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { @@ -4812,15 +4751,29 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, goto table_exists; } + DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000);); + /* Create a new table by copying from source table + + Altough exclusive name-lock on target table protects us from concurrent + DML and DDL operations on it we still want to wrap .FRM creation and call + to ha_create_table() in critical section protected by LOCK_open in order + to provide minimal atomicity against operations which disregard name-locks, + like I_S implementation, for example. This is a temporary and should not + be copied. Instead we should fix our code to always honor name-locks. + + Also some engines (e.g. NDB cluster) require that LOCK_open should be held + during the call to ha_create_table(). See bug #28614 for more info. */ + VOID(pthread_mutex_lock(&LOCK_open)); if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE))) { if (my_errno == ENOENT) my_error(ER_BAD_DB_ERROR,MYF(0),db); else my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno); + VOID(pthread_mutex_unlock(&LOCK_open)); goto err; } @@ -4842,10 +4795,12 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, strmov(src_path, tmp_path); my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)); #endif + + DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000);); + dst_path[dst_path_length - reg_ext_length]= '\0'; // Remove .frm - pthread_mutex_lock(&LOCK_open); err= ha_create_table(thd, dst_path, db, table_name, create_info, 1); - pthread_mutex_unlock(&LOCK_open); + VOID(pthread_mutex_unlock(&LOCK_open)); if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { if (err || !open_temporary_table(thd, dst_path, db, table_name, 1)) @@ -4862,6 +4817,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, goto err; /* purecov: inspected */ } + DBUG_EXECUTE_IF("sleep_create_like_before_binlogging", my_sleep(6000000);); + /* We have to write the query before we unlock the tables. */ @@ -4881,14 +4838,10 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, 3 temporary normal Nothing 4 temporary temporary Nothing ==== ========= ========= ============================== - - The variable 'tmp_table' below is used to see if the source - table is a temporary table: if it is set, then the source table - was a temporary table and we can take apropriate actions. */ if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { - if (tmp_table) // Case 2 + if (src_table->table->s->tmp_table) // Case 2 { char buf[2048]; String query(buf, sizeof(buf), system_charset_info); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 38d9663fa5c..93df7db0605 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1579,7 +1579,6 @@ create: lex->create_info.default_table_charset= NULL; lex->name.str= 0; lex->name.length= 0; - lex->like_name= 0; } create2 { @@ -3603,27 +3602,15 @@ create2: create3 {} | LIKE table_ident { - THD *thd= YYTHD; - LEX *lex= thd->lex; - if (!(lex->like_name= $2)) + Lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE; + if (!Lex->select_lex.add_table_to_list(YYTHD, $2, NULL, 0, TL_READ)) MYSQL_YYABORT; - if ($2->db.str == NULL && - thd->copy_db_to(&($2->db.str), &($2->db.length))) - { - MYSQL_YYABORT; - } } | '(' LIKE table_ident ')' { - THD *thd= YYTHD; - LEX *lex= thd->lex; - if (!(lex->like_name= $3)) + Lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE; + if (!Lex->select_lex.add_table_to_list(YYTHD, $3, NULL, 0, TL_READ)) MYSQL_YYABORT; - if ($3->db.str == NULL && - thd->copy_db_to(&($3->db.str), &($3->db.length))) - { - MYSQL_YYABORT; - } } ; @@ -5112,7 +5099,6 @@ alter: lex->key_list.empty(); lex->col_list.empty(); lex->select_lex.init_order(); - lex->like_name= 0; lex->select_lex.db= ((TABLE_LIST*) lex->select_lex.table_list.first)->db; bzero((char*) &lex->create_info,sizeof(lex->create_info)); From a53b80b3f3f187370d3360202b7849856ab9582a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 May 2007 17:32:40 +0500 Subject: [PATCH 25/74] Bug#27636 mysqlbinlog-cp932 and ctype_cp932 tests fails if LC_* variables set to *_*.UTF-8 As MySQL character set tests can print results in many character sets (latin1, utf8-8, sjis, cp932 and others) - its output can be incompatible with the current locale settings, which makes PERL confuse. Fix: reset LC_ALL and LC_CTYPE to "C", which is compatible with any character set. mysql-test/mysql-test-run.pl: Ignore current locale settings, because "mysqltest" output can be not compatible with the locale. --- mysql-test/mysql-test-run.pl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index b48ac6c5abc..cbd7ccd5bbd 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1792,6 +1792,18 @@ sub environment_setup () { $ENV{'CHARSETSDIR'}= $path_charsetsdir; $ENV{'UMASK'}= "0660"; # The octal *string* $ENV{'UMASK_DIR'}= "0770"; # The octal *string* + + # + # MySQL tests can produce output in various character sets + # (especially, ctype_xxx.test). To avoid confusing Perl + # with output which is incompatible with the current locale + # settings, we reset the current values of LC_ALL and LC_CTYPE to "C". + # For details, please see + # Bug#27636 tests fails if LC_* variables set to *_*.UTF-8 + # + $ENV{'LC_ALL'}= "C"; + $ENV{'LC_CTYPE'}= "C"; + $ENV{'LC_COLLATE'}= "C"; $ENV{'USE_RUNNING_SERVER'}= $opt_extern; $ENV{'MYSQL_TEST_DIR'}= $glob_mysql_test_dir; From 1632586e20205ad1ed6ac5b865b6164a7be333ee Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 May 2007 13:11:45 +0200 Subject: [PATCH 26/74] Bug#28644 Memory status report confused with memory leak This patch removes a false memory leak error report from the test suite. There is a test case that puposely provokes a SAFEMALLOC leak report, even though there is no actual leak. mysql-test/lib/mtr_report.pl: There is a test case that purposely provokes a SAFEMALLOC leak report, even though there is no actual leak. We need to detect this, and ignore the warning in that case. sql/sql_test.cc: Added tags to surround memory dump status report to help the test suite to determine that this isn't a memory leak --- mysql-test/lib/mtr_report.pl | 14 ++++++++++++++ sql/sql_test.cc | 2 ++ 2 files changed, 16 insertions(+) diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index a2c16e1941a..cd24610f9c0 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -261,8 +261,19 @@ sub mtr_report_stats ($) { mtr_warning("can't read $errlog"); next; } + my $leak_reports_expected= undef; while ( ) { + # There is a test case that purposely provokes a + # SAFEMALLOC leak report, even though there is no actual + # leak. We need to detect this, and ignore the warning in + # that case. + if (/Begin safemalloc memory dump:/) { + $leak_reports_expected= 1; + } elsif (/End safemalloc memory dump./) { + $leak_reports_expected= undef; + } + # Skip some non fatal warnings from the log files if ( /Warning:\s+Table:.* on (delete|rename)/ or /Warning:\s+Setting lower_case_table_names=2/ or @@ -273,6 +284,9 @@ sub mtr_report_stats ($) { } if ( /$pattern/ ) { + if ($leak_reports_expected) { + next; + } $found_problems= 1; print WARN $_; } diff --git a/sql/sql_test.cc b/sql/sql_test.cc index d6afc888be2..e73fd03426a 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -406,7 +406,9 @@ Next alarm time: %lu\n", if (thd) thd->proc_info="malloc"; my_checkmalloc(); + fprintf(stdout,"\nBegin safemalloc memory dump:\n"); // tag needed for test suite TERMINATE(stdout); // Write malloc information + fprintf(stdout,"\nEnd safemalloc memory dump.\n"); #ifdef HAVE_MALLINFO struct mallinfo info= mallinfo(); From bcb1ff7f4833272dfb9fbd8809089827d156bdab Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 24 May 2007 22:13:49 +0200 Subject: [PATCH 27/74] This changeset belongs to the fix of Bug#735 Prepared Statements: there is no support for Query Cache - Create "--ps-protocol" and no "---protocol" variants of the former tests t/grant_cache.test and t/query_cache_sql_prepare.test. - Some additional subtest and fixes of bugs - Minor improvements mysql-test/include/grant_cache.inc: - Rename mysql-test/t/grant_cache.test to include/grant_cache.inc - Toplevel scripts running variants of this test are t/grant_cache_ps_prot.test (runs only with "--ps-protocol") t/grant_cache_no_prot.test (skipped if any protocol is assigned) - Modifications to include/grant_cache.inc: - Minor improvements like replace --error by --error - enable that some subtests are run with "--ps-protocol" mysql-test/include/query_cache_sql_prepare.inc: - Rename t/query_cache_sql_prepare.test to include/query_cache_sql_prepare.inc - Toplevel scripts running variants of this test are query_cache_ps_ps_prot.test (skipped if other protocol than --ps-protocol is used.) query_cache_ps_no_prot.test (skipped if ---protocol is used) - Modifications to include/query_cache_sql_prepare.inc: - Minor improvements like add drop table - Add tests checking that - another connection gets the same amount of QC hits - statements running via ps-protocol do not hit QC results of preceding sql EXECUTEs mysql-test/r/grant_cache_no_prot.result: Updated result mysql-test/r/query_cache_ps_no_prot.result: Updated result tests/mysql_client_test.c: - correct wrong sized "for" loop - add some missing tests of query cache hit numbers mysql-test/r/grant_cache_ps_prot.result: New BitKeeper file ``mysql-test/r/grant_cache_ps_prot.result'' mysql-test/r/query_cache_ps_ps_prot.result: New BitKeeper file ``mysql-test/r/query_cache_ps_ps_prot.result'' mysql-test/t/grant_cache_no_prot.test: Variant of the test grant_cache to be run without any "---protocol" mysql-test/t/grant_cache_ps_prot.test: Variant of the test grant_cache to be run with "--ps-protocol" only mysql-test/t/query_cache_ps_no_prot.test: Variant of the test query_cache_sql_prepare to be run without any "---protocol" mysql-test/t/query_cache_ps_ps_prot.test: Variant of the test query_cache_sql_prepare to be run with "--ps-protocol" only --- .../grant_cache.inc} | 100 +++-- .../include/query_cache_sql_prepare.inc | 271 +++++++++++++ ...ache.result => grant_cache_no_prot.result} | 8 + mysql-test/r/grant_cache_ps_prot.result | 218 +++++++++++ mysql-test/r/query_cache_ps_no_prot.result | 362 ++++++++++++++++++ mysql-test/r/query_cache_ps_ps_prot.result | 362 ++++++++++++++++++ mysql-test/r/query_cache_sql_prepare.result | 204 ---------- mysql-test/t/grant_cache_no_prot.test | 25 ++ mysql-test/t/grant_cache_ps_prot.test | 24 ++ mysql-test/t/query_cache_ps_no_prot.test | 26 ++ mysql-test/t/query_cache_ps_ps_prot.test | 25 ++ mysql-test/t/query_cache_sql_prepare.test | 146 ------- tests/mysql_client_test.c | 6 +- 13 files changed, 1384 insertions(+), 393 deletions(-) rename mysql-test/{t/grant_cache.test => include/grant_cache.inc} (64%) create mode 100644 mysql-test/include/query_cache_sql_prepare.inc rename mysql-test/r/{grant_cache.result => grant_cache_no_prot.result} (92%) create mode 100644 mysql-test/r/grant_cache_ps_prot.result create mode 100644 mysql-test/r/query_cache_ps_no_prot.result create mode 100644 mysql-test/r/query_cache_ps_ps_prot.result delete mode 100644 mysql-test/r/query_cache_sql_prepare.result create mode 100644 mysql-test/t/grant_cache_no_prot.test create mode 100644 mysql-test/t/grant_cache_ps_prot.test create mode 100644 mysql-test/t/query_cache_ps_no_prot.test create mode 100644 mysql-test/t/query_cache_ps_ps_prot.test delete mode 100644 mysql-test/t/query_cache_sql_prepare.test diff --git a/mysql-test/t/grant_cache.test b/mysql-test/include/grant_cache.inc similarity index 64% rename from mysql-test/t/grant_cache.test rename to mysql-test/include/grant_cache.inc index 10e571fc5f5..dd65d1ed726 100644 --- a/mysql-test/t/grant_cache.test +++ b/mysql-test/include/grant_cache.inc @@ -1,13 +1,42 @@ -# Grant tests not performed with embedded server --- source include/not_embedded.inc --- source include/have_query_cache.inc -# See at the end of the test why we disable the ps protocol (*) --- disable_ps_protocol +################### include/grant_cache.inc #################### +# +# Test grants with query cache +# +# Last update: +# 2007-05-03 ML - Move t/grant_cache.test to include/grant_cache.inc +# - Remove the disabling of the ps-protocol +# - minor improvements like error names instead of numbers +# - Create two toplevel tests sourcing this routine +# +# Running this test with and without "--ps-protocol" produces different +# Qcache_not_cached results because of the following reason: +# In normal protocol, a SELECT failing due to insufficient privileges +# increments Qcache_not_cached, while in ps-protocol, no. +# In detail: +# - In normal protocol, +# the "access denied" errors on SELECT are issued at (stack trace): +# mysql_parse/mysql_execute_command/execute_sqlcom_select/handle_select/ +# mysql_select/JOIN::prepare/setup_wild/insert_fields/ +# check_grant_all_columns/my_error/my_message_sql, which then calls +# push_warning/query_cache_abort: at this moment, +# query_cache_store_query() has been called, so query exists in cache, +# so thd->net.query_cache_query!=NULL, so query_cache_abort() removes +# the query from cache, which causes a query_cache.refused++ (thus, +# a Qcache_not_cached++). +# - In ps-protocol, +# the error is issued at prepare time; +# for this mysql_test_select() is called, not execute_sqlcom_select() +# (and that also leads to JOIN::prepare/etc). Thus, as +# query_cache_store_query() has not been called, +# thd->net.query_cache_query==NULL, so query_cache_abort() does nothing: +# Qcache_not_cached is not incremented. +# +# A run of this tests with sp/cursor/view protocol does not make sense +# because these protocols serve totally different purposes than this test. +# --source include/add_anonymous_users.inc -# -# Test grants with query cache # --disable_warnings drop table if exists test.t1,mysqltest.t1,mysqltest.t2; @@ -18,6 +47,7 @@ set GLOBAL query_cache_size=1355776; reset query cache; flush status; +--echo ----- establish connection root ----- connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connection root; show grants for current_user; @@ -33,6 +63,7 @@ insert into mysqltest.t2 values (3,3,3); create table test.t1 (a char (10)); insert into test.t1 values ("test.t1"); select * from t1; +--echo ----- establish connection root2 ----- connect (root2,localhost,root,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK); connection root2; # put queries in cache @@ -51,6 +82,7 @@ grant SELECT on test.t1 to mysqltest_2@localhost; grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost; # The following queries should be fetched from cache +--echo ----- establish connection user1 (user=mysqltest_1) ----- connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK); connection user1; show grants for current_user(); @@ -76,12 +108,14 @@ show status like "Qcache_hits"; show status like "Qcache_not_cached"; +--echo ----- establish connection unkuser (user=unkuser) ----- # Don't use '' as user because it will pick Unix login connect (unkuser,localhost,unkuser,,,$MASTER_MYPORT,$MASTER_MYSOCK); connection unkuser; show grants for current_user(); # The following queries should be fetched from cache +--echo ----- establish connection user2 (user=mysqltest_2) ----- connect (user2,localhost,mysqltest_2,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK); connection user2; select "user2"; @@ -90,39 +124,41 @@ select a from t1; select c from t1; select * from mysqltest.t1,test.t1; --replace_result 127.0.0.1 localhost ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR select * from t2; show status like "Qcache_queries_in_cache"; show status like "Qcache_hits"; show status like "Qcache_not_cached"; # The following queries should not be fetched from cache +--echo ----- establish connection user3 (user=mysqltest_3) ----- connect (user3,localhost,mysqltest_3,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK); connection user3; select "user3"; --replace_result 127.0.0.1 localhost ---error 1143 +--error ER_COLUMNACCESS_DENIED_ERROR select * from t1; select a from t1; --replace_result 127.0.0.1 localhost ---error 1143 +--error ER_COLUMNACCESS_DENIED_ERROR select c from t1; --replace_result 127.0.0.1 localhost ---error 1142 +--error ER_TABLEACCESS_DENIED_ERROR select * from t2; --replace_result 127.0.0.1 localhost ---error 1143 +--error ER_COLUMNACCESS_DENIED_ERROR select mysqltest.t1.c from test.t1,mysqltest.t1; show status like "Qcache_queries_in_cache"; show status like "Qcache_hits"; show status like "Qcache_not_cached"; # Connect without a database +--echo ----- establish connection user4 (user=mysqltest_1) ----- connect (user4,localhost,mysqltest_1,,*NO-ONE*,$MASTER_MYPORT,$MASTER_MYSOCK); connection user4; select "user4"; show grants; ---error 1046 +--error ER_NO_DB_ERROR select a from t1; # The following query is not cached before (different database) select * from mysqltest.t1,test.t1; @@ -135,7 +171,16 @@ show status like "Qcache_not_cached"; # Cleanup -connection root; +--echo ----- switch to connection default and close connections ----- +connection default; +disconnect root; +disconnect root2; +disconnect user1; +disconnect user2; +disconnect user3; +disconnect user4; +disconnect unkuser; + # # A temporary 4.1 workaround to make this test pass if # mysql was compiled with other than latin1 --with-charset=XXX. @@ -156,30 +201,3 @@ drop database mysqltest; set GLOBAL query_cache_size=default; --source include/delete_anonymous_users.inc - - -# End of 4.1 tests - -# (*) Why we disable the ps protocol: because in normal protocol, -# a SELECT failing due to insufficient privileges increments -# Qcache_not_cached, while in ps-protocol, no. -# In detail: in normal protocol, -# the "access denied" errors on SELECT are issued at (stack trace): -# mysql_parse/mysql_execute_command/execute_sqlcom_select/handle_select/ -# mysql_select/JOIN::prepare/setup_wild/insert_fields/ -# check_grant_all_columns/my_error/my_message_sql, which then calls -# push_warning/query_cache_abort: at this moment, -# query_cache_store_query() has been called, so query exists in cache, -# so thd->net.query_cache_query!=NULL, so query_cache_abort() removes -# the query from cache, which causes a query_cache.refused++ (thus, -# a Qcache_not_cached++). -# While in ps-protocol, the error is issued at prepare time; -# for this mysql_test_select() is called, not execute_sqlcom_select() -# (and that also leads to JOIN::prepare/etc). Thus, as -# query_cache_store_query() has not been called, -# thd->net.query_cache_query==NULL, so query_cache_abort() does nothing: -# Qcache_not_cached is not incremented. -# As this test prints Qcache_not_cached after SELECT failures, -# we cannot enable this test in ps-protocol. - ---enable_ps_protocol diff --git a/mysql-test/include/query_cache_sql_prepare.inc b/mysql-test/include/query_cache_sql_prepare.inc new file mode 100644 index 00000000000..cdb3bd586e7 --- /dev/null +++ b/mysql-test/include/query_cache_sql_prepare.inc @@ -0,0 +1,271 @@ +############### include/query_cache_sql_prepare.inc ################ +# +# This is to see how statements prepared via the PREPARE SQL command +# go into the query cache: if using parameters they cannot; if not +# using parameters they can. +# Query cache is abbreviated as "QC" +# +# Last update: +# 2007-05-03 ML - Move t/query_cache_sql_prepare.test +# to include/query_cache_sql_prepare.inc +# - Create two toplevel tests sourcing this routine +# - Add tests checking that +# - another connection gets the same amount of QC hits +# - statements running via ps-protocol do not hit QC results +# of preceding sql EXECUTEs +# + +--source include/have_query_cache.inc +# embedded can't make more than one connection, which this test needs +-- source include/not_embedded.inc + +--echo ---- establish connection con1 (root) ---- +connect (con1,localhost,root,,test,$MASTER_MYPORT,); +--echo ---- switch to connection default ---- +connection default; + +set @initial_query_cache_size = @@global.query_cache_size; +set @@global.query_cache_size=100000; +flush status; +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1(c1 int); +insert into t1 values(1),(10),(100); + +# Prepared statements has no parameters, query caching should happen +prepare stmt1 from "select * from t1 where c1=10"; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +# Another prepared statement (same text, same connection), should hit the QC +prepare stmt2 from "select * from t1 where c1=10"; +execute stmt2; +show status like 'Qcache_hits'; +execute stmt2; +show status like 'Qcache_hits'; +execute stmt2; +show status like 'Qcache_hits'; +# Another prepared statement (same text, other connection), should hit the QC +--echo ---- switch to connection con1 ---- +connection con1; +prepare stmt3 from "select * from t1 where c1=10"; +execute stmt3; +show status like 'Qcache_hits'; +execute stmt3; +show status like 'Qcache_hits'; +execute stmt3; +show status like 'Qcache_hits'; +--echo ---- switch to connection default ---- +connection default; + +# Mixup tests, where statements without PREPARE.../EXECUTE.... meet statements +# with PREPARE.../EXECUTE.... (text protocol). Both statements have the +# same text. QC hits occur only when both statements use the same protocol. +# The outcome of the test depends on the mysqltest startup options +# - with "--ps-protocol" +# Statements without PREPARE.../EXECUTE.... run as prepared statements +# with binary protocol. Expect to get no QC hits. +# - without any "---protocol" +# Statements without PREPARE.../EXECUTE run as non prepared statements +# with text protocol. Expect to get QC hits. +############################################################################ +# +# Statement with PREPARE.../EXECUTE.... first +let $my_stmt= SELECT * FROM t1 WHERE c1 = 100; +eval prepare stmt10 from "$my_stmt"; +show status like 'Qcache_hits'; +execute stmt10; +show status like 'Qcache_hits'; +execute stmt10; +show status like 'Qcache_hits'; +eval $my_stmt; +show status like 'Qcache_hits'; +--echo ---- switch to connection con1 ---- +connection con1; +eval $my_stmt; +show status like 'Qcache_hits'; +--echo ---- switch to connection default ---- +connection default; +# +# Statement without PREPARE.../EXECUTE.... first +let $my_stmt= SELECT * FROM t1 WHERE c1 = 1; +eval prepare stmt11 from "$my_stmt"; +--echo ---- switch to connection con1 ---- +connection con1; +eval prepare stmt12 from "$my_stmt"; +--echo ---- switch to connection default ---- +connection default; +eval $my_stmt; +show status like 'Qcache_hits'; +eval $my_stmt; +show status like 'Qcache_hits'; +execute stmt11; +show status like 'Qcache_hits'; +--echo ---- switch to connection con1 ---- +connection con1; +execute stmt12; +show status like 'Qcache_hits'; +--echo ---- switch to connection default ---- +connection default; + +# Prepared statement has parameters, query caching should not happen +prepare stmt1 from "select * from t1 where c1=?"; +show status like 'Qcache_hits'; +set @a=1; +execute stmt1 using @a; +show status like 'Qcache_hits'; +execute stmt1 using @a; +show status like 'Qcache_hits'; +--echo ---- switch to connection con1 ---- +connection con1; +set @a=1; +prepare stmt4 from "select * from t1 where c1=?"; +execute stmt4 using @a; +show status like 'Qcache_hits'; +--echo ---- switch to connection default ---- +connection default; + +# See if enabling/disabling the query cache between PREPARE and +# EXECUTE is an issue; the expected result is that the query cache +# will not be used. +# Indeed, decision to read/write the query cache is taken at PREPARE +# time, so if the query cache was disabled at PREPARE time then no +# execution of the statement will read/write the query cache. +# If the query cache was enabled at PREPARE time, but disabled at +# EXECUTE time, at EXECUTE time the query cache internal functions do +# nothing so again the query cache is not read/written. But if the +# query cache is re-enabled before another execution then that +# execution will read/write the query cache. + +# QC is enabled at PREPARE +prepare stmt1 from "select * from t1 where c1=10"; +# then QC is disabled at EXECUTE +# Expect to see no additional Qcache_hits. +set global query_cache_size=0; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +# The QC is global = affects also other connections. +# Expect to see no additional Qcache_hits. +--echo ---- switch to connection con1 ---- +connection con1; +execute stmt3; +show status like 'Qcache_hits'; +execute stmt3; +show status like 'Qcache_hits'; +execute stmt3; +show status like 'Qcache_hits'; +# +# then QC is re-enabled for more EXECUTE. +--echo ---- switch to connection default ---- +connection default; +set global query_cache_size=100000; +# Expect to see additional Qcache_hits. +# The fact that the QC was temporary disabled should have no affect +# except that the first execute will not hit results from the +# beginning of the test (because QC has been emptied meanwhile by +# setting its size to 0). +execute stmt1; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +# The QC is global = affects also other connections. +--echo ---- switch to connection con1 ---- +connection con1; +execute stmt3; +show status like 'Qcache_hits'; +execute stmt3; +show status like 'Qcache_hits'; +execute stmt3; +show status like 'Qcache_hits'; +--echo ---- switch to connection default ---- +connection default; +# +# then QC is re-disabled for more EXECUTE. +# Expect to see no additional Qcache_hits. +# The fact that the QC was temporary enabled should have no affect. +set global query_cache_size=0; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +# The QC is global = affects also other connections. +--echo ---- switch to connection con1 ---- +connection con1; +execute stmt3; +show status like 'Qcache_hits'; +execute stmt3; +show status like 'Qcache_hits'; +execute stmt3; +show status like 'Qcache_hits'; +# + +--echo ---- switch to connection default ---- +connection default; +# QC is disabled at PREPARE +set global query_cache_size=0; +prepare stmt1 from "select * from t1 where c1=10"; +--echo ---- switch to connection con1 ---- +connection con1; +prepare stmt3 from "select * from t1 where c1=10"; +--echo ---- switch to connection default ---- +connection default; +# then QC is enabled at EXECUTE +set global query_cache_size=100000; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +execute stmt1; +show status like 'Qcache_hits'; +# The QC is global = affects also other connections. +--echo ---- switch to connection con1 ---- +connection con1; +show status like 'Qcache_hits'; +execute stmt3; +show status like 'Qcache_hits'; +execute stmt3; +show status like 'Qcache_hits'; +execute stmt3; +show status like 'Qcache_hits'; +--echo ---- switch to connection default ---- +connection default; +# +# QC is disabled at PREPARE +set global query_cache_size=0; +prepare stmt1 from "select * from t1 where c1=?"; +# then QC is enabled at EXECUTE +set global query_cache_size=100000; +show status like 'Qcache_hits'; +set @a=1; +execute stmt1 using @a; +show status like 'Qcache_hits'; +set @a=100; +execute stmt1 using @a; +show status like 'Qcache_hits'; +set @a=10; +execute stmt1 using @a; +show status like 'Qcache_hits'; + + +drop table t1; +--echo ---- disconnect connection con1 ---- +disconnect con1; + +set @@global.query_cache_size=@initial_query_cache_size; +flush status; # reset Qcache status variables for next tests diff --git a/mysql-test/r/grant_cache.result b/mysql-test/r/grant_cache_no_prot.result similarity index 92% rename from mysql-test/r/grant_cache.result rename to mysql-test/r/grant_cache_no_prot.result index 2c6840d77d0..02360c4c325 100644 --- a/mysql-test/r/grant_cache.result +++ b/mysql-test/r/grant_cache_no_prot.result @@ -3,6 +3,7 @@ drop database if exists mysqltest; set GLOBAL query_cache_size=1355776; reset query cache; flush status; +----- establish connection root ----- show grants for current_user; Grants for root@localhost GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION @@ -19,6 +20,7 @@ insert into test.t1 values ("test.t1"); select * from t1; a test.t1 +----- establish connection root2 ----- select * from t1; a b c 1 1 1 @@ -48,6 +50,7 @@ grant SELECT on mysqltest.* to mysqltest_1@localhost; grant SELECT on mysqltest.t1 to mysqltest_2@localhost; grant SELECT on test.t1 to mysqltest_2@localhost; grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost; +----- establish connection user1 (user=mysqltest_1) ----- show grants for current_user(); Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' @@ -112,9 +115,11 @@ Qcache_hits 3 show status like "Qcache_not_cached"; Variable_name Value Qcache_not_cached 1 +----- establish connection unkuser (user=unkuser) ----- show grants for current_user(); Grants for @localhost GRANT USAGE ON *.* TO ''@'localhost' +----- establish connection user2 (user=mysqltest_2) ----- select "user2"; user2 user2 @@ -145,6 +150,7 @@ Qcache_hits 7 show status like "Qcache_not_cached"; Variable_name Value Qcache_not_cached 2 +----- establish connection user3 (user=mysqltest_3) ----- select "user3"; user3 user3 @@ -169,6 +175,7 @@ Qcache_hits 7 show status like "Qcache_not_cached"; Variable_name Value Qcache_not_cached 7 +----- establish connection user4 (user=mysqltest_1) ----- select "user4"; user4 user4 @@ -199,6 +206,7 @@ Qcache_hits 8 show status like "Qcache_not_cached"; Variable_name Value Qcache_not_cached 8 +----- switch to connection default and close connections ----- set names binary; delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); diff --git a/mysql-test/r/grant_cache_ps_prot.result b/mysql-test/r/grant_cache_ps_prot.result new file mode 100644 index 00000000000..1e2cd1baa3a --- /dev/null +++ b/mysql-test/r/grant_cache_ps_prot.result @@ -0,0 +1,218 @@ +drop table if exists test.t1,mysqltest.t1,mysqltest.t2; +drop database if exists mysqltest; +set GLOBAL query_cache_size=1355776; +reset query cache; +flush status; +----- establish connection root ----- +show grants for current_user; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +show grants; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +create database if not exists mysqltest; +create table mysqltest.t1 (a int,b int,c int); +create table mysqltest.t2 (a int,b int,c int); +insert into mysqltest.t1 values (1,1,1),(2,2,2); +insert into mysqltest.t2 values (3,3,3); +create table test.t1 (a char (10)); +insert into test.t1 values ("test.t1"); +select * from t1; +a +test.t1 +----- establish connection root2 ----- +select * from t1; +a b c +1 1 1 +2 2 2 +select a from t1; +a +1 +2 +select c from t1; +c +1 +2 +select * from t2; +a b c +3 3 3 +select * from mysqltest.t1,test.t1; +a b c a +1 1 1 test.t1 +2 2 2 test.t1 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits%"; +Variable_name Value +Qcache_hits 0 +grant SELECT on mysqltest.* to mysqltest_1@localhost; +grant SELECT on mysqltest.t1 to mysqltest_2@localhost; +grant SELECT on test.t1 to mysqltest_2@localhost; +grant SELECT(a) on mysqltest.t1 to mysqltest_3@localhost; +----- establish connection user1 (user=mysqltest_1) ----- +show grants for current_user(); +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 0 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 0 +select "user1"; +user1 +user1 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 0 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 1 +select * from t1; +a b c +1 1 1 +2 2 2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 1 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 1 +select a from t1 ; +a +1 +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 2 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 1 +select c from t1; +c +1 +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 3 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 1 +----- establish connection unkuser (user=unkuser) ----- +show grants for current_user(); +Grants for @localhost +GRANT USAGE ON *.* TO ''@'localhost' +----- establish connection user2 (user=mysqltest_2) ----- +select "user2"; +user2 +user2 +select * from t1; +a b c +1 1 1 +2 2 2 +select a from t1; +a +1 +2 +select c from t1; +c +1 +2 +select * from mysqltest.t1,test.t1; +a b c a +1 1 1 test.t1 +2 2 2 test.t1 +select * from t2; +ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 't2' +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 7 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 2 +----- establish connection user3 (user=mysqltest_3) ----- +select "user3"; +user3 +user3 +select * from t1; +ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'b' in table 't1' +select a from t1; +a +1 +2 +select c from t1; +ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'c' in table 't1' +select * from t2; +ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for table 't2' +select mysqltest.t1.c from test.t1,mysqltest.t1; +ERROR 42000: SELECT command denied to user 'mysqltest_3'@'localhost' for column 'c' in table 't1' +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 7 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 4 +----- establish connection user4 (user=mysqltest_1) ----- +select "user4"; +user4 +user4 +show grants; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' +select a from t1; +ERROR 3D000: No database selected +select * from mysqltest.t1,test.t1; +a b c a +1 1 1 test.t1 +2 2 2 test.t1 +select a from mysqltest.t1; +a +1 +2 +select a from mysqltest.t1; +a +1 +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 8 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 8 +show status like "Qcache_not_cached"; +Variable_name Value +Qcache_not_cached 5 +----- switch to connection default and close connections ----- +set names binary; +delete from mysql.user where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +delete from mysql.db where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +delete from mysql.tables_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +delete from mysql.columns_priv where user in ("mysqltest_1","mysqltest_2","mysqltest_3"); +flush privileges; +drop table test.t1,mysqltest.t1,mysqltest.t2; +drop database mysqltest; +set GLOBAL query_cache_size=default; diff --git a/mysql-test/r/query_cache_ps_no_prot.result b/mysql-test/r/query_cache_ps_no_prot.result new file mode 100644 index 00000000000..bf162439918 --- /dev/null +++ b/mysql-test/r/query_cache_ps_no_prot.result @@ -0,0 +1,362 @@ +---- establish connection con1 (root) ---- +---- switch to connection default ---- +set @initial_query_cache_size = @@global.query_cache_size; +set @@global.query_cache_size=100000; +flush status; +drop table if exists t1; +create table t1(c1 int); +insert into t1 values(1),(10),(100); +prepare stmt1 from "select * from t1 where c1=10"; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 0 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 0 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 1 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 2 +prepare stmt2 from "select * from t1 where c1=10"; +execute stmt2; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 3 +execute stmt2; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 4 +execute stmt2; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 5 +---- switch to connection con1 ---- +prepare stmt3 from "select * from t1 where c1=10"; +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 6 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 7 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 8 +---- switch to connection default ---- +prepare stmt10 from "SELECT * FROM t1 WHERE c1 = 100"; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 8 +execute stmt10; +c1 +100 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 8 +execute stmt10; +c1 +100 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 9 +SELECT * FROM t1 WHERE c1 = 100; +c1 +100 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 10 +---- switch to connection con1 ---- +SELECT * FROM t1 WHERE c1 = 100; +c1 +100 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 11 +---- switch to connection default ---- +prepare stmt11 from "SELECT * FROM t1 WHERE c1 = 1"; +---- switch to connection con1 ---- +prepare stmt12 from "SELECT * FROM t1 WHERE c1 = 1"; +---- switch to connection default ---- +SELECT * FROM t1 WHERE c1 = 1; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 11 +SELECT * FROM t1 WHERE c1 = 1; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +execute stmt11; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 13 +---- switch to connection con1 ---- +execute stmt12; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +---- switch to connection default ---- +prepare stmt1 from "select * from t1 where c1=?"; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +set @a=1; +execute stmt1 using @a; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +execute stmt1 using @a; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +---- switch to connection con1 ---- +set @a=1; +prepare stmt4 from "select * from t1 where c1=?"; +execute stmt4 using @a; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +---- switch to connection default ---- +prepare stmt1 from "select * from t1 where c1=10"; +set global query_cache_size=0; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +---- switch to connection con1 ---- +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +---- switch to connection default ---- +set global query_cache_size=100000; +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 15 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 16 +---- switch to connection con1 ---- +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 18 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +---- switch to connection default ---- +set global query_cache_size=0; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +---- switch to connection con1 ---- +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +---- switch to connection default ---- +set global query_cache_size=0; +prepare stmt1 from "select * from t1 where c1=10"; +---- switch to connection con1 ---- +prepare stmt3 from "select * from t1 where c1=10"; +---- switch to connection default ---- +set global query_cache_size=100000; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +---- switch to connection con1 ---- +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +---- switch to connection default ---- +set global query_cache_size=0; +prepare stmt1 from "select * from t1 where c1=?"; +set global query_cache_size=100000; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +set @a=1; +execute stmt1 using @a; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +set @a=100; +execute stmt1 using @a; +c1 +100 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +set @a=10; +execute stmt1 using @a; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 19 +drop table t1; +---- disconnect connection con1 ---- +set @@global.query_cache_size=@initial_query_cache_size; +flush status; diff --git a/mysql-test/r/query_cache_ps_ps_prot.result b/mysql-test/r/query_cache_ps_ps_prot.result new file mode 100644 index 00000000000..56aeda4a253 --- /dev/null +++ b/mysql-test/r/query_cache_ps_ps_prot.result @@ -0,0 +1,362 @@ +---- establish connection con1 (root) ---- +---- switch to connection default ---- +set @initial_query_cache_size = @@global.query_cache_size; +set @@global.query_cache_size=100000; +flush status; +drop table if exists t1; +create table t1(c1 int); +insert into t1 values(1),(10),(100); +prepare stmt1 from "select * from t1 where c1=10"; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 0 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 0 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 1 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 2 +prepare stmt2 from "select * from t1 where c1=10"; +execute stmt2; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 3 +execute stmt2; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 4 +execute stmt2; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 5 +---- switch to connection con1 ---- +prepare stmt3 from "select * from t1 where c1=10"; +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 6 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 7 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 8 +---- switch to connection default ---- +prepare stmt10 from "SELECT * FROM t1 WHERE c1 = 100"; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 8 +execute stmt10; +c1 +100 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 8 +execute stmt10; +c1 +100 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 9 +SELECT * FROM t1 WHERE c1 = 100; +c1 +100 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 9 +---- switch to connection con1 ---- +SELECT * FROM t1 WHERE c1 = 100; +c1 +100 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 10 +---- switch to connection default ---- +prepare stmt11 from "SELECT * FROM t1 WHERE c1 = 1"; +---- switch to connection con1 ---- +prepare stmt12 from "SELECT * FROM t1 WHERE c1 = 1"; +---- switch to connection default ---- +SELECT * FROM t1 WHERE c1 = 1; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 10 +SELECT * FROM t1 WHERE c1 = 1; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 11 +execute stmt11; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 11 +---- switch to connection con1 ---- +execute stmt12; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +---- switch to connection default ---- +prepare stmt1 from "select * from t1 where c1=?"; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +set @a=1; +execute stmt1 using @a; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +execute stmt1 using @a; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +---- switch to connection con1 ---- +set @a=1; +prepare stmt4 from "select * from t1 where c1=?"; +execute stmt4 using @a; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +---- switch to connection default ---- +prepare stmt1 from "select * from t1 where c1=10"; +set global query_cache_size=0; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +---- switch to connection con1 ---- +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +---- switch to connection default ---- +set global query_cache_size=100000; +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 12 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 13 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 14 +---- switch to connection con1 ---- +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 15 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 16 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +---- switch to connection default ---- +set global query_cache_size=0; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +---- switch to connection con1 ---- +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +---- switch to connection default ---- +set global query_cache_size=0; +prepare stmt1 from "select * from t1 where c1=10"; +---- switch to connection con1 ---- +prepare stmt3 from "select * from t1 where c1=10"; +---- switch to connection default ---- +set global query_cache_size=100000; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt1; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +---- switch to connection con1 ---- +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +execute stmt3; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +---- switch to connection default ---- +set global query_cache_size=0; +prepare stmt1 from "select * from t1 where c1=?"; +set global query_cache_size=100000; +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +set @a=1; +execute stmt1 using @a; +c1 +1 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +set @a=100; +execute stmt1 using @a; +c1 +100 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +set @a=10; +execute stmt1 using @a; +c1 +10 +show status like 'Qcache_hits'; +Variable_name Value +Qcache_hits 17 +drop table t1; +---- disconnect connection con1 ---- +set @@global.query_cache_size=@initial_query_cache_size; +flush status; diff --git a/mysql-test/r/query_cache_sql_prepare.result b/mysql-test/r/query_cache_sql_prepare.result deleted file mode 100644 index 64af5bc4ec2..00000000000 --- a/mysql-test/r/query_cache_sql_prepare.result +++ /dev/null @@ -1,204 +0,0 @@ -set global query_cache_size=100000; -flush status; -create table t1(c1 int); -insert into t1 values(1),(10),(100); -prepare stmt1 from "select * from t1 where c1=10"; -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 0 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 0 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 1 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 2 -prepare stmt2 from "select * from t1 where c1=10"; -execute stmt2; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 3 -execute stmt2; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 4 -execute stmt2; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 5 -prepare stmt3 from "select * from t1 where c1=10"; -execute stmt3; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 6 -execute stmt3; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 7 -execute stmt3; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 8 -select * from t1 where c1=10; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 9 -flush tables; -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 9 -select * from t1 where c1=10; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 10 -prepare stmt1 from "select * from t1 where c1=?"; -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 10 -set @a=1; -execute stmt1 using @a; -c1 -1 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 10 -set @a=100; -execute stmt1 using @a; -c1 -100 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 10 -set @a=10; -execute stmt1 using @a; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 10 -prepare stmt1 from "select * from t1 where c1=10"; -set global query_cache_size=0; -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 10 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 10 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 10 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 10 -set global query_cache_size=100000; -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 10 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 11 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -set global query_cache_size=0; -prepare stmt1 from "select * from t1 where c1=10"; -set global query_cache_size=100000; -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -execute stmt1; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -set global query_cache_size=0; -prepare stmt1 from "select * from t1 where c1=?"; -set global query_cache_size=100000; -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -set @a=1; -execute stmt1 using @a; -c1 -1 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -set @a=100; -execute stmt1 using @a; -c1 -100 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -set @a=10; -execute stmt1 using @a; -c1 -10 -show status like 'Qcache_hits'; -Variable_name Value -Qcache_hits 12 -drop table t1; -set global query_cache_size=0; -flush status; diff --git a/mysql-test/t/grant_cache_no_prot.test b/mysql-test/t/grant_cache_no_prot.test new file mode 100644 index 00000000000..1f6a9aeb9ed --- /dev/null +++ b/mysql-test/t/grant_cache_no_prot.test @@ -0,0 +1,25 @@ +#################### t/grant_cache_no_prot.test ################### +# +# Test grants with query cache to be run when mysqltest was started +# without any "---protocol". +# +# Last update: +# 2007-05-03 ML - Move t/grant_cache.test to include/grant_cache.inc +# - Create this test as non "---protocol" variant. +# + +# We cannot run on embedded server because we use multiple sessions. +--source include/not_embedded.inc + +--source include/have_query_cache.inc + +# The file with expected results fits only to a run without +# ps-protocol/sp-protocol/cursor-protocol/view-protocol. +if (`SELECT $PS_PROTOCOL + $SP_PROTOCOL + $CURSOR_PROTOCOL + + $VIEW_PROTOCOL > 0`) +{ + --skip Test requires: ps-protocol/sp-protocol/cursor-protocol/view-protocol disabled +} + +# The main testing script +--source include/grant_cache.inc diff --git a/mysql-test/t/grant_cache_ps_prot.test b/mysql-test/t/grant_cache_ps_prot.test new file mode 100644 index 00000000000..7b579f869e9 --- /dev/null +++ b/mysql-test/t/grant_cache_ps_prot.test @@ -0,0 +1,24 @@ +#################### t/grant_cache_ps_prot.test ################## +# +# Test grants with query cache to be run when mysqltest was +# started with the option "--ps-protocol". +# +# Last update: +# 2007-05-03 ML - Move t/grant_cache.test to include/grant_cache.inc +# - Create this test as "--ps-protocol" only variant. +# + +# We cannot run on embedded server because we use multiple sessions. +--source include/not_embedded.inc + +--source include/have_query_cache.inc + +# The file with expected results fits only to a run with "--ps-protocol". +if (`SELECT $SP_PROTOCOL + $CURSOR_PROTOCOL + $VIEW_PROTOCOL > 0 + OR $PS_PROTOCOL = 0`) +{ + --skip Test requires: ps-protocol enabled, other protocols disabled +} + +# The main testing script +--source include/grant_cache.inc diff --git a/mysql-test/t/query_cache_ps_no_prot.test b/mysql-test/t/query_cache_ps_no_prot.test new file mode 100644 index 00000000000..6f4263eeef9 --- /dev/null +++ b/mysql-test/t/query_cache_ps_no_prot.test @@ -0,0 +1,26 @@ +#################### t/query_cache_ps_no_prot.test ##################### +# +# Test grants with query cache to be run when mysqltest was started +# without any "---protocol". +# +# Last update: +# 2007-05-03 ML - Move t/query_cache_sql_prepare.test to +# include/query_cache_sql_prepare.inc +# - Create this test as non "---protocol" variant. +# + +# We cannot run on embedded server because we use multiple sessions. +--source include/not_embedded.inc + +--source include/have_query_cache.inc + +# The file with expected results fits only to a run without +# ps-protocol/sp-protocol/cursor-protocol/view-protocol. +if (`SELECT $PS_PROTOCOL + $SP_PROTOCOL + $CURSOR_PROTOCOL + + $VIEW_PROTOCOL > 0`) +{ + --skip Test requires: ps-protocol/sp-protocol/cursor-protocol/view-protocol disabled +} + +# The main testing script +--source include/query_cache_sql_prepare.inc diff --git a/mysql-test/t/query_cache_ps_ps_prot.test b/mysql-test/t/query_cache_ps_ps_prot.test new file mode 100644 index 00000000000..dc49624788a --- /dev/null +++ b/mysql-test/t/query_cache_ps_ps_prot.test @@ -0,0 +1,25 @@ +#################### t/query_cache_ps_ps_prot.test ##################### +# +# Test grants with query cache to be run when mysqltest was started +# without any "---protocol". +# +# Last update: +# 2007-05-03 ML - Move t/query_cache_sql_prepare.test to +# include/query_cache_sql_prepare.inc +# - Create this test as "--ps-protocol" only variant. +# + +# We cannot run on embedded server because we use multiple sessions. +--source include/not_embedded.inc + +--source include/have_query_cache.inc + +# The file with expected results fits only to a run with "--ps-protocol". +if (`SELECT $SP_PROTOCOL + $CURSOR_PROTOCOL + $VIEW_PROTOCOL > 0 + OR $PS_PROTOCOL = 0`) +{ + --skip Test requires: ps-protocol enabled, other protocols disabled +} + +# The main testing script +--source include/query_cache_sql_prepare.inc diff --git a/mysql-test/t/query_cache_sql_prepare.test b/mysql-test/t/query_cache_sql_prepare.test deleted file mode 100644 index a02388b2ae5..00000000000 --- a/mysql-test/t/query_cache_sql_prepare.test +++ /dev/null @@ -1,146 +0,0 @@ -# This is to see how statements prepared via the PREPARE SQL command -# go into the query cache: if using parameters they cannot; if not -# using parameters they can. -# Query cache is abbreviated as "QC" - --- source include/have_query_cache.inc -# embedded can't make more than one connection, which this test needs --- source include/not_embedded.inc - -connect (con1,localhost,root,,test,$MASTER_MYPORT,); -connection default; - -set global query_cache_size=100000; -flush status; -create table t1(c1 int); -insert into t1 values(1),(10),(100); - -# Prepared statements has no parameters, query caching should happen -prepare stmt1 from "select * from t1 where c1=10"; -show status like 'Qcache_hits'; -execute stmt1; -show status like 'Qcache_hits'; -execute stmt1; -show status like 'Qcache_hits'; -execute stmt1; -show status like 'Qcache_hits'; -# Another prepared statement (same text, same connection), should hit the QC -prepare stmt2 from "select * from t1 where c1=10"; -execute stmt2; -show status like 'Qcache_hits'; -execute stmt2; -show status like 'Qcache_hits'; -execute stmt2; -show status like 'Qcache_hits'; -# Another prepared statement (same text, other connection), should hit the QC -connection con1; -prepare stmt3 from "select * from t1 where c1=10"; -execute stmt3; -show status like 'Qcache_hits'; -execute stmt3; -show status like 'Qcache_hits'; -execute stmt3; -show status like 'Qcache_hits'; -connection default; -# A non-prepared statement (same text, same connection), should hit -# the QC (as it uses the text protocol like SQL EXECUTE). -# But if it uses the binary protocol, it will not hit. So we make sure -# that it uses the text protocol: --- disable_ps_protocol -select * from t1 where c1=10; -show status like 'Qcache_hits'; - # A non-prepared statement (same text, other connection), should hit -# the QC. To test that it hits the result of SQL EXECUTE, we need to -# empty/repopulate the QC (to remove the result from the non-prepared -# SELECT just above). -flush tables; -execute stmt1; -show status like 'Qcache_hits'; -connection con1; -select * from t1 where c1=10; -show status like 'Qcache_hits'; --- enable_ps_protocol -connection default; - -# Prepared statement has parameters, query caching should not happen -prepare stmt1 from "select * from t1 where c1=?"; -show status like 'Qcache_hits'; -set @a=1; -execute stmt1 using @a; -show status like 'Qcache_hits'; -set @a=100; -execute stmt1 using @a; -show status like 'Qcache_hits'; -set @a=10; -execute stmt1 using @a; -show status like 'Qcache_hits'; - -# See if enabling/disabling the query cache between PREPARE and -# EXECUTE is an issue; the expected result is that the query cache -# will not be used. -# Indeed, decision to read/write the query cache is taken at PREPARE -# time, so if the query cache was disabled at PREPARE time then no -# execution of the statement will read/write the query cache. -# If the query cache was enabled at PREPARE time, but disabled at -# EXECUTE time, at EXECUTE time the query cache internal functions do -# nothing so again the query cache is not read/written. But if the -# query cache is re-enabled before another execution then that -# execution will read/write the query cache. - -# QC is enabled at PREPARE -prepare stmt1 from "select * from t1 where c1=10"; -# then QC is disabled at EXECUTE -set global query_cache_size=0; -show status like 'Qcache_hits'; -execute stmt1; -show status like 'Qcache_hits'; -execute stmt1; -show status like 'Qcache_hits'; -execute stmt1; -show status like 'Qcache_hits'; -# then QC is re-enabled for more EXECUTE. -set global query_cache_size=100000; -# Note that this execution will not hit results from the -# beginning of the test (because QC has been emptied meanwhile by -# setting its size to 0). -execute stmt1; -show status like 'Qcache_hits'; -execute stmt1; -show status like 'Qcache_hits'; -execute stmt1; -show status like 'Qcache_hits'; - -# QC is disabled at PREPARE -set global query_cache_size=0; -prepare stmt1 from "select * from t1 where c1=10"; -# then QC is enabled at EXECUTE -set global query_cache_size=100000; -show status like 'Qcache_hits'; -execute stmt1; -show status like 'Qcache_hits'; -execute stmt1; -show status like 'Qcache_hits'; -execute stmt1; -show status like 'Qcache_hits'; - -# QC is disabled at PREPARE -set global query_cache_size=0; -prepare stmt1 from "select * from t1 where c1=?"; -# then QC is enabled at EXECUTE -set global query_cache_size=100000; -show status like 'Qcache_hits'; -set @a=1; -execute stmt1 using @a; -show status like 'Qcache_hits'; -set @a=100; -execute stmt1 using @a; -show status like 'Qcache_hits'; -set @a=10; -execute stmt1 using @a; -show status like 'Qcache_hits'; - - -drop table t1; - -set global query_cache_size=0; -flush status; # reset Qcache status variables for next tests diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 53224cccc2d..7af90480e2a 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -2471,7 +2471,7 @@ static void test_ps_query_cache() "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')"); myquery(rc); - for (iteration= TEST_QCACHE_ON; iteration < TEST_QCACHE_ON_OFF; iteration++) + for (iteration= TEST_QCACHE_ON; iteration <= TEST_QCACHE_ON_OFF; iteration++) { switch (iteration) @@ -2610,7 +2610,9 @@ static void test_ps_query_cache() case TEST_QCACHE_ON_OFF: /* should not have hit */ DIE_UNLESS(hits2-hits1 == 0); break; - case TEST_QCACHE_ON_WITH_OTHER_CONN: + case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */ + DIE_UNLESS(hits2-hits1 == 1); + break; mysql_close(lmysql); mysql= org_mysql; } From 850eadadc6da7e4bd4df4a8dd211329629ba1a07 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 May 2007 00:41:27 +0400 Subject: [PATCH 28/74] Fix warnings. sql/item_func.h: Resolve a warning (wrong initialization order). sql/sql_lex.cc: Make -ansi mode compile. --- sql/item_func.h | 2 +- sql/sql_lex.cc | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/sql/item_func.h b/sql/item_func.h index 827bfd56e87..51ffe2133c9 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1261,7 +1261,7 @@ class Item_func_get_user_var :public Item_func, public: LEX_STRING name; // keep it public Item_func_get_user_var(LEX_STRING a): - Item_func(), name(a), m_cached_result_type(STRING_RESULT) {} + Item_func(), m_cached_result_type(STRING_RESULT), name(a) {} enum Functype functype() const { return GUSERVAR_FUNC; } LEX_STRING get_name() { return name; } double val_real(); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 65e5f8035e4..7c900cf64d3 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1786,8 +1786,6 @@ st_lex::st_lex() :result(0), yacc_yyss(0), yacc_yyvs(0), sql_command(SQLCOM_END), option_type(OPT_DEFAULT) { - /* Check that plugins_static_buffer is declared immediately after plugins */ - compile_time_assert((&plugins + 1) == (DYNAMIC_ARRAY*)plugins_static_buffer); my_init_dynamic_array2(&plugins, sizeof(plugin_ref), plugins_static_buffer, From b432f9c1e3e16f54f9322873954d8e313567d54c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 May 2007 14:46:22 +0200 Subject: [PATCH 29/74] Fix for bug#28666 CREATE EVENT ... EVERY 0 SECOND let server crash A missing check for zero value of interval was added. mysql-test/r/events_bugs.result: update result file mysql-test/t/events_bugs.test: add test case for bug#28666 CREATE EVENT ... EVERY 0 SECOND let server crash sql/event_data_objects.cc: add a missing check about zero value for interval --- mysql-test/r/events_bugs.result | 29 +++++++++++++++++++++++++ mysql-test/t/events_bugs.test | 38 +++++++++++++++++++++++++++++++++ sql/event_data_objects.cc | 3 ++- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index 5b48e3ea142..ba3e5fa0289 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -528,4 +528,33 @@ DROP EVENT e3; DROP EVENT e2; DROP EVENT e1; SET TIME_ZONE=@save_time_zone; +drop event if exists new_event; +CREATE EVENT new_event ON SCHEDULE EVERY 0 SECOND DO SELECT 1; +ERROR HY000: INTERVAL is either not positive or too big +CREATE EVENT new_event ON SCHEDULE EVERY (SELECT 0) SECOND DO SELECT 1; +ERROR HY000: INTERVAL is either not positive or too big +CREATE EVENT new_event ON SCHEDULE EVERY "abcdef" SECOND DO SELECT 1; +ERROR HY000: INTERVAL is either not positive or too big +CREATE EVENT new_event ON SCHEDULE EVERY "0abcdef" SECOND DO SELECT 1; +ERROR HY000: INTERVAL is either not positive or too big +CREATE EVENT new_event ON SCHEDULE EVERY "a1bcdef" SECOND DO SELECT 1; +ERROR HY000: INTERVAL is either not positive or too big +CREATE EVENT new_event ON SCHEDULE EVERY (SELECT "abcdef" UNION SELECT "abcdef") SECOND DO SELECT 1; +ERROR HY000: INTERVAL is either not positive or too big +CREATE EVENT new_event ON SCHEDULE EVERY (SELECT "0abcdef") SECOND DO SELECT 1; +ERROR HY000: INTERVAL is either not positive or too big +CREATE EVENT new_event ON SCHEDULE EVERY (SELECT "a1bcdef") SECOND DO SELECT 1; +ERROR HY000: INTERVAL is either not positive or too big +CREATE EVENT new_event ON SCHEDULE AT "every day" DO SELECT 1; +ERROR HY000: Incorrect AT value: 'every day' +CREATE EVENT new_event ON SCHEDULE AT "0every day" DO SELECT 1; +ERROR HY000: Incorrect AT value: '0every day' +CREATE EVENT new_event ON SCHEDULE AT (SELECT "every day") DO SELECT 1; +ERROR HY000: Incorrect AT value: 'every day' +CREATE EVENT new_event ON SCHEDULE AT NOW() STARTS NOW() DO SELECT 1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'STARTS NOW() DO SELECT 1' at line 1 +CREATE EVENT new_event ON SCHEDULE AT NOW() ENDS NOW() DO SELECT 1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ENDS NOW() DO SELECT 1' at line 1 +CREATE EVENT new_event ON SCHEDULE AT NOW() STARTS NOW() ENDS NOW() DO SELECT 1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'STARTS NOW() ENDS NOW() DO SELECT 1' at line 1 drop database events_test; diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index b2c44da7f99..5bd8ae67fb1 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -610,6 +610,44 @@ DROP EVENT e1; SET TIME_ZONE=@save_time_zone; +# +# START - BUG#28666 CREATE EVENT ... EVERY 0 SECOND let server crash +# +--disable_warnings +drop event if exists new_event; +--enable_warnings +--error ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG +CREATE EVENT new_event ON SCHEDULE EVERY 0 SECOND DO SELECT 1; +--error ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG +CREATE EVENT new_event ON SCHEDULE EVERY (SELECT 0) SECOND DO SELECT 1; +--error ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG +CREATE EVENT new_event ON SCHEDULE EVERY "abcdef" SECOND DO SELECT 1; +--error ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG +CREATE EVENT new_event ON SCHEDULE EVERY "0abcdef" SECOND DO SELECT 1; +--error ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG +CREATE EVENT new_event ON SCHEDULE EVERY "a1bcdef" SECOND DO SELECT 1; + +--error ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG +CREATE EVENT new_event ON SCHEDULE EVERY (SELECT "abcdef" UNION SELECT "abcdef") SECOND DO SELECT 1; +--error ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG +CREATE EVENT new_event ON SCHEDULE EVERY (SELECT "0abcdef") SECOND DO SELECT 1; +--error ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG +CREATE EVENT new_event ON SCHEDULE EVERY (SELECT "a1bcdef") SECOND DO SELECT 1; + +--error ER_WRONG_VALUE +CREATE EVENT new_event ON SCHEDULE AT "every day" DO SELECT 1; +--error ER_WRONG_VALUE +CREATE EVENT new_event ON SCHEDULE AT "0every day" DO SELECT 1; +--error ER_WRONG_VALUE +CREATE EVENT new_event ON SCHEDULE AT (SELECT "every day") DO SELECT 1; + +--error ER_PARSE_ERROR +CREATE EVENT new_event ON SCHEDULE AT NOW() STARTS NOW() DO SELECT 1; +--error ER_PARSE_ERROR +CREATE EVENT new_event ON SCHEDULE AT NOW() ENDS NOW() DO SELECT 1; +--error ER_PARSE_ERROR +CREATE EVENT new_event ON SCHEDULE AT NOW() STARTS NOW() ENDS NOW() DO SELECT 1; + # # End of tests # diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 9394bdcdae5..86a8f264331 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -413,7 +413,8 @@ Event_parse_data::init_interval(THD *thd) default: ;/* these are the microsec stuff */ } - if (interval_tmp.neg || expression > EVEX_MAX_INTERVAL_VALUE) + if (interval_tmp.neg || expression == 0 || + expression > EVEX_MAX_INTERVAL_VALUE) { my_error(ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG, MYF(0)); DBUG_RETURN(EVEX_BAD_PARAMS); From 1e33b063f07522e3a94cb62357e02d70168d10aa Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 May 2007 14:36:01 -0600 Subject: [PATCH 30/74] Bug#27876 (SF with cyrillic variable name fails during execution (regression)) The root cause of this bug is related to the function skip_rear_comments, in sql_lex.cc Recent code changes in skip_rear_comments changed the prototype from "const uchar*" to "const char*", which had an unforseen impact on this test: (endp[-1] < ' ') With unsigned characters, this code filters bytes of value [0x00 - 0x20] With *signed* characters, this also filters bytes of value [0x80 - 0xFF]. This caused the regression reported, considering cyrillic characters in the parameter name to be whitespace, and truncated. Note that the regression is present both in 5.0 and 5.1. With this fix: - [0x80 - 0xFF] bytes are no longer considered whitespace. This alone fixes the regression. In addition, filtering [0x00 - 0x20] was found bogus and abusive, so that the code now filters uses my_isspace when looking for whitespace. Note that this fix is only addressing the regression affecting UTF-8 in general, but does not address a more fundamental problem with skip_rear_comments: parsing a string *backwards*, starting at end[-1], is not safe with multi-bytes characters, so that end[-1] can confuse the last byte of a multi-byte characters with a characters to filter out. The only known impact of this remaining issue affects objects that have to meet all the conditions below: - the object is a FUNCTION / PROCEDURE / TRIGGER / EVENT / VIEW - the body consist of only *1* instruction, and does *not* contain a BEGIN-END block - the instruction ends, lexically, with * ';'? For example, "select ;" or "return ;" - The last character of is a multi-byte character - the last byte of this character is ';' '*', '/' or whitespace In this case, the body of the object will be truncated after parsing, and stored in an invalid format. This last issue has not been fixed in this patch, since the real fix will be implemented by Bug 25411 (trigger code truncated), which is caused by the very same code. The real problem is that the function skip_rear_comments is only a work-around, and should be removed entirely: see the proposed patch for bug 25411 for details. sql/sp_head.cc: In skip_rear_comments, Filter out only whitespace, not other (non ascii or control) valid characters sql/sql_lex.cc: In skip_rear_comments, Filter out only whitespace, not other (non ascii or control) valid characters sql/sql_lex.h: In skip_rear_comments, Filter out only whitespace, not other (non ascii or control) valid characters sql/sql_view.cc: In skip_rear_comments, Filter out only whitespace, not other (non ascii or control) valid characters tests/mysql_client_test.c: Bug#27876 (SF with cyrillic variable name fails during execution (regression)) --- sql/sp_head.cc | 2 +- sql/sql_lex.cc | 8 +++-- sql/sql_lex.h | 2 +- sql/sql_view.cc | 3 +- tests/mysql_client_test.c | 64 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 6 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 835d8bf038f..bb742198381 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -539,7 +539,7 @@ sp_head::init_strings(THD *thd, LEX *lex) Trim "garbage" at the end. This is sometimes needed with the "/ * ! VERSION... * /" wrapper in dump files. */ - endp= skip_rear_comments((char*) m_body_begin, (char*) endp); + endp= skip_rear_comments(thd->charset(), (char*) m_body_begin, (char*) endp); m_body.length= endp - m_body_begin; m_body.str= strmake_root(root, m_body_begin, m_body.length); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 7bcdc499011..2428b2e2330 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1098,6 +1098,7 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) SYNOPSIS skip_rear_comments() + cs character set begin pointer to the beginning of statement end pointer to the end of statement @@ -1108,10 +1109,11 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) Pointer to the last non-comment symbol of the statement. */ -char *skip_rear_comments(char *begin, char *end) +char *skip_rear_comments(CHARSET_INFO *cs, char *begin, char *end) { - while (begin < end && (end[-1] <= ' ' || end[-1] == '*' || - end[-1] == '/' || end[-1] == ';')) + while (begin < end && (end[-1] == '*' || + end[-1] == '/' || end[-1] == ';') || + my_isspace(cs, end[-1])) end-= 1; return end; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 6c9283126c4..f8405ef14ca 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1271,4 +1271,4 @@ extern void lex_free(void); extern void lex_start(THD *thd); extern void lex_end(LEX *lex); extern int MYSQLlex(void *arg, void *yythd); -extern char *skip_rear_comments(char *begin, char *end); +extern char *skip_rear_comments(CHARSET_INFO *cs, char *begin, char *end); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index ba367040b36..bfa799ff289 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -772,7 +772,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, view->query.str= (char*)str.ptr(); view->query.length= str.length()-1; // we do not need last \0 view->source.str= thd->query + thd->lex->create_view_select_start; - view->source.length= (char *)skip_rear_comments((char *)view->source.str, + view->source.length= (char *)skip_rear_comments(thd->charset(), + (char *)view->source.str, (char *)thd->query + thd->query_length) - view->source.str; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 38346ad0dbc..e56dd693287 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15560,6 +15560,69 @@ static void test_bug24179() } +/* + Bug#27876 (SF with cyrillic variable name fails during execution (regression)) +*/ +static void test_bug27876() +{ + int rc; + MYSQL_RES *result; + + char utf8_func[] = + { + 0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba, + 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba, + 0xd0, 0xb0, + 0x00 + }; + + char utf8_param[] = + { + 0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0, + 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a, + 0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, + 0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f, + 0x00 + }; + + char query[500]; + + DBUG_ENTER("test_bug27876"); + myheader("test_bug27876"); + + rc= mysql_query(mysql, "set names utf8"); + myquery(rc); + + rc= mysql_query(mysql, "select version()"); + myquery(rc); + result= mysql_store_result(mysql); + mytest(result); + + sprintf(query, "DROP FUNCTION IF EXISTS %s", utf8_func); + rc= mysql_query(mysql, query); + myquery(rc); + + sprintf(query, + "CREATE FUNCTION %s( %s VARCHAR(25))" + " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s", + utf8_func, utf8_param, utf8_param); + rc= mysql_query(mysql, query); + myquery(rc); + sprintf(query, "SELECT %s(VERSION())", utf8_func); + rc= mysql_query(mysql, query); + myquery(rc); + result= mysql_store_result(mysql); + mytest(result); + + sprintf(query, "DROP FUNCTION %s", utf8_func); + rc= mysql_query(mysql, query); + myquery(rc); + + rc= mysql_query(mysql, "set names default"); + myquery(rc); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -15840,6 +15903,7 @@ static struct my_tests_st my_tests[]= { { "test_bug23383", test_bug23383 }, { "test_bug21635", test_bug21635 }, { "test_bug24179", test_bug24179 }, + { "test_bug27876", test_bug27876 }, { 0, 0 } }; From 5ed76763f864f8d0a5a6295e1ba492cd2f1acbf9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 May 2007 16:17:20 -0600 Subject: [PATCH 31/74] Code review comments sql/sql_lex.cc: Fixed parenthese typo, found during code review --- sql/sql_lex.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 2428b2e2330..cbfba3d4d80 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1112,8 +1112,8 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) char *skip_rear_comments(CHARSET_INFO *cs, char *begin, char *end) { while (begin < end && (end[-1] == '*' || - end[-1] == '/' || end[-1] == ';') || - my_isspace(cs, end[-1])) + end[-1] == '/' || end[-1] == ';' || + my_isspace(cs, end[-1]))) end-= 1; return end; } From 624d65c5918dcaf5ca9288a9c77a927643b1d4df Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 26 May 2007 16:36:38 +0200 Subject: [PATCH 32/74] Fix for bug#26338 events_bugs.test fail on Debian and bug#28285 Test "events_bugs" has instable results of "select /*1*/ ... from processlist" mysql-test/r/events_bugs.result: uppercase mysql-test/t/events.test: wait at the end of the script for event which haven't finished their execution. This should solve bug#26338 events_bugs.test fail on Debian and bug#28285 Test "events_bugs" has instable results of "select /*1*/ ... from processlist" mysql-test/t/events_bugs.test: wait at the end of the script for event which haven't finished their execution. This should solve bug#26338 events_bugs.test fail on Debian and bug#28285 Test "events_bugs" has instable results of "select /*1*/ ... from processlist" mysql-test/t/events_grant.test: wait at the end of the script for event which haven't finished their execution. This should solve bug#26338 events_bugs.test fail on Debian and bug#28285 Test "events_bugs" has instable results of "select /*1*/ ... from processlist" mysql-test/t/events_logs_tests.test: wait at the end of the script for event which haven't finished their execution. This should solve bug#26338 events_bugs.test fail on Debian and bug#28285 Test "events_bugs" has instable results of "select /*1*/ ... from processlist" mysql-test/t/events_scheduling.test: wait at the end of the script for event which haven't finished their execution. This should solve bug#26338 events_bugs.test fail on Debian and bug#28285 Test "events_bugs" has instable results of "select /*1*/ ... from processlist" mysql-test/t/events_stress.test: wait at the end of the script for event which haven't finished their execution. This should solve bug#26338 events_bugs.test fail on Debian and bug#28285 Test "events_bugs" has instable results of "select /*1*/ ... from processlist" mysql-test/t/events_time_zone.test: wait at the end of the script for event which haven't finished their execution. This should solve bug#26338 events_bugs.test fail on Debian and bug#28285 Test "events_bugs" has instable results of "select /*1*/ ... from processlist" mysql-test/t/events_trans.test: wait at the end of the script for event which haven't finished their execution. This should solve bug#26338 events_bugs.test fail on Debian and bug#28285 Test "events_bugs" has instable results of "select /*1*/ ... from processlist" mysql-test/t/events_trans_notembedded.test: wait at the end of the script for event which haven't finished their execution. This should solve bug#26338 events_bugs.test fail on Debian and bug#28285 Test "events_bugs" has instable results of "select /*1*/ ... from processlist" --- mysql-test/r/events_bugs.result | 2 +- mysql-test/t/events.test | 14 ++++++++++++++ mysql-test/t/events_bugs.test | 10 +++++++++- mysql-test/t/events_grant.test | 10 ++++++++-- mysql-test/t/events_logs_tests.test | 6 ++++++ mysql-test/t/events_scheduling.test | 10 ++++++++++ mysql-test/t/events_stress.test | 1 + mysql-test/t/events_time_zone.test | 6 +++++- mysql-test/t/events_trans.test | 6 ++++++ mysql-test/t/events_trans_notembedded.test | 5 +++++ 10 files changed, 65 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index ba3e5fa0289..fae530f556b 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -557,4 +557,4 @@ CREATE EVENT new_event ON SCHEDULE AT NOW() ENDS NOW() DO SELECT 1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ENDS NOW() DO SELECT 1' at line 1 CREATE EVENT new_event ON SCHEDULE AT NOW() STARTS NOW() ENDS NOW() DO SELECT 1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'STARTS NOW() ENDS NOW() DO SELECT 1' at line 1 -drop database events_test; +DROP DATABASE events_test; diff --git a/mysql-test/t/events.test b/mysql-test/t/events.test index 575f9984a79..dcb591352a8 100644 --- a/mysql-test/t/events.test +++ b/mysql-test/t/events.test @@ -451,6 +451,10 @@ set global event_scheduler=off; --echo "Should have only our process now:" select /*4*/ user, host, db, command, state, info from information_schema.processlist where (command!='Daemon' || user='event_scheduler') and (info is null or info not like '%processlist%') order by info; drop event закачка21; +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where db='events_test' and command = 'Connect' and user=current_user(); +--source include/wait_condition.inc #### # Bug #16410 Events: CREATE EVENT is legal in a CREATE TRIGGER statement @@ -725,4 +729,14 @@ drop table t1| drop event e1| delimiter ;| + +# +# End of tests +# + +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where db='events_test' and command = 'Connect' and user=current_user(); +--source include/wait_condition.inc + drop database events_test; diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index 5bd8ae67fb1..f369fbecd66 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -648,7 +648,15 @@ CREATE EVENT new_event ON SCHEDULE AT NOW() ENDS NOW() DO SELECT 1; --error ER_PARSE_ERROR CREATE EVENT new_event ON SCHEDULE AT NOW() STARTS NOW() ENDS NOW() DO SELECT 1; + + # # End of tests # -drop database events_test; + +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where db='events_test' and command = 'Connect' and user=current_user(); +--source include/wait_condition.inc + +DROP DATABASE events_test; diff --git a/mysql-test/t/events_grant.test b/mysql-test/t/events_grant.test index 44288fc1ac6..cff2475c5aa 100644 --- a/mysql-test/t/events_grant.test +++ b/mysql-test/t/events_grant.test @@ -101,8 +101,14 @@ disconnect ev_con1; connection default; DROP USER ev_test@localhost; DROP DATABASE events_test2; -# -## EVENTS grants test end + +# +# End of tests # +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where db='events_test' and command = 'Connect' and user=current_user(); +--source include/wait_condition.inc + DROP DATABASE events_test; diff --git a/mysql-test/t/events_logs_tests.test b/mysql-test/t/events_logs_tests.test index 25b75f13f01..0c56f32beff 100644 --- a/mysql-test/t/events_logs_tests.test +++ b/mysql-test/t/events_logs_tests.test @@ -107,4 +107,10 @@ SET SESSION long_query_time =@old_session_long_query_time; DROP DATABASE events_test; + SET GLOBAL event_scheduler=off; + +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where db='events_test' and command = 'Connect' and user=current_user(); +--source include/wait_condition.inc diff --git a/mysql-test/t/events_scheduling.test b/mysql-test/t/events_scheduling.test index 31c09a3d561..b1eeae1e020 100644 --- a/mysql-test/t/events_scheduling.test +++ b/mysql-test/t/events_scheduling.test @@ -106,3 +106,13 @@ DROP TABLE table_3; DROP TABLE table_4; DROP DATABASE events_test; SET GLOBAL event_scheduler=OFF; + +# +# End of tests +# + +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where db='events_test' and command = 'Connect' and user=current_user(); +--source include/wait_condition.inc + diff --git a/mysql-test/t/events_stress.test b/mysql-test/t/events_stress.test index fd1ae34ac3c..22959898b43 100644 --- a/mysql-test/t/events_stress.test +++ b/mysql-test/t/events_stress.test @@ -133,4 +133,5 @@ DROP USER event_user3@localhost; # # DROP DATABASE test end (bug #16406) # + DROP DATABASE events_test; diff --git a/mysql-test/t/events_time_zone.test b/mysql-test/t/events_time_zone.test index 5f929e0b07a..af3466a339c 100644 --- a/mysql-test/t/events_time_zone.test +++ b/mysql-test/t/events_time_zone.test @@ -288,7 +288,11 @@ DROP TABLE t_step; DROP DATABASE mysqltest_db1; --disable_query_log eval USE $old_db; ---enable_query_log +--enable_query_log +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where db='mysqltest_db1' and command = 'Connect' and user=current_user(); +--source include/wait_condition.inc --echo End of 5.1 tests. diff --git a/mysql-test/t/events_trans.test b/mysql-test/t/events_trans.test index 77427070cbb..562b5a9625f 100644 --- a/mysql-test/t/events_trans.test +++ b/mysql-test/t/events_trans.test @@ -111,5 +111,11 @@ commit work; # # Cleanup # + +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where db='events_test' and command = 'Connect' and user=current_user(); +--source include/wait_condition.inc + drop database events_test; diff --git a/mysql-test/t/events_trans_notembedded.test b/mysql-test/t/events_trans_notembedded.test index adc293d7e79..3c151dd18b1 100644 --- a/mysql-test/t/events_trans_notembedded.test +++ b/mysql-test/t/events_trans_notembedded.test @@ -57,5 +57,10 @@ drop database mysqltest_db2; # # Cleanup # +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where db='events_test' and command = 'Connect' and user=current_user(); +--source include/wait_condition.inc + drop database events_test; From b11f1d0c97665024a5eca974326435d075b90e9e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 May 2007 15:30:01 +0400 Subject: [PATCH 33/74] 5.1 version of a fix and test cases for bugs: Bug#4968 ""Stored procedure crash if cursor opened on altered table" Bug#6895 "Prepared Statements: ALTER TABLE DROP COLUMN does nothing" Bug#19182 "CREATE TABLE bar (m INT) SELECT n FROM foo; doesn't work from stored procedure." Bug#19733 "Repeated alter, or repeated create/drop, fails" Bug#22060 "ALTER TABLE x AUTO_INCREMENT=y in SP crashes server" Bug#24879 "Prepared Statements: CREATE TABLE (UTF8 KEY) produces a growing key length" (this bug is not fixed in 5.0) Re-execution of CREATE DATABASE, CREATE TABLE and ALTER TABLE statements in stored routines or as prepared statements caused incorrect results (and crashes in versions prior to 5.0.25). In 5.1 the problem occured only for CREATE DATABASE, CREATE TABLE SELECT and CREATE TABLE with INDEX/DATA DIRECTOY options). The problem of bugs 4968, 19733, 19282 and 6895 was that functions mysql_prepare_table, mysql_create_table and mysql_alter_table are not re-execution friendly: during their operation they modify contents of LEX (members create_info, alter_info, key_list, create_list), thus making the LEX unusable for the next execution. In particular, these functions removed processed columns and keys from create_list, key_list and drop_list. Search the code in sql_table.cc for drop_it.remove() and similar patterns to find evidence. The fix is to supply to these functions a usable copy of each of the above structures at every re-execution of an SQL statement. To simplify memory management, LEX::key_list and LEX::create_list were added to LEX::alter_info, a fresh copy of which is created for every execution. The problem of crashing bug 22060 stemmed from the fact that the above metnioned functions were not only modifying HA_CREATE_INFO structure in LEX, but also were changing it to point to areas in volatile memory of the execution memory root. The patch solves this problem by creating and using an on-stack copy of HA_CREATE_INFO in mysql_execute_command. Additionally, this patch splits the part of mysql_alter_table that analizes and rewrites information from the parser into a separate function - mysql_prepare_alter_table, in analogy with mysql_prepare_table, which is renamed to mysql_prepare_create_table. mysql-test/r/ps.result: Update test results (Bug#19182, Bug#22060, Bug#4968, Bug#6895) mysql-test/r/sp.result: Update results (Bug#19733) mysql-test/t/ps.test: Add test cases for Bug#19182, Bug#22060, Bug#4968, Bug#6895 mysql-test/t/sp.test: Add a test case for Bug#19733 sql/field.h: Implement a deep copy constructor for create_field sql/mysql_priv.h: LEX::key_list and LEX::create_list were moved to LEX::alter_info. Update declarations to use LEX::alter_info instead of these two members. Remove declarations of mysql_add_index, mysql_drop_index. sql/sql_class.cc: Implement deep copy constructors. sql/sql_class.h: Implement (almost) deep copy constructors for key_part_spec, Alter_drop, Alter_column, Key, foreign_key. Replace pair with an instance of Alter_info in select_create constructor. We create a new copy of Alter_info each time we re-execute SELECT .. CREATE prepared statement. sql/sql_insert.cc: Adjust to a new signature of create_table_from_items. sql/sql_lex.cc: Implement Alter_info::Alter_info that would make a "deep" copy of all definition lists (keys, columns). Move is_partition_management() from sql_partition.cc (feature-based file division is evil). sql/sql_lex.h: Move key_list and create_list to class Alter_info. Implement Alter_info::Alter_info that can be used with PS and SP. Get rid of Alter_info::clear() which was an attempt to save on matches and always use Alter_info::reset(). Implement an auxiliary Alter_info::init_for_create_from_alter() which is used in mysql_alter_table. sql/sql_list.cc: Implement a copy constructor of class List that makes a deep copy of all list nodes. sql/sql_list.h: Implement a way to make a deep copy of all list nodes. sql/sql_parse.cc: Adjust to new signatures of mysql_create_table, mysql_alter_table, select_create. Functions mysql_create_index and mysql_drop_index has become identical after initialization of alter_info was moved to the parser, and were merged. Flag enable_slow_log was not updated for SQLCOM_DROP_INDEX, which was a bug. Just like CREATE INDEX, DROP INDEX is currently done via complete table rebuild and is rightfully a slow administrative statement. sql/sql_partition.cc: Move is_partition_management() to sql_lex.cc Adjust code to the new Alter_info. sql/sql_table.cc: Adjust mysql_alter_table, mysql_recreate_table, mysql_create_table, mysql_prepare_table to new signatures. Rename mysql_prepare_table to mysql_prepare_create_table. Make sure it follows the convention and returns FALSE for success and TRUE for error. Move parts of mysql_alter_table to mysql_prepare_alter_table. Move the first invokation of mysql_prepare_table from mysql_alter_table to compare_tables, as it was needed only for the purpose of correct comparison. Since now Alter_info itself is created in the runtime mem root, adjust mysql_prepare_table to always allocate memory in the runtime memory root. Remove dead code. sql/sql_yacc.yy: LEX::key_list and LEX::create_list moved to class Alter_info --- mysql-test/r/ps.result | 168 +++++ mysql-test/r/sp.result | 17 + mysql-test/t/ps.test | 194 +++++ mysql-test/t/sp.test | 28 + sql/field.h | 3 + sql/mysql_priv.h | 37 +- sql/sql_class.cc | 34 + sql/sql_class.h | 61 +- sql/sql_insert.cc | 17 +- sql/sql_lex.cc | 47 ++ sql/sql_lex.h | 49 +- sql/sql_list.cc | 34 + sql/sql_list.h | 79 +- sql/sql_parse.cc | 248 ++++--- sql/sql_partition.cc | 39 +- sql/sql_table.cc | 1549 +++++++++++++++++++--------------------- sql/sql_yacc.yy | 62 +- 17 files changed, 1602 insertions(+), 1064 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index b811a27203c..0216ec2a174 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1062,6 +1062,87 @@ EXECUTE stmt USING @a; 0 0 DEALLOCATE PREPARE stmt; DROP TABLE t1; +DROP TABLE IF EXISTS t1, t2; +CREATE TABLE t1 (i INT); +PREPARE st_19182 +FROM "CREATE TABLE t2 (i INT, j INT, KEY (i), KEY(j)) SELECT i FROM t1"; +EXECUTE st_19182; +DESC t2; +Field Type Null Key Default Extra +j int(11) YES MUL NULL +i int(11) YES MUL NULL +DROP TABLE t2; +EXECUTE st_19182; +DESC t2; +Field Type Null Key Default Extra +j int(11) YES MUL NULL +i int(11) YES MUL NULL +DEALLOCATE PREPARE st_19182; +DROP TABLE t2, t1; +drop database if exists mysqltest; +drop table if exists t1, t2; +create database mysqltest character set utf8; +prepare stmt1 from "create table mysqltest.t1 (c char(10))"; +prepare stmt2 from "create table mysqltest.t2 select 'test'"; +execute stmt1; +execute stmt2; +show create table mysqltest.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8 +show create table mysqltest.t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `test` varchar(4) CHARACTER SET latin1 NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=utf8 +drop table mysqltest.t1; +drop table mysqltest.t2; +alter database mysqltest character set latin1; +execute stmt1; +execute stmt2; +show create table mysqltest.t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +show create table mysqltest.t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `test` varchar(4) NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop database mysqltest; +deallocate prepare stmt1; +deallocate prepare stmt2; +execute stmt; +show create table t1; +drop table t1; +execute stmt; +show create table t1; +drop table t1; +deallocate prepare stmt; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2), (3), (1); +PREPARE st1 FROM +'(SELECT a FROM t1) UNION (SELECT a+10 FROM t1) ORDER BY RAND()*0+a'; +EXECUTE st1; +a +1 +2 +3 +11 +12 +13 +EXECUTE st1; +a +1 +2 +3 +11 +12 +13 +DEALLOCATE PREPARE st1; +DROP TABLE t1; End of 4.1 tests. create table t1 (a varchar(20)); insert into t1 values ('foo'); @@ -1544,6 +1625,72 @@ a 2 DEALLOCATE PREPARE stmt; DROP TABLE t1,t2; +drop table if exists t1; +create table t1 (s1 char(20)); +prepare stmt from "alter table t1 modify s1 int"; +execute stmt; +execute stmt; +drop table t1; +deallocate prepare stmt; +drop table if exists t1; +create table t1 (a int, b int); +prepare s_6895 from "alter table t1 drop column b"; +execute s_6895; +show columns from t1; +Field Type Null Key Default Extra +a int(11) YES NULL +drop table t1; +create table t1 (a int, b int); +execute s_6895; +show columns from t1; +Field Type Null Key Default Extra +a int(11) YES NULL +drop table t1; +create table t1 (a int, b int); +execute s_6895; +show columns from t1; +Field Type Null Key Default Extra +a int(11) YES NULL +deallocate prepare s_6895; +drop table t1; +create table t1 (i int primary key auto_increment) comment='comment for table t1'; +create table t2 (i int, j int, k int); +prepare stmt from "alter table t1 auto_increment=100"; +execute stmt; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`i`) +) ENGINE=MyISAM AUTO_INCREMENT=100 DEFAULT CHARSET=latin1 COMMENT='comment for table t1' +flush tables; +select * from t2; +i j k +execute stmt; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `i` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`i`) +) ENGINE=MyISAM AUTO_INCREMENT=100 DEFAULT CHARSET=latin1 COMMENT='comment for table t1' +deallocate prepare stmt; +drop table t1, t2; +set @old_character_set_server= @@character_set_server; +set @@character_set_server= latin1; +prepare stmt from "create database mysqltest_1"; +execute stmt; +show create database mysqltest_1; +Database Create Database +mysqltest_1 CREATE DATABASE `mysqltest_1` /*!40100 DEFAULT CHARACTER SET latin1 */ +drop database mysqltest_1; +set @@character_set_server= utf8; +execute stmt; +show create database mysqltest_1; +Database Create Database +mysqltest_1 CREATE DATABASE `mysqltest_1` /*!40100 DEFAULT CHARACTER SET utf8 */ +drop database mysqltest_1; +deallocate prepare stmt; +set @@character_set_server= @old_character_set_server; drop tables if exists t1; create table t1 (id int primary key auto_increment, value varchar(10)); insert into t1 (id, value) values (1, 'FIRST'), (2, 'SECOND'), (3, 'THIRD'); @@ -2524,4 +2671,25 @@ i j 4 5 3 NULL DROP TABLE t1, t2; +drop table if exists t1; +Warnings: +Note 1051 Unknown table 't1' +prepare stmt +from "create table t1 (c char(100) character set utf8, key (c(10)))"; +execute stmt; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(100) CHARACTER SET utf8 DEFAULT NULL, + KEY `c` (`c`(10)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +execute stmt; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(100) CHARACTER SET utf8 DEFAULT NULL, + KEY `c` (`c`(10)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; End of 5.1 tests. diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index ac394a9df3d..e6dea250355 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -5617,6 +5617,23 @@ Called B Called B drop procedure proc_21462_a| drop procedure proc_21462_b| +drop table if exists t3| +drop procedure if exists proc_bug19733| +create table t3 (s1 int)| +create procedure proc_bug19733() +begin +declare v int default 0; +while v < 100 do +create index i on t3 (s1); +drop index i on t3; +set v = v + 1; +end while; +end| +call proc_bug19733()| +call proc_bug19733()| +call proc_bug19733()| +drop procedure proc_bug19733| +drop table t3| DROP PROCEDURE IF EXISTS p1| DROP VIEW IF EXISTS v1, v2| DROP TABLE IF EXISTS t3, t4| diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 1fd1cc4a405..9da6835580b 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1118,6 +1118,113 @@ EXECUTE stmt USING @a; DEALLOCATE PREPARE stmt; DROP TABLE t1; +# +# Bug#19182: CREATE TABLE bar (m INT) SELECT n FROM foo; doesn't work +# from stored procedure. +# +# The cause of a bug was that cached LEX::create_list was modified, +# and then together with LEX::key_list was reset. +# +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +CREATE TABLE t1 (i INT); + +PREPARE st_19182 +FROM "CREATE TABLE t2 (i INT, j INT, KEY (i), KEY(j)) SELECT i FROM t1"; + +EXECUTE st_19182; +DESC t2; + +DROP TABLE t2; + +# Check that on second execution we don't loose 'j' column and the keys +# on 'i' and 'j' columns. +EXECUTE st_19182; +DESC t2; + +DEALLOCATE PREPARE st_19182; +DROP TABLE t2, t1; + +# +# Bug #22060 "ALTER TABLE x AUTO_INCREMENT=y in SP crashes server" +# +# Code which implemented CREATE/ALTER TABLE and CREATE DATABASE +# statement modified HA_CREATE_INFO structure in LEX, making these +# statements PS/SP-unsafe (their re-execution might have resulted +# in incorrect results). +# +--disable_warnings +drop database if exists mysqltest; +drop table if exists t1, t2; +--enable_warnings +# CREATE TABLE and CREATE TABLE ... SELECT +create database mysqltest character set utf8; +prepare stmt1 from "create table mysqltest.t1 (c char(10))"; +prepare stmt2 from "create table mysqltest.t2 select 'test'"; +execute stmt1; +execute stmt2; +show create table mysqltest.t1; +show create table mysqltest.t2; +drop table mysqltest.t1; +drop table mysqltest.t2; +alter database mysqltest character set latin1; +execute stmt1; +execute stmt2; +show create table mysqltest.t1; +show create table mysqltest.t2; +drop database mysqltest; +deallocate prepare stmt1; +deallocate prepare stmt2; +# +# CREATE TABLE with DATA DIRECTORY option +# +# Protect ourselves from data left in tmp/ by a previos possibly failed +# test +--system rm -f $MYSQLTEST_VARDIR/tmp/t1.* +--disable_warnings +--disable_query_log +eval prepare stmt from "create table t1 (c char(10)) data directory='$MYSQLTEST_VARDIR/tmp'"; +--enable_query_log +execute stmt; +# +# DATA DIRECTORY option does not always work: if the operating +# system does not support symlinks, have_symlinks option is automatically +# disabled. +# In this case DATA DIRECTORY is silently ignored when +# creating a table, and is not output by SHOW CREATE TABLE. +# +--disable_result_log +show create table t1; +--enable_result_log +drop table t1; +execute stmt; +--disable_result_log +show create table t1; +--enable_result_log +--enable_warnings +drop table t1; +deallocate prepare stmt; +# + +# +# Bug #27937: crash on the second execution for prepared statement +# from UNION with ORDER BY an expression containing RAND() +# + +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2), (3), (1); + +PREPARE st1 FROM + '(SELECT a FROM t1) UNION (SELECT a+10 FROM t1) ORDER BY RAND()*0+a'; + +EXECUTE st1; +EXECUTE st1; + +DEALLOCATE PREPARE st1; +DROP TABLE t1; + --echo End of 4.1 tests. ############################# 5.0 tests start ################################ @@ -1596,6 +1703,77 @@ EXECUTE stmt USING @arg; DEALLOCATE PREPARE stmt; DROP TABLE t1,t2; +# +# Bug#4968 "Stored procedure crash if cursor opened on altered table" +# The bug is not repeatable any more after the fix for +# Bug#15217 "Bug #15217 Using a SP cursor on a table created with PREPARE +# fails with weird error", however ALTER TABLE is not re-execution friendly +# and that caused a valgrind warning. Check that the warning is gone. +# +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (s1 char(20)); +prepare stmt from "alter table t1 modify s1 int"; +execute stmt; +execute stmt; +drop table t1; +deallocate prepare stmt; + +# +# Bug#6895 "Prepared Statements: ALTER TABLE DROP COLUMN does nothing" +# +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a int, b int); +prepare s_6895 from "alter table t1 drop column b"; +execute s_6895; +show columns from t1; +drop table t1; +create table t1 (a int, b int); +execute s_6895; +show columns from t1; +drop table t1; +create table t1 (a int, b int); +execute s_6895; +show columns from t1; +deallocate prepare s_6895; +drop table t1; + +# +# Bug #22060 "ALTER TABLE x AUTO_INCREMENT=y in SP crashes server" +# +# 5.0 part of the test. +# + +# ALTER TABLE +create table t1 (i int primary key auto_increment) comment='comment for table t1'; +create table t2 (i int, j int, k int); +prepare stmt from "alter table t1 auto_increment=100"; +execute stmt; +show create table t1; +# Let us trash table-cache's memory +flush tables; +select * from t2; +execute stmt; +show create table t1; +deallocate prepare stmt; +drop table t1, t2; +# 5.1 part of the test. +# CREATE DATABASE +set @old_character_set_server= @@character_set_server; +set @@character_set_server= latin1; +prepare stmt from "create database mysqltest_1"; +execute stmt; +show create database mysqltest_1; +drop database mysqltest_1; +set @@character_set_server= utf8; +execute stmt; +show create database mysqltest_1; +drop database mysqltest_1; +deallocate prepare stmt; +set @@character_set_server= @old_character_set_server; # @@ -2570,5 +2748,21 @@ connection default; DROP TABLE t1, t2; +# +# Bug #24879 Prepared Statements: CREATE TABLE (UTF8 KEY) produces a growing +# key length +# +# Test that parse information is not altered by subsequent executions of a +# prepared statement +# +drop table if exists t1; +prepare stmt +from "create table t1 (c char(100) character set utf8, key (c(10)))"; +execute stmt; +show create table t1; +drop table t1; +execute stmt; +show create table t1; +drop table t1; --echo End of 5.1 tests. diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 6da4bb1b81c..60f6b0a491e 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -6569,6 +6569,34 @@ drop procedure proc_21462_a| drop procedure proc_21462_b| +# +# Bug#19733 "Repeated alter, or repeated create/drop, fails" +# Check that CREATE/DROP INDEX is re-execution friendly. +# +--disable_warnings +drop table if exists t3| +drop procedure if exists proc_bug19733| +--enable_warnings +create table t3 (s1 int)| + +create procedure proc_bug19733() +begin + declare v int default 0; + while v < 100 do + create index i on t3 (s1); + drop index i on t3; + set v = v + 1; + end while; +end| + +call proc_bug19733()| +call proc_bug19733()| +call proc_bug19733()| + +drop procedure proc_bug19733| +drop table t3| + + # # BUG#20492: Subsequent calls to stored procedure yeild incorrect # result if join is used diff --git a/sql/field.h b/sql/field.h index 2c2640a8262..f9b4ae33378 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1622,6 +1622,9 @@ public: uint offset,pack_flag; create_field() :after(0) {} create_field(Field *field, Field *orig_field); + /* Used to make a clone of this object for ALTER/CREATE TABLE */ + create_field *clone(MEM_ROOT *mem_root) const + { return new (mem_root) create_field(*this); } void create_length_to_internal_length(void); /* Init for a tmp table field. To be extended if need be. */ diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 0b843d5610d..2fba4c25802 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -960,32 +960,26 @@ int prepare_create_field(create_field *sql_field, longlong table_flags); bool mysql_create_table(THD *thd,const char *db, const char *table_name, HA_CREATE_INFO *create_info, - List &fields, List &keys, - bool tmp_table, uint select_field_count, - bool use_copy_create_info); + Alter_info *alter_info, + bool tmp_table, uint select_field_count); bool mysql_create_table_no_lock(THD *thd, const char *db, const char *table_name, HA_CREATE_INFO *create_info, - List &fields, List &keys, - bool tmp_table, uint select_field_count, - bool use_copy_create_info); + Alter_info *alter_info, + bool tmp_table, uint select_field_count); bool mysql_alter_table(THD *thd, char *new_db, char *new_name, HA_CREATE_INFO *create_info, TABLE_LIST *table_list, - List &fields, - List &keys, - uint order_num, ORDER *order, bool ignore, - ALTER_INFO *alter_info, bool do_send_ok); -bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok); -bool mysql_create_like_table(THD *thd, TABLE_LIST *table, TABLE_LIST *src_table, + Alter_info *alter_info, + uint order_num, ORDER *order, bool ignore); +bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list); +bool mysql_create_like_table(THD *thd, TABLE_LIST *table, + TABLE_LIST *src_table, HA_CREATE_INFO *create_info); bool mysql_rename_table(handlerton *base, const char *old_db, const char * old_name, const char *new_db, const char * new_name, uint flags); -bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys); -bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, - ALTER_INFO *alter_info); bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, Item **conds, uint order_num, ORDER *order); int mysql_update(THD *thd,TABLE_LIST *tables,List &fields, @@ -1309,14 +1303,13 @@ char *make_default_log_name(char *buff,const char* log_ext); #ifdef WITH_PARTITION_STORAGE_ENGINE uint fast_alter_partition_table(THD *thd, TABLE *table, - ALTER_INFO *alter_info, + Alter_info *alter_info, HA_CREATE_INFO *create_info, TABLE_LIST *table_list, - List *create_list, - List *key_list, char *db, + char *db, const char *table_name, uint fast_alter_partition); -uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info, +uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, HA_CREATE_INFO *create_info, handlerton *old_db_type, bool *partition_changed, @@ -1348,11 +1341,7 @@ typedef struct st_lock_param_type ulonglong deleted; THD *thd; HA_CREATE_INFO *create_info; - ALTER_INFO *alter_info; - List *create_list; - List new_create_list; - List *key_list; - List new_key_list; + Alter_info *alter_info; TABLE *table; KEY *key_info_buffer; const char *db; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 87cf9b16d24..0f54d3b7ca5 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -91,6 +91,40 @@ bool key_part_spec::operator==(const key_part_spec& other) const return length == other.length && !strcmp(field_name, other.field_name); } +/** + Construct an (almost) deep copy of this key. Only those + elements that are known to never change are not copied. + If out of memory, a partial copy is returned and an error is set + in THD. +*/ + +Key::Key(const Key &rhs, MEM_ROOT *mem_root) + :type(rhs.type), + key_create_info(rhs.key_create_info), + columns(rhs.columns, mem_root), + name(rhs.name), + generated(rhs.generated) +{ + list_copy_and_replace_each_value(columns, mem_root); +} + +/** + Construct an (almost) deep copy of this foreign key. Only those + elements that are known to never change are not copied. + If out of memory, a partial copy is returned and an error is set + in THD. +*/ + +foreign_key::foreign_key(const foreign_key &rhs, MEM_ROOT *mem_root) + :Key(rhs), + ref_table(rhs.ref_table), + ref_columns(rhs.ref_columns), + delete_opt(rhs.delete_opt), + update_opt(rhs.update_opt), + match_opt(rhs.match_opt) +{ + list_copy_and_replace_each_value(ref_columns, mem_root); +} /* Test if a foreign key (= generated key) is a prefix of the given key diff --git a/sql/sql_class.h b/sql/sql_class.h index ba0defcf875..af0f396c683 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -90,6 +90,17 @@ public: uint length; key_part_spec(const char *name,uint len=0) :field_name(name), length(len) {} bool operator==(const key_part_spec& other) const; + /** + Construct a copy of this key_part_spec. field_name is copied + by-pointer as it is known to never change. At the same time + 'length' may be reset in mysql_prepare_create_table, and this + is why we supply it with a copy. + + @return If out of memory, 0 is returned and an error is set in + THD. + */ + key_part_spec *clone(MEM_ROOT *mem_root) const + { return new (mem_root) key_part_spec(*this); } }; @@ -100,6 +111,12 @@ public: enum drop_type type; Alter_drop(enum drop_type par_type,const char *par_name) :name(par_name), type(par_type) {} + /** + Used to make a clone of this object for ALTER/CREATE TABLE + @sa comment for key_part_spec::clone + */ + Alter_drop *clone(MEM_ROOT *mem_root) const + { return new (mem_root) Alter_drop(*this); } }; @@ -109,6 +126,12 @@ public: Item *def; Alter_column(const char *par_name,Item *literal) :name(par_name), def(literal) {} + /** + Used to make a clone of this object for ALTER/CREATE TABLE + @sa comment for key_part_spec::clone + */ + Alter_column *clone(MEM_ROOT *mem_root) const + { return new (mem_root) Alter_column(*this); } }; @@ -127,9 +150,16 @@ public: :type(type_par), key_create_info(*key_info_arg), columns(cols), name(name_arg), generated(generated_arg) {} - ~Key() {} + Key(const Key &rhs, MEM_ROOT *mem_root); + virtual ~Key() {} /* Equality comparison of keys (ignoring name) */ friend bool foreign_key_prefix(Key *a, Key *b); + /** + Used to make a clone of this object for ALTER/CREATE TABLE + @sa comment for key_part_spec::clone + */ + virtual Key *clone(MEM_ROOT *mem_root) const + { return new (mem_root) Key(*this, mem_root); } }; class Table_ident; @@ -152,6 +182,13 @@ public: delete_opt(delete_opt_arg), update_opt(update_opt_arg), match_opt(match_opt_arg) {} + foreign_key(const foreign_key &rhs, MEM_ROOT *mem_root); + /** + Used to make a clone of this object for ALTER/CREATE TABLE + @sa comment for key_part_spec::clone + */ + virtual Key *clone(MEM_ROOT *mem_root) const + { return new (mem_root) foreign_key(*this, mem_root); } }; typedef struct st_mysql_lock @@ -1944,20 +1981,20 @@ class select_insert :public select_result_interceptor { class select_create: public select_insert { ORDER *group; TABLE_LIST *create_table; - List *extra_fields; - List *keys; HA_CREATE_INFO *create_info; + Alter_info *alter_info; Field **field; public: - select_create (TABLE_LIST *table_arg, - HA_CREATE_INFO *create_info_par, - List &fields_par, - List &keys_par, - List &select_fields,enum_duplicates duplic, bool ignore) - :select_insert (NULL, NULL, &select_fields, 0, 0, duplic, ignore), - create_table(table_arg), extra_fields(&fields_par),keys(&keys_par), - create_info(create_info_par) - {} + select_create(TABLE_LIST *table_arg, + HA_CREATE_INFO *create_info_arg, + Alter_info *alter_info_arg, + List &select_fields, + enum_duplicates duplic, bool ignore) + :select_insert(NULL, NULL, &select_fields, 0, 0, duplic, ignore), + create_table(table_arg), + create_info(create_info_arg), + alter_info(alter_info_arg) + {} int prepare(List &list, SELECT_LEX_UNIT *u); void binlog_show_create_table(TABLE **tables, uint count); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 0268e1d3a41..480b94d0d21 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3138,11 +3138,11 @@ bool select_insert::send_eof() temporary table flag) create_table in Pointer to TABLE_LIST object providing database and name for table to be created or to be open - extra_fields in/out Initial list of fields for table to be created - keys in List of keys for table to be created + alter_info in/out Initial list of columns and indexes for the table + to be created items in List of items which should be used to produce rest of fields for the table (corresponding fields will - be added to the end of 'extra_fields' list) + be added to the end of alter_info->create_list) lock out Pointer to the MYSQL_LOCK object for table created (or open temporary table) will be returned in this parameter. Since this table is not included in @@ -3171,8 +3171,7 @@ bool select_insert::send_eof() static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, TABLE_LIST *create_table, - List *extra_fields, - List *keys, + Alter_info *alter_info, List *items, MYSQL_LOCK **lock, TABLEOP_HOOKS *hooks) @@ -3236,7 +3235,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, DBUG_RETURN(0); if (item->maybe_null) cr_field->flags &= ~NOT_NULL_FLAG; - extra_fields->push_back(cr_field); + alter_info->create_list.push_back(cr_field); } DBUG_EXECUTE_IF("sleep_create_select_before_create", my_sleep(6000000);); @@ -3261,8 +3260,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, tmp_disable_binlog(thd); if (!mysql_create_table_no_lock(thd, create_table->db, create_table->table_name, - create_info, *extra_fields, *keys, 0, - select_field_count, 0)) + create_info, alter_info, 0, + select_field_count)) { if (create_info->table_existed && @@ -3388,7 +3387,7 @@ select_create::prepare(List &values, SELECT_LEX_UNIT *u) } if (!(table= create_table_from_items(thd, create_info, create_table, - extra_fields, keys, &values, + alter_info, &values, &thd->extra_lock, hook_ptr))) DBUG_RETURN(-1); // abort() deletes table diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 7c900cf64d3..535a2492159 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1118,6 +1118,34 @@ int MYSQLlex(void *arg, void *yythd) } +Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) + :drop_list(rhs.drop_list, mem_root), + alter_list(rhs.alter_list, mem_root), + key_list(rhs.key_list, mem_root), + create_list(rhs.create_list, mem_root), + flags(rhs.flags), + keys_onoff(rhs.keys_onoff), + tablespace_op(rhs.tablespace_op), + partition_names(rhs.partition_names, mem_root), + no_parts(rhs.no_parts) +{ + /* + Make deep copies of used objects. + This is not a fully deep copy - clone() implementations + of Alter_drop, Alter_column, Key, foreign_key, key_part_spec + do not copy string constants. At the same length the only + reason we make a copy currently is that ALTER/CREATE TABLE + code changes input Alter_info definitions, but string + constants never change. + */ + list_copy_and_replace_each_value(drop_list, mem_root); + list_copy_and_replace_each_value(alter_list, mem_root); + list_copy_and_replace_each_value(key_list, mem_root); + list_copy_and_replace_each_value(create_list, mem_root); + /* partition_names are not deeply copied currently */ +} + + /* Skip comment in the end of statement. @@ -2379,3 +2407,22 @@ bool st_select_lex::add_index_hint (THD *thd, char *str, uint length) current_index_hint_clause, str, length)); } + +/** + A routine used by the parser to decide whether we are specifying a full + partitioning or if only partitions to add or to split. + + @note This needs to be outside of WITH_PARTITION_STORAGE_ENGINE since it + is used from the sql parser that doesn't have any #ifdef's + + @retval TRUE Yes, it is part of a management partition command + @retval FALSE No, not a management partition command +*/ + +bool st_lex::is_partition_management() const +{ + return (sql_command == SQLCOM_ALTER_TABLE && + (alter_info.flags == ALTER_ADD_PARTITION || + alter_info.flags == ALTER_REORGANIZE_PARTITION)); +} + diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ddd7c752e11..400535babf0 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -830,26 +830,60 @@ inline bool st_select_lex_unit::is_union () #define ALTER_REMOVE_PARTITIONING (1L << 25) #define ALTER_FOREIGN_KEY (1L << 26) -typedef struct st_alter_info +/** + @brief Parsing data for CREATE or ALTER TABLE. + + This structure contains a list of columns or indexes to be created, + altered or dropped. +*/ + +class Alter_info { +public: List drop_list; List alter_list; + List key_list; + List create_list; uint flags; enum enum_enable_or_disable keys_onoff; enum tablespace_op_type tablespace_op; List partition_names; uint no_parts; - st_alter_info(){clear();} - void clear() + Alter_info() : + flags(0), + keys_onoff(LEAVE_AS_IS), + tablespace_op(NO_TABLESPACE_OP), + no_parts(0) + {} + + void reset() { + drop_list.empty(); + alter_list.empty(); + key_list.empty(); + create_list.empty(); + flags= 0; keys_onoff= LEAVE_AS_IS; tablespace_op= NO_TABLESPACE_OP; no_parts= 0; partition_names.empty(); } - void reset(){drop_list.empty();alter_list.empty();clear();} -} ALTER_INFO; + /** + Construct a copy of this object to be used for mysql_alter_table + and mysql_create_table. Historically, these two functions modify + their Alter_info arguments. This behaviour breaks re-execution of + prepared statements and stored procedures and is compensated by + always supplying a copy of Alter_info to these functions. + + @return You need to use check the error in THD for out + of memory condition after calling this function. + */ + Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root); +private: + Alter_info &operator=(const Alter_info &rhs); // not implemented + Alter_info(const Alter_info &rhs); // not implemented +}; struct st_sp_chistics { @@ -1103,8 +1137,6 @@ typedef struct st_lex : public Query_tables_list List interval_list; List users_list; List columns; - List key_list; - List create_list; List *insert_list,field_list,value_list,update_list; List many_values; List var_list; @@ -1202,7 +1234,7 @@ typedef struct st_lex : public Query_tables_list bool safe_to_cache_query; bool subqueries, ignore; st_parsing_options parsing_options; - ALTER_INFO alter_info; + Alter_info alter_info; /* Prepared statements SQL syntax:*/ LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */ /* @@ -1361,6 +1393,7 @@ typedef struct st_lex : public Query_tables_list void restore_backup_query_tables_list(Query_tables_list *backup); bool table_or_sp_used(); + bool is_partition_management() const; } LEX; struct st_lex_local: public st_lex diff --git a/sql/sql_list.cc b/sql/sql_list.cc index 01ab9b91424..49b649133d0 100644 --- a/sql/sql_list.cc +++ b/sql/sql_list.cc @@ -36,3 +36,37 @@ void free_list(I_List *list) while ((tmp= list->get())) delete tmp; } + + +base_list::base_list(const base_list &rhs, MEM_ROOT *mem_root) +{ + if (rhs.elements) + { + /* + It's okay to allocate an array of nodes at once: we never + call a destructor for list_node objects anyway. + */ + first= (list_node*) alloc_root(mem_root, + sizeof(list_node) * rhs.elements); + if (first) + { + elements= rhs.elements; + list_node *dst= first; + list_node *src= rhs.first; + for (; dst < first + elements - 1; dst++, src= src->next) + { + dst->info= src->info; + dst->next= dst + 1; + } + /* Copy the last node */ + dst->info= src->info; + dst->next= &end_of_list; + /* Setup 'last' member */ + last= &dst->next; + return; + } + } + elements= 0; + first= &end_of_list; + last= &first; +} diff --git a/sql/sql_list.h b/sql/sql_list.h index ba61a931e04..486e297bd67 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -1,3 +1,5 @@ +#ifndef INCLUDES_MYSQL_SQL_LIST_H +#define INCLUDES_MYSQL_SQL_LIST_H /* Copyright (C) 2000-2003 MySQL AB This program is free software; you can redistribute it and/or modify @@ -63,21 +65,24 @@ public: pointer. */ -class list_node :public Sql_alloc + +/** + list_node - a node of a single-linked list. + @note We never call a destructor for instances of this class. +*/ + +struct list_node :public Sql_alloc { -public: list_node *next; void *info; list_node(void *info_par,list_node *next_par) :next(next_par),info(info_par) - {} + {} list_node() /* For end_of_list */ - { - info=0; - next= this; - } - friend class base_list; - friend class base_list_iterator; + { + info= 0; + next= this; + } }; @@ -93,12 +98,28 @@ public: inline void empty() { elements=0; first= &end_of_list; last=&first;} inline base_list() { empty(); } + /** + This is a shallow copy constructor that implicitly passes the ownership + from the source list to the new instance. The old instance is not + updated, so both objects end up sharing the same nodes. If one of + the instances then adds or removes a node, the other becomes out of + sync ('last' pointer), while still operational. Some old code uses and + relies on this behaviour. This logic is quite tricky: please do not use + it in any new code. + */ inline base_list(const base_list &tmp) :Sql_alloc() { elements= tmp.elements; first= tmp.first; last= elements ? tmp.last : &first; } + /** + Construct a deep copy of the argument in memory root mem_root. + The elements themselves are copied by pointer. If you also + need to copy elements by value, you should employ + list_copy_and_replace_each_value after creating a copy. + */ + base_list(const base_list &rhs, MEM_ROOT *mem_root); inline base_list(bool error) { } inline bool push_back(void *info) { @@ -185,6 +206,15 @@ public: elements+= list->elements; } } + /** + Swap two lists. + */ + inline void swap(base_list &rhs) + { + swap_variables(list_node *, first, rhs.first); + swap_variables(list_node **, last, rhs.last); + swap_variables(uint, elements, rhs.elements); + } inline list_node* last_node() { return *last; } inline list_node* first_node() { return first;} inline void *head() { return first->info; } @@ -349,6 +379,8 @@ template class List :public base_list public: inline List() :base_list() {} inline List(const List &tmp) :base_list(tmp) {} + inline List(const List &tmp, MEM_ROOT *mem_root) : + base_list(tmp, mem_root) {} inline bool push_back(T *a) { return base_list::push_back(a); } inline bool push_back(T *a, MEM_ROOT *mem_root) { return base_list::push_back(a, mem_root); } @@ -547,3 +579,32 @@ public: I_List_iterator(I_List &a) : base_ilist_iterator(a) {} inline T* operator++(int) { return (T*) base_ilist_iterator::next(); } }; + +/** + Make a deep copy of each list element. + + @note A template function and not a template method of class List + is employed because of explicit template instantiation: + in server code there are explicit instantiations of List and + an explicit instantiation of a template requires that any method + of the instantiated class used in the template can be resolved. + Evidently not all template arguments have clone() method with + the right signature. + + @return You must query the error state in THD for out-of-memory + situation after calling this function. +*/ + +template +inline +void +list_copy_and_replace_each_value(List &list, MEM_ROOT *mem_root) +{ + /* Make a deep copy of each element */ + List_iterator it(list); + T *el; + while ((el= it++)) + it.replace(el->clone(mem_root)); +} + +#endif // INCLUDES_MYSQL_SQL_LIST_H diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5ddfd7fd688..6d6f159a299 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2086,23 +2086,47 @@ mysql_execute_command(THD *thd) // Skip first table, which is the table we are creating TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local); TABLE_LIST *select_tables= lex->query_tables; + /* + Code below (especially in mysql_create_table() and select_create + methods) may modify HA_CREATE_INFO structure in LEX, so we have to + use a copy of this structure to make execution prepared statement- + safe. A shallow copy is enough as this code won't modify any memory + referenced from this structure. + */ + HA_CREATE_INFO create_info(lex->create_info); + /* + We need to copy alter_info for the same reasons of re-execution + safety, only in case of Alter_info we have to do (almost) a deep + copy. + */ + Alter_info alter_info(lex->alter_info, thd->mem_root); + + if (thd->is_fatal_error) + { + /* If out of memory when creating a copy of alter_info. */ + res= 1; + goto end_with_restore_list; + } if ((res= create_table_precheck(thd, select_tables, create_table))) goto end_with_restore_list; + /* Might have been updated in create_table_precheck */ + create_info.alias= create_table->alias; + #ifndef HAVE_READLINK - if (lex->create_info.data_file_name) + if (create_info.data_file_name) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, "DATA DIRECTORY option ignored"); - if (lex->create_info.index_file_name) + if (create_info.index_file_name) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, "INDEX DIRECTORY option ignored"); - lex->create_info.data_file_name=lex->create_info.index_file_name=0; + create_info.data_file_name= create_info.index_file_name= NULL; #else /* Fix names if symlinked tables */ - if (append_file_to_dir(thd, &lex->create_info.data_file_name, + if (append_file_to_dir(thd, &create_info.data_file_name, create_table->table_name) || - append_file_to_dir(thd, &lex->create_info.index_file_name, + append_file_to_dir(thd, &create_info.index_file_name, create_table->table_name)) goto end_with_restore_list; #endif @@ -2110,14 +2134,14 @@ mysql_execute_command(THD *thd) If we are using SET CHARSET without DEFAULT, add an implicit DEFAULT to not confuse old users. (This may change). */ - if ((lex->create_info.used_fields & + if ((create_info.used_fields & (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) == HA_CREATE_USED_CHARSET) { - lex->create_info.used_fields&= ~HA_CREATE_USED_CHARSET; - lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; - lex->create_info.default_table_charset= lex->create_info.table_charset; - lex->create_info.table_charset= 0; + create_info.used_fields&= ~HA_CREATE_USED_CHARSET; + create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + create_info.default_table_charset= create_info.table_charset; + create_info.table_charset= 0; } /* The create-select command will open and read-lock the select table @@ -2156,7 +2180,7 @@ mysql_execute_command(THD *thd) select_lex->options|= SELECT_NO_UNLOCK; unit->set_limit(select_lex); - if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) + if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE)) { lex->link_first_table_back(create_table, link_to_local); create_table->create= TRUE; @@ -2168,7 +2192,7 @@ mysql_execute_command(THD *thd) Is table which we are changing used somewhere in other parts of query */ - if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) + if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE)) { TABLE_LIST *duplicate; create_table= lex->unlink_first_table(&link_to_local); @@ -2180,10 +2204,10 @@ mysql_execute_command(THD *thd) } } /* If we create merge table, we have to test tables in merge, too */ - if (lex->create_info.used_fields & HA_CREATE_USED_UNION) + if (create_info.used_fields & HA_CREATE_USED_UNION) { TABLE_LIST *tab; - for (tab= (TABLE_LIST*) lex->create_info.merge_list.first; + for (tab= (TABLE_LIST*) create_info.merge_list.first; tab; tab= tab->next_local) { @@ -2198,18 +2222,15 @@ mysql_execute_command(THD *thd) } /* - FIXME Temporary hack which will go away once Kostja pushes - his uber-fix for ALTER/CREATE TABLE. + select_create is currently not re-execution friendly and + needs to be created for every execution of a PS/SP. */ - lex->create_info.table_existed= 0; - if ((result= new select_create(create_table, - &lex->create_info, - lex->create_list, - lex->key_list, - select_lex->item_list, - lex->duplicates, - lex->ignore))) + &create_info, + &alter_info, + select_lex->item_list, + lex->duplicates, + lex->ignore))) { /* CREATE from SELECT give its SELECT_LEX for SELECT, @@ -2218,29 +2239,25 @@ mysql_execute_command(THD *thd) res= handle_select(thd, lex, result, 0); delete result; } - /* reset for PS */ - lex->create_list.empty(); - lex->key_list.empty(); } - else if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) + else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE)) create_table= lex->unlink_first_table(&link_to_local); } else { /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */ - if (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) + if (create_info.options & HA_LEX_CREATE_TMP_TABLE) thd->options|= OPTION_KEEP_LOG; /* regular create */ - if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE) + if (create_info.options & HA_LEX_CREATE_TABLE_LIKE) res= mysql_create_like_table(thd, create_table, select_tables, - &lex->create_info); + &create_info); else { res= mysql_create_table(thd, create_table->db, - create_table->table_name, &lex->create_info, - lex->create_list, - lex->key_list, 0, 0, 1); + create_table->table_name, &create_info, + &alter_info, 0, 0); } if (!res) send_ok(thd); @@ -2252,15 +2269,46 @@ end_with_restore_list: break; } case SQLCOM_CREATE_INDEX: + /* Fall through */ + case SQLCOM_DROP_INDEX: + /* + CREATE INDEX and DROP INDEX are implemented by calling ALTER + TABLE with proper arguments. + + In the future ALTER TABLE will notice that the request is to + only add indexes and create these one by one for the existing + table without having to do a full rebuild. + */ + { + /* Prepare stack copies to be re-execution safe */ + HA_CREATE_INFO create_info; + Alter_info alter_info(lex->alter_info, thd->mem_root); + + if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */ + goto error; + DBUG_ASSERT(first_table == all_tables && first_table != 0); if (check_one_table_access(thd, INDEX_ACL, all_tables)) goto error; /* purecov: inspected */ - thd->enable_slow_log= opt_log_slow_admin_statements; if (end_active_trans(thd)) goto error; - res= mysql_create_index(thd, first_table, lex->key_list); - break; + /* + Currently CREATE INDEX or DROP INDEX cause a full table rebuild + and thus classify as slow administrative statements just like + ALTER TABLE. + */ + thd->enable_slow_log= opt_log_slow_admin_statements; + bzero((char*) &create_info, sizeof(create_info)); + create_info.db_type= 0; + create_info.row_type= ROW_TYPE_NOT_USED; + create_info.default_table_charset= thd->variables.collation_database; + + res= mysql_alter_table(thd, first_table->db, first_table->table_name, + &create_info, first_table, &alter_info, + 0, (ORDER*) 0, 0); + break; + } #ifdef HAVE_REPLICATION case SQLCOM_SLAVE_START: { @@ -2302,11 +2350,22 @@ end_with_restore_list: { ulong priv=0; ulong priv_needed= ALTER_ACL; + /* + Code in mysql_alter_table() may modify its HA_CREATE_INFO argument, + so we have to use a copy of this structure to make execution + prepared statement- safe. A shallow copy is enough as no memory + referenced from this structure will be modified. + */ + HA_CREATE_INFO create_info(lex->create_info); + Alter_info alter_info(lex->alter_info, thd->mem_root); + + if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */ + goto error; /* We also require DROP priv for ALTER TABLE ... DROP PARTITION, as well as for RENAME TO, as being done by SQLCOM_RENAME_TABLE */ - if (lex->alter_info.flags & (ALTER_DROP_PARTITION | ALTER_RENAME)) + if (alter_info.flags & (ALTER_DROP_PARTITION | ALTER_RENAME)) priv_needed|= DROP_ACL; /* Must be set in the parser */ @@ -2318,7 +2377,7 @@ end_with_restore_list: is_schema_db(select_lex->db))|| check_merge_table_access(thd, first_table->db, (TABLE_LIST *) - lex->create_info.merge_list.first)) + create_info.merge_list.first)) goto error; /* purecov: inspected */ if (grant_option) { @@ -2337,13 +2396,13 @@ end_with_restore_list: } } /* Don't yet allow changing of symlinks with ALTER TABLE */ - if (lex->create_info.data_file_name) + if (create_info.data_file_name) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, "DATA DIRECTORY option ignored"); - if (lex->create_info.index_file_name) + if (create_info.index_file_name) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, "INDEX DIRECTORY option ignored"); - lex->create_info.data_file_name=lex->create_info.index_file_name=0; + create_info.data_file_name= create_info.index_file_name= NULL; /* ALTER TABLE ends previous transaction */ if (end_active_trans(thd)) goto error; @@ -2357,12 +2416,12 @@ end_with_restore_list: thd->enable_slow_log= opt_log_slow_admin_statements; res= mysql_alter_table(thd, select_lex->db, lex->name.str, - &lex->create_info, - first_table, lex->create_list, - lex->key_list, + &create_info, + first_table, + &alter_info, select_lex->order_list.elements, (ORDER *) select_lex->order_list.first, - lex->ignore, &lex->alter_info, 1); + lex->ignore); break; } case SQLCOM_RENAME_TABLE: @@ -2505,7 +2564,7 @@ end_with_restore_list: goto error; /* purecov: inspected */ thd->enable_slow_log= opt_log_slow_admin_statements; res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ? - mysql_recreate_table(thd, first_table, 1) : + mysql_recreate_table(thd, first_table) : mysql_optimize_table(thd, first_table, &lex->check_opt); /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) @@ -2858,14 +2917,6 @@ end_with_restore_list: lex->drop_temporary); } break; - case SQLCOM_DROP_INDEX: - DBUG_ASSERT(first_table == all_tables && first_table != 0); - if (check_one_table_access(thd, INDEX_ACL, all_tables)) - goto error; /* purecov: inspected */ - if (end_active_trans(thd)) - goto error; - res= mysql_drop_index(thd, first_table, &lex->alter_info); - break; case SQLCOM_SHOW_PROCESSLIST: if (!thd->security_ctx->priv_user[0] && check_global_access(thd,PROCESS_ACL)) @@ -3005,6 +3056,12 @@ end_with_restore_list: break; case SQLCOM_CREATE_DB: { + /* + As mysql_create_db() may modify HA_CREATE_INFO structure passed to + it, we need to use a copy of LEX::create_info to make execution + prepared statement- safe. + */ + HA_CREATE_INFO create_info(lex->create_info); if (end_active_trans(thd)) { res= -1; @@ -3037,7 +3094,7 @@ end_with_restore_list: is_schema_db(lex->name.str))) break; res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : - lex->name.str), &lex->create_info, 0); + lex->name.str), &create_info, 0); break; } case SQLCOM_DROP_DB: @@ -3130,6 +3187,7 @@ end_with_restore_list: case SQLCOM_ALTER_DB: { LEX_STRING *db= &lex->name; + HA_CREATE_INFO create_info(lex->create_info); if (check_db_name(db)) { my_error(ER_WRONG_DB_NAME, MYF(0), db->str); @@ -3159,7 +3217,7 @@ end_with_restore_list: ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } - res= mysql_alter_db(thd, db->str, &lex->create_info); + res= mysql_alter_db(thd, db->str, &create_info); break; } case SQLCOM_SHOW_CREATE_DB: @@ -3750,7 +3808,7 @@ create_sp_error: goto error; } - my_bool nsok= thd->net.no_send_ok; + my_bool save_no_send_ok= thd->net.no_send_ok; thd->net.no_send_ok= TRUE; if (sp->m_flags & sp_head::MULTI_RESULTS) { @@ -3761,7 +3819,7 @@ create_sp_error: back */ my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str); - thd->net.no_send_ok= nsok; + thd->net.no_send_ok= save_no_send_ok; goto error; } /* @@ -3777,7 +3835,7 @@ create_sp_error: if (check_routine_access(thd, EXECUTE_ACL, sp->m_db.str, sp->m_name.str, TRUE, FALSE)) { - thd->net.no_send_ok= nsok; + thd->net.no_send_ok= save_no_send_ok; goto error; } #endif @@ -3802,7 +3860,7 @@ create_sp_error: thd->variables.select_limit= select_limit; - thd->net.no_send_ok= nsok; + thd->net.no_send_ok= save_no_send_ok; thd->server_status&= ~bits_to_be_cleared; if (!res) @@ -5432,18 +5490,22 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, } if (type_modifier & PRI_KEY_FLAG) { + Key *key; lex->col_list.push_back(new key_part_spec(field_name->str, 0)); - lex->key_list.push_back(new Key(Key::PRIMARY, NullS, - &default_key_create_info, - 0, lex->col_list)); + key= new Key(Key::PRIMARY, NullS, + &default_key_create_info, + 0, lex->col_list); + lex->alter_info.key_list.push_back(key); lex->col_list.empty(); } if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) { + Key *key; lex->col_list.push_back(new key_part_spec(field_name->str, 0)); - lex->key_list.push_back(new Key(Key::UNIQUE, NullS, - &default_key_create_info, 0, - lex->col_list)); + key= new Key(Key::UNIQUE, NullS, + &default_key_create_info, 0, + lex->col_list); + lex->alter_info.key_list.push_back(key); lex->col_list.empty(); } @@ -5503,7 +5565,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, interval_list, cs, uint_geom_type)) DBUG_RETURN(1); - lex->create_list.push_back(new_field); + lex->alter_info.create_list.push_back(new_field); lex->last_field=new_field; DBUG_RETURN(0); } @@ -6525,55 +6587,6 @@ Item * all_any_subquery_creator(Item *left_expr, } -/* - CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with - the proper arguments. This isn't very fast but it should work for most - cases. - - In the future ALTER TABLE will notice that only added indexes - and create these one by one for the existing table without having to do - a full rebuild. - - One should normally create all indexes with CREATE TABLE or ALTER TABLE. -*/ - -bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys) -{ - List fields; - ALTER_INFO alter_info; - alter_info.flags= ALTER_ADD_INDEX; - HA_CREATE_INFO create_info; - DBUG_ENTER("mysql_create_index"); - bzero((char*) &create_info,sizeof(create_info)); - create_info.db_type= 0; - create_info.default_table_charset= thd->variables.collation_database; - create_info.row_type= ROW_TYPE_NOT_USED; - DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name, - &create_info, table_list, - fields, keys, 0, (ORDER*)0, - 0, &alter_info, 1)); -} - - -bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) -{ - List fields; - List keys; - HA_CREATE_INFO create_info; - DBUG_ENTER("mysql_drop_index"); - bzero((char*) &create_info,sizeof(create_info)); - create_info.db_type= 0; - create_info.default_table_charset= thd->variables.collation_database; - create_info.row_type= ROW_TYPE_NOT_USED; - alter_info->clear(); - alter_info->flags= ALTER_DROP_INDEX; - DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name, - &create_info, table_list, - fields, keys, 0, (ORDER*)0, - 0, alter_info, 1)); -} - - /* Multi update query pre-check @@ -6885,7 +6898,6 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ? CREATE_TMP_ACL : CREATE_ACL); - lex->create_info.alias= create_table->alias; if (check_access(thd, want_priv, create_table->db, &create_table->grant.privilege, 0, 0, test(create_table->schema_table)) || diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 9b929900143..fda15a613a0 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -141,30 +141,6 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info, PARTITION_ITERATOR *part_iter); static void set_up_range_analysis_info(partition_info *part_info); -/* - A routine used by the parser to decide whether we are specifying a full - partitioning or if only partitions to add or to split. - - SYNOPSIS - is_partition_management() - lex Reference to the lex object - - RETURN VALUE - TRUE Yes, it is part of a management partition command - FALSE No, not a management partition command - - DESCRIPTION - This needs to be outside of WITH_PARTITION_STORAGE_ENGINE since it is - used from the sql parser that doesn't have any #ifdef's -*/ - -my_bool is_partition_management(LEX *lex) -{ - return (lex->sql_command == SQLCOM_ALTER_TABLE && - (lex->alter_info.flags == ALTER_ADD_PARTITION || - lex->alter_info.flags == ALTER_REORGANIZE_PARTITION)); -} - #ifdef WITH_PARTITION_STORAGE_ENGINE /* A support function to check if a name is in a list of strings @@ -4125,7 +4101,7 @@ error: change patterns. */ -uint prep_alter_part_table(THD *thd, TABLE *table, ALTER_INFO *alter_info, +uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, HA_CREATE_INFO *create_info, handlerton *old_db_type, bool *partition_changed, @@ -5991,8 +5967,6 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, alter_info ALTER TABLE info create_info Create info for CREATE TABLE table_list List of the table involved - create_list The fields in the resulting table - key_list The keys in the resulting table db Database name of new table table_name Table name of new table @@ -6006,11 +5980,10 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, */ uint fast_alter_partition_table(THD *thd, TABLE *table, - ALTER_INFO *alter_info, + Alter_info *alter_info, HA_CREATE_INFO *create_info, TABLE_LIST *table_list, - List *create_list, - List *key_list, char *db, + char *db, const char *table_name, uint fast_alter_partition) { @@ -6027,8 +6000,6 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, lpt->part_info= part_info; lpt->alter_info= alter_info; lpt->create_info= create_info; - lpt->create_list= create_list; - lpt->key_list= key_list; lpt->db_options= create_info->table_options; if (create_info->row_type == ROW_TYPE_DYNAMIC) lpt->db_options|= HA_OPTION_PACK_RECORD; @@ -6106,7 +6077,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, The first approach here was to downgrade locks. Now a different approach is decided upon. The idea is that the handler will have access to the - ALTER_INFO when store_lock arrives with TL_WRITE_ALLOW_READ. So if the + Alter_info when store_lock arrives with TL_WRITE_ALLOW_READ. So if the handler knows that this functionality can be handled with a lower lock level it will set the lock level to TL_WRITE_ALLOW_WRITE immediately. Thus the need to downgrade the lock disappears. @@ -6379,7 +6350,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, user */ DBUG_RETURN(fast_end_partition(thd, lpt->copied, lpt->deleted, - table, table_list, FALSE, lpt, + table, table_list, FALSE, NULL, written_bin_log)); } #endif diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d15cece0b5a..d9f50549ac0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -41,12 +41,16 @@ static int copy_data_between_tables(TABLE *from,TABLE *to, static bool prepare_blob_field(THD *thd, create_field *sql_field); static bool check_engine(THD *, const char *, HA_CREATE_INFO *); -static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, - List *fields, - List *keys, bool tmp_table, - uint *db_options, - handler *file, KEY **key_info_buffer, - uint *key_count, int select_field_count); +static bool +mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, + Alter_info *alter_info, + bool tmp_table, + uint *db_options, + handler *file, KEY **key_info_buffer, + uint *key_count, int select_field_count); +static bool +mysql_prepare_alter_table(THD *thd, HA_CREATE_INFO *create_info, + Alter_info *alter_info); #define MYSQL50_TABLE_NAME_PREFIX "#mysql50#" #define MYSQL50_TABLE_NAME_PREFIX_LENGTH 9 @@ -230,107 +234,13 @@ uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen) Return values for compare_tables(). If you make compare_tables() non-static, move them to a header file. */ -#define ALTER_TABLE_DATA_CHANGED 1 -#define ALTER_TABLE_INDEX_CHANGED 2 - -/* - SYNOPSIS - mysql_copy_create_list() - orig_create_list Original list of created fields - inout::new_create_list Copy of original list - - RETURN VALUES - FALSE Success - TRUE Memory allocation error - - DESCRIPTION - mysql_prepare_table destroys the create_list and in some cases we need - this lists for more purposes. Thus we copy it specifically for use - by mysql_prepare_table -*/ - -static int mysql_copy_create_list(List *orig_create_list, - List *new_create_list) +enum enum_compare_tables_result { - List_iterator prep_field_it(*orig_create_list); - create_field *prep_field; - DBUG_ENTER("mysql_copy_create_list"); - - while ((prep_field= prep_field_it++)) - { - create_field *field= new create_field(*prep_field); - if (!field || new_create_list->push_back(field)) - { - mem_alloc_error(2); - DBUG_RETURN(TRUE); - } - } - DBUG_RETURN(FALSE); -} - - -/* - SYNOPSIS - mysql_copy_key_list() - orig_key Original list of keys - inout::new_key Copy of original list - - RETURN VALUES - FALSE Success - TRUE Memory allocation error - - DESCRIPTION - mysql_prepare_table destroys the key list and in some cases we need - this lists for more purposes. Thus we copy it specifically for use - by mysql_prepare_table -*/ - -static int mysql_copy_key_list(List *orig_key, - List *new_key) -{ - List_iterator prep_key_it(*orig_key); - Key *prep_key; - DBUG_ENTER("mysql_copy_key_list"); - - while ((prep_key= prep_key_it++)) - { - List prep_columns; - List_iterator prep_col_it(prep_key->columns); - key_part_spec *prep_col; - Key *temp_key; - - while ((prep_col= prep_col_it++)) - { - key_part_spec *prep_key_part; - - if (!(prep_key_part= new key_part_spec(*prep_col))) - { - mem_alloc_error(sizeof(key_part_spec)); - DBUG_RETURN(TRUE); - } - if (prep_columns.push_back(prep_key_part)) - { - mem_alloc_error(2); - DBUG_RETURN(TRUE); - } - } - if (!(temp_key= new Key(prep_key->type, prep_key->name, - &prep_key->key_create_info, - prep_key->generated, - prep_columns))) - { - mem_alloc_error(sizeof(Key)); - DBUG_RETURN(TRUE); - } - if (new_key->push_back(temp_key)) - { - mem_alloc_error(2); - DBUG_RETURN(TRUE); - } - } - DBUG_RETURN(FALSE); -} + ALTER_TABLE_METADATA_ONLY= 0, + ALTER_TABLE_DATA_CHANGED= 1, + ALTER_TABLE_INDEX_CHANGED= 2 +}; /* -------------------------------------------------------------------------- @@ -1304,19 +1214,14 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) strxmov(shadow_frm_name, shadow_path, reg_ext, NullS); if (flags & WFRM_WRITE_SHADOW) { - if (mysql_copy_create_list(lpt->create_list, - &lpt->new_create_list) || - mysql_copy_key_list(lpt->key_list, - &lpt->new_key_list) || - mysql_prepare_table(lpt->thd, lpt->create_info, - &lpt->new_create_list, - &lpt->new_key_list, - /*tmp_table*/ 1, - &lpt->db_options, - lpt->table->file, - &lpt->key_info_buffer, - &lpt->key_count, - /*select_field_count*/ 0)) + if (mysql_prepare_create_table(lpt->thd, lpt->create_info, + lpt->alter_info, + /*tmp_table*/ 1, + &lpt->db_options, + lpt->table->file, + &lpt->key_info_buffer, + &lpt->key_count, + /*select_field_count*/ 0)) { DBUG_RETURN(TRUE); } @@ -1343,7 +1248,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) lpt->create_info->table_options= lpt->db_options; if ((mysql_create_frm(lpt->thd, shadow_frm_name, lpt->db, lpt->table_name, lpt->create_info, - lpt->new_create_list, lpt->key_count, + lpt->alter_info->create_list, lpt->key_count, lpt->key_info_buffer, lpt->table->file)) || lpt->table->file->create_handler_files(shadow_path, NULL, CHF_CREATE_FLAG, @@ -2029,7 +1934,7 @@ int prepare_create_field(create_field *sql_field, DBUG_ENTER("prepare_field"); /* - This code came from mysql_prepare_table. + This code came from mysql_prepare_create_table. Indent preserved to make patching easier */ DBUG_ASSERT(sql_field->charset); @@ -2130,7 +2035,8 @@ int prepare_create_field(create_field *sql_field, break; case MYSQL_TYPE_BIT: /* - We have sql_field->pack_flag already set here, see mysql_prepare_table(). + We have sql_field->pack_flag already set here, see + mysql_prepare_create_table(). */ break; case MYSQL_TYPE_NEWDECIMAL: @@ -2179,11 +2085,10 @@ int prepare_create_field(create_field *sql_field, Preparation for table creation SYNOPSIS - mysql_prepare_table() + mysql_prepare_create_table() thd Thread object. create_info Create information (like MAX_ROWS). - fields List of fields to create. - keys List of keys to create. + alter_info List of columns and indexes to create tmp_table If a temporary table is to be created. db_options INOUT Table options (like HA_OPTION_PACK_RECORD). file The handler for the new table. @@ -2198,16 +2103,17 @@ int prepare_create_field(create_field *sql_field, sets create_info->varchar if the table has a varchar RETURN VALUES - 0 ok - -1 error + FALSE OK + TRUE error */ -static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, - List *fields, - List *keys, bool tmp_table, - uint *db_options, - handler *file, KEY **key_info_buffer, - uint *key_count, int select_field_count) +static bool +mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, + Alter_info *alter_info, + bool tmp_table, + uint *db_options, + handler *file, KEY **key_info_buffer, + uint *key_count, int select_field_count) { const char *key_name; create_field *sql_field,*dup_field; @@ -2218,11 +2124,12 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, int timestamps= 0, timestamps_with_niladic= 0; int field_no,dup_no; int select_field_pos,auto_increment=0; - List_iterator it(*fields),it2(*fields); + List_iterator it(alter_info->create_list); + List_iterator it2(alter_info->create_list); uint total_uneven_bit_length= 0; - DBUG_ENTER("mysql_prepare_table"); + DBUG_ENTER("mysql_prepare_create_table"); - select_field_pos= fields->elements - select_field_count; + select_field_pos= alter_info->create_list.elements - select_field_count; null_fields=blob_columns=0; create_info->varchar= 0; max_key_length= file->max_key_length(); @@ -2257,7 +2164,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4), STRING_WITH_LEN("_bin")); my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* @@ -2271,26 +2178,23 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->sql_type == MYSQL_TYPE_SET || sql_field->sql_type == MYSQL_TYPE_ENUM)) { - Query_arena backup_arena; - bool need_to_change_arena= !thd->stmt_arena->is_conventional(); - if (need_to_change_arena) - { - /* Asser that we don't do that at every PS execute */ - DBUG_ASSERT(thd->stmt_arena->is_first_stmt_execute() || - thd->stmt_arena->is_first_sp_execute()); - thd->set_n_backup_active_arena(thd->stmt_arena, &backup_arena); - } - + /* + Starting from 5.1 we work here with a copy of create_field + created by the caller, not with the instance that was + originally created during parsing. It's OK to create + a temporary item and initialize with it a member of the + copy -- this item will be thrown away along with the copy + at the end of execution, and thus not introduce a dangling + pointer in the parsed tree of a prepared statement or a + stored procedure statement. + */ sql_field->def= sql_field->def->safe_charset_converter(save_cs); - if (need_to_change_arena) - thd->restore_active_arena(thd->stmt_arena, &backup_arena); - if (sql_field->def == NULL) { /* Could not convert */ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } @@ -2309,12 +2213,11 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (!interval) { /* - Create the typelib in prepared statement memory if we're - executing one. + Create the typelib in runtime memory - we will free the + occupied memory at the same time when we free this + sql_field -- at the end of execution. */ - MEM_ROOT *stmt_root= thd->stmt_arena->mem_root; - - interval= sql_field->interval= typelib(stmt_root, + interval= sql_field->interval= typelib(thd->mem_root, sql_field->interval_list); List_iterator int_it(sql_field->interval_list); String conv, *tmp; @@ -2331,7 +2234,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { uint cnv_errs; conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs); - interval->type_names[i]= strmake_root(stmt_root, conv.ptr(), + interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(), conv.length()); interval->type_lengths[i]= conv.length(); } @@ -2348,7 +2251,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, comma_buf, comma_length, NULL, 0)) { my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set", tmp->ptr()); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } @@ -2369,7 +2272,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if ((sql_field->flags & NOT_NULL_FLAG) != 0) { my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* else, NULL is an allowed value */ @@ -2385,7 +2288,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (not_found) { my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } calculate_interval_lengths(cs, interval, &dummy, &field_length); @@ -2403,7 +2306,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if ((sql_field->flags & NOT_NULL_FLAG) != 0) { my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* else, the defaults yield the correct length for NULLs. */ @@ -2414,7 +2317,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */ { my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } @@ -2435,7 +2338,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->create_length_to_internal_length(); if (prepare_blob_field(thd, sql_field)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (!(sql_field->flags & NOT_NULL_FLAG)) null_fields++; @@ -2443,7 +2346,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (check_column_name(sql_field->field_name)) { my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* Check if we have used the same field name before */ @@ -2460,7 +2363,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (field_no < select_field_pos || dup_no >= select_field_pos) { my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } else { @@ -2511,9 +2414,9 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (prepare_create_field(sql_field, &blob_columns, ×tamps, ×tamps_with_niladic, file->ha_table_flags())) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (sql_field->sql_type == MYSQL_TYPE_VARCHAR) - create_info->varchar= 1; + create_info->varchar= TRUE; sql_field->offset= record_offset; if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) auto_increment++; @@ -2523,31 +2426,32 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS, ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (auto_increment > 1) { my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (auto_increment && (file->ha_table_flags() & HA_NO_AUTO_INCREMENT)) { my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT, ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS)) { my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* Create keys */ - List_iterator key_iterator(*keys), key_iterator2(*keys); + List_iterator key_iterator(alter_info->key_list); + List_iterator key_iterator2(alter_info->key_list); uint key_parts=0, fk_key_count=0; bool primary_key=0,unique_key=0; Key *key, *key2; @@ -2573,7 +2477,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, my_error(ER_WRONG_FK_DEF, MYF(0), (fk_key->name ? fk_key->name : "foreign key without name"), ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } continue; } @@ -2582,7 +2486,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (key->columns.elements > tmp) { my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } key_name_str.str= (char*) key->name; key_name_str.length= key->name ? strlen(key->name) : 0; @@ -2590,7 +2494,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, system_charset_info, 1)) { my_error(ER_TOO_LONG_IDENT, MYF(0), key->name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } key_iterator2.rewind (); if (key->type != Key::FOREIGN_KEY) @@ -2630,20 +2534,20 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } tmp=file->max_keys(); if (*key_count > tmp) { my_error(ER_TOO_MANY_KEYS,MYF(0),tmp); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } (*key_info_buffer)= key_info= (KEY*) sql_calloc(sizeof(KEY) * (*key_count)); key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts); if (!*key_info_buffer || ! key_part_info) - DBUG_RETURN(-1); // Out of memory + DBUG_RETURN(TRUE); // Out of memory key_iterator.rewind(); key_number=0; @@ -2680,7 +2584,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, #else my_error(ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, sym_group_geom.needed_define); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); #endif case Key::FOREIGN_KEY: key_number--; // Skip this key @@ -2703,7 +2607,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { my_message(ER_TABLE_CANT_HANDLE_FT, ER(ER_TABLE_CANT_HANDLE_FT), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } /* @@ -2721,12 +2625,12 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { my_message(ER_TABLE_CANT_HANDLE_SPKEYS, ER(ER_TABLE_CANT_HANDLE_SPKEYS), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (key_info->key_parts != 1) { my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } else if (key_info->algorithm == HA_KEY_ALG_RTREE) @@ -2735,15 +2639,15 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if ((key_info->key_parts & 1) == 1) { my_error(ER_WRONG_ARGUMENTS, MYF(0), "RTREE INDEX"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* TODO: To be deleted */ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "RTREE INDEX"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); #else my_error(ER_FEATURE_DISABLED, MYF(0), sym_group_rtree.name, sym_group_rtree.needed_define); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); #endif } @@ -2776,7 +2680,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (!sql_field) { my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } while ((dup_column= cols2++) != column) { @@ -2786,7 +2690,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, my_printf_error(ER_DUP_FIELDNAME, ER(ER_DUP_FIELDNAME),MYF(0), column->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } cols2.rewind(); @@ -2819,7 +2723,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (key->type == Key::SPATIAL && column->length) { my_error(ER_WRONG_SUB_KEY, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (f_is_blob(sql_field->pack_flag) || @@ -2828,7 +2732,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS)) { my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type == Field::GEOM_POINT) @@ -2836,7 +2740,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (!column->length) { my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } #ifdef HAVE_SPATIAL @@ -2867,13 +2771,13 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (!(file->ha_table_flags() & HA_NULL_IN_KEY)) { my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (key->type == Key::SPATIAL) { my_message(ER_SPATIAL_CANT_HAVE_NULL, ER(ER_SPATIAL_CANT_HAVE_NULL), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } @@ -2909,7 +2813,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, else { my_error(ER_TOO_LONG_KEY,MYF(0),length); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } @@ -2922,7 +2826,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, column->length != length))) { my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS)) length=column->length; @@ -2930,7 +2834,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, else if (length == 0) { my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (length > file->max_key_part_length() && key->type != Key::FULLTEXT) { @@ -2949,7 +2853,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, else { my_error(ER_TOO_LONG_KEY,MYF(0),length); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } key_part_info->length=(uint16) length; @@ -2978,7 +2882,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } key_name=primary_key_name; primary_key=1; @@ -2989,7 +2893,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (check_if_keyname_exists(key_name, *key_info_buffer, key_info)) { my_error(ER_DUP_KEYNAME, MYF(0), key_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } key_info->name=(char*) key_name; } @@ -2997,7 +2901,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (!key_info->name || check_column_name(key_info->name)) { my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (!(key_info->flags & HA_NULL_PART_KEY)) unique_key=1; @@ -3005,7 +2909,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (key_length > max_key_length && key->type != Key::FULLTEXT) { my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } key_info++; } @@ -3013,19 +2917,19 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY)) { my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (auto_increment > 0) { my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* Sort keys in optimized order */ qsort((gptr) *key_info_buffer, *key_count, sizeof(KEY), (qsort_cmp) sort_keys); create_info->null_bits= null_fields; - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -3116,7 +3020,8 @@ static bool prepare_blob_field(THD *thd, create_field *sql_field) /* Preparation of create_field for SP function return values. - Based on code used in the inner loop of mysql_prepare_table() above + Based on code used in the inner loop of mysql_prepare_create_table() + above. SYNOPSIS sp_prepare_create_field() @@ -3164,31 +3069,6 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field) } -/* - Copy HA_CREATE_INFO struct - SYNOPSIS - copy_create_info() - lex_create_info The create_info struct setup by parser - RETURN VALUES - > 0 A pointer to a copy of the lex_create_info - 0 Memory allocation error - DESCRIPTION - Allocate memory for copy of HA_CREATE_INFO structure from parser - to ensure we can reuse the parser struct in stored procedures - and prepared statements. -*/ - -static HA_CREATE_INFO *copy_create_info(HA_CREATE_INFO *lex_create_info) -{ - HA_CREATE_INFO *create_info; - if (!(create_info= (HA_CREATE_INFO*)sql_alloc(sizeof(HA_CREATE_INFO)))) - mem_alloc_error(sizeof(HA_CREATE_INFO)); - else - memcpy((void*)create_info, (void*)lex_create_info, sizeof(HA_CREATE_INFO)); - return create_info; -} - - /* Create a table @@ -3197,15 +3077,12 @@ static HA_CREATE_INFO *copy_create_info(HA_CREATE_INFO *lex_create_info) thd Thread object db Database table_name Table name - lex_create_info Create information (like MAX_ROWS) + create_info Create information (like MAX_ROWS) fields List of fields to create keys List of keys to create internal_tmp_table Set to 1 if this is an internal temporary table (From ALTER TABLE) - select_field_count - use_copy_create_info Should we make a copy of create info (we do this - when this is called from sql_parse.cc where we - want to ensure lex object isn't manipulated. + select_field_count DESCRIPTION If one creates a temporary table, this is automatically opened @@ -3227,36 +3104,25 @@ static HA_CREATE_INFO *copy_create_info(HA_CREATE_INFO *lex_create_info) bool mysql_create_table_no_lock(THD *thd, const char *db, const char *table_name, - HA_CREATE_INFO *lex_create_info, - List &fields, - List &keys,bool internal_tmp_table, - uint select_field_count, - bool use_copy_create_info) + HA_CREATE_INFO *create_info, + Alter_info *alter_info, + bool internal_tmp_table, + uint select_field_count) { char path[FN_REFLEN]; uint path_length; const char *alias; uint db_options, key_count; KEY *key_info_buffer; - HA_CREATE_INFO *create_info; handler *file; bool error= TRUE; DBUG_ENTER("mysql_create_table_no_lock"); DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d", db, table_name, internal_tmp_table)); - if (use_copy_create_info) - { - if (!(create_info= copy_create_info(lex_create_info))) - { - DBUG_RETURN(TRUE); - } - } - else - create_info= lex_create_info; - + /* Check for duplicate fields and check type of table to create */ - if (!fields.elements) + if (!alter_info->create_list.elements) { my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS), MYF(0)); @@ -3308,7 +3174,7 @@ bool mysql_create_table_no_lock(THD *thd, Check that we don't use foreign keys in the table since it won't work even with InnoDB beneath it. */ - List_iterator key_iterator(keys); + List_iterator key_iterator(alter_info->key_list); Key *key; handlerton *part_engine_type= create_info->db_type; char *part_syntax_buf; @@ -3435,10 +3301,11 @@ bool mysql_create_table_no_lock(THD *thd, set_table_default_charset(thd, create_info, (char*) db); - if (mysql_prepare_table(thd, create_info, &fields, - &keys, internal_tmp_table, &db_options, file, - &key_info_buffer, &key_count, - select_field_count)) + if (mysql_prepare_create_table(thd, create_info, alter_info, + internal_tmp_table, + &db_options, file, + &key_info_buffer, &key_count, + select_field_count)) goto err; /* Check if table exists */ @@ -3546,7 +3413,8 @@ bool mysql_create_table_no_lock(THD *thd, create_info->table_options=db_options; path[path_length - reg_ext_length]= '\0'; // Remove .frm extension - if (rea_create_table(thd, path, db, table_name, create_info, fields, + if (rea_create_table(thd, path, db, table_name, + create_info, alter_info->create_list, key_count, key_info_buffer, file)) goto unlock_and_end; @@ -3598,10 +3466,9 @@ warn: bool mysql_create_table(THD *thd, const char *db, const char *table_name, HA_CREATE_INFO *create_info, - List &fields, - List &keys,bool internal_tmp_table, - uint select_field_count, - bool use_copy_create_info) + Alter_info *alter_info, + bool internal_tmp_table, + uint select_field_count) { TABLE *name_lock= 0; bool result; @@ -3651,9 +3518,9 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name, } result= mysql_create_table_no_lock(thd, db, table_name, create_info, - fields, keys, internal_tmp_table, - select_field_count, - use_copy_create_info); + alter_info, + internal_tmp_table, + select_field_count); unlock: if (name_lock) @@ -4307,10 +4174,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, (table->table->file->ha_check_for_upgrade(check_opt) == HA_ADMIN_NEEDS_ALTER)) { + my_bool save_no_send_ok= thd->net.no_send_ok; ha_autocommit_or_rollback(thd, 1); close_thread_tables(thd); tmp_disable_binlog(thd); // binlogging is done by caller if wanted - result_code= mysql_recreate_table(thd, table, 0); + thd->net.no_send_ok= TRUE; + result_code= mysql_recreate_table(thd, table); + thd->net.no_send_ok= save_no_send_ok; reenable_binlog(thd); goto send_result; } @@ -4389,6 +4259,7 @@ send_result_message: case HA_ADMIN_TRY_ALTER: { + my_bool save_no_send_ok= thd->net.no_send_ok; /* This is currently used only by InnoDB. ha_innobase::optimize() answers "try with alter", so here we close the table, do an ALTER TABLE, @@ -4400,7 +4271,9 @@ send_result_message: *save_next_global= table->next_global; table->next_local= table->next_global= 0; tmp_disable_binlog(thd); // binlogging is done by caller if wanted - result_code= mysql_recreate_table(thd, table, 0); + thd->net.no_send_ok= TRUE; + result_code= mysql_recreate_table(thd, table); + thd->net.no_send_ok= save_no_send_ok; reenable_binlog(thd); ha_autocommit_or_rollback(thd, 0); close_thread_tables(thd); @@ -4680,7 +4553,7 @@ bool mysql_preload_keys(THD* thd, TABLE_LIST* tables) */ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, - HA_CREATE_INFO *lex_create_info) + HA_CREATE_INFO *create_info) { TABLE *name_lock= 0; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; @@ -4690,17 +4563,12 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, int err; bool res= TRUE; uint not_used; - HA_CREATE_INFO *create_info; #ifdef WITH_PARTITION_STORAGE_ENGINE char tmp_path[FN_REFLEN]; #endif char ts_name[FN_LEN]; DBUG_ENTER("mysql_create_like_table"); - if (!(create_info= copy_create_info(lex_create_info))) - { - DBUG_RETURN(TRUE); - } /* CREATE TABLE ... LIKE is not allowed for views. */ src_table->required_type= FRMTYPE_TABLE; @@ -5006,12 +4874,18 @@ err: SYNOPSIS compare_tables() table The original table. - create_list The fields for the new table. - key_info_buffer An array of KEY structs for the new indexes. - key_count The number of elements in the array. + alter_info Alter options, fields and keys for the new + table. create_info Create options for the new table. - alter_info Alter options. order_num Number of order list elements. + need_copy_table OUT Result of the comparison. Undefined if error. + Otherwise is one of: + ALTER_TABLE_METADATA_ONLY No copy needed + ALTER_TABLE_DATA_CHANGED Data changes, + copy needed + ALTER_TABLE_INDEX_CHANGED Index changes, + copy might be needed + key_info_buffer OUT An array of KEY structs for new indexes index_drop_buffer OUT An array of offsets into table->key_info. index_drop_count OUT The number of elements in the array. index_add_buffer OUT An array of offsets into key_info_buffer. @@ -5033,27 +4907,69 @@ err: that need to be dropped and/or (re-)created. RETURN VALUES - 0 No copy needed - ALTER_TABLE_DATA_CHANGED Data changes, copy needed - ALTER_TABLE_INDEX_CHANGED Index changes, copy might be needed + TRUE error + FALSE success */ -static uint compare_tables(TABLE *table, List *create_list, - KEY *key_info_buffer, uint key_count, - HA_CREATE_INFO *create_info, - ALTER_INFO *alter_info, uint order_num, - uint *index_drop_buffer, uint *index_drop_count, - uint *index_add_buffer, uint *index_add_count, - bool varchar) +static +bool +compare_tables(TABLE *table, + Alter_info *alter_info, + HA_CREATE_INFO *create_info, + uint order_num, + enum enum_compare_tables_result *need_copy_table, + KEY **key_info_buffer, + uint **index_drop_buffer, uint *index_drop_count, + uint **index_add_buffer, uint *index_add_count) { Field **f_ptr, *field; uint changes= 0, tmp; - List_iterator_fast new_field_it(*create_list); + uint key_count; + List_iterator_fast new_field_it(alter_info->create_list); create_field *new_field; KEY_PART_INFO *key_part; KEY_PART_INFO *end; + /* + Remember if the new definition has new VARCHAR column; + create_info->varchar will be reset in mysql_prepare_create_table. + */ + bool varchar= create_info->varchar; DBUG_ENTER("compare_tables"); + { + THD *thd= table->in_use; + /* + Create a copy of alter_info. + To compare the new and old table definitions, we need to "prepare" + the new definition - transform it from parser output to a format + that describes the final table layout (all column defaults are + initialized, duplicate columns are removed). This is done by + mysql_prepare_create_table. Unfortunately, + mysql_prepare_create_table performs its transformations + "in-place", that is, modifies the argument. Since we would + like to keep compare_tables() idempotent (not altering any + of the arguments) we create a copy of alter_info here and + pass it to mysql_prepare_create_table, then use the result + to evaluate possibility of fast ALTER TABLE, and then + destroy the copy. + */ + Alter_info tmp_alter_info(*alter_info, thd->mem_root); + uint db_options= 0; /* not used */ + /* Create the prepared information. */ + if (mysql_prepare_create_table(thd, create_info, + &tmp_alter_info, + (table->s->tmp_table != NO_TMP_TABLE), + &db_options, + table->file, key_info_buffer, + &key_count, 0)) + DBUG_RETURN(1); + /* Allocate result buffers. */ + if (! (*index_drop_buffer= + (uint*) thd->alloc(sizeof(uint) * table->s->keys)) || + ! (*index_add_buffer= + (uint*) thd->alloc(sizeof(uint) * tmp_alter_info.key_list.elements))) + DBUG_RETURN(1); + } /* Some very basic checks. If number of fields changes, or the handler, we need to run full ALTER TABLE. In the future @@ -5080,7 +4996,7 @@ static uint compare_tables(TABLE *table, List *create_list, prior to 5.0 branch. See BUG#6236. */ - if (table->s->fields != create_list->elements || + if (table->s->fields != alter_info->create_list.elements || table->s->db_type() != create_info->db_type || table->s->tmp_table || create_info->used_fields & HA_CREATE_USED_ENGINE || @@ -5090,7 +5006,10 @@ static uint compare_tables(TABLE *table, List *create_list, order_num || !table->s->mysql_version || (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar)) - DBUG_RETURN(ALTER_TABLE_DATA_CHANGED); + { + *need_copy_table= ALTER_TABLE_DATA_CHANGED; + DBUG_RETURN(0); + } /* Go through fields and check if the original ones are compatible @@ -5106,7 +5025,10 @@ static uint compare_tables(TABLE *table, List *create_list, /* Check that NULL behavior is same for old and new fields */ if ((new_field->flags & NOT_NULL_FLAG) != (uint) (field->flags & NOT_NULL_FLAG)) - DBUG_RETURN(ALTER_TABLE_DATA_CHANGED); + { + *need_copy_table= ALTER_TABLE_DATA_CHANGED; + DBUG_RETURN(0); + } /* Don't pack rows in old tables if the user has requested this. */ if (create_info->row_type == ROW_TYPE_DYNAMIC || @@ -5124,7 +5046,10 @@ static uint compare_tables(TABLE *table, List *create_list, /* Evaluate changes bitmap and send to check_if_incompatible_data() */ if (!(tmp= field->is_equal(new_field))) - DBUG_RETURN(ALTER_TABLE_DATA_CHANGED); + { + *need_copy_table= ALTER_TABLE_DATA_CHANGED; + DBUG_RETURN(0); + } // Clear indexed marker field->flags&= ~FIELD_IN_ADD_INDEX; changes|= tmp; @@ -5137,7 +5062,7 @@ static uint compare_tables(TABLE *table, List *create_list, KEY *table_key; KEY *table_key_end= table->key_info + table->s->keys; KEY *new_key; - KEY *new_key_end= key_info_buffer + key_count; + KEY *new_key_end= *key_info_buffer + key_count; DBUG_PRINT("info", ("index count old: %d new: %d", table->s->keys, key_count)); @@ -5153,7 +5078,7 @@ static uint compare_tables(TABLE *table, List *create_list, KEY_PART_INFO *new_part; /* Search a new key with the same name. */ - for (new_key= key_info_buffer; new_key < new_key_end; new_key++) + for (new_key= *key_info_buffer; new_key < new_key_end; new_key++) { if (! strcmp(table_key->name, new_key->name)) break; @@ -5161,7 +5086,7 @@ static uint compare_tables(TABLE *table, List *create_list, if (new_key >= new_key_end) { /* Key not found. Add the offset of the key to the drop buffer. */ - index_drop_buffer[(*index_drop_count)++]= table_key - table->key_info; + (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info; DBUG_PRINT("info", ("index dropped: '%s'", table_key->name)); continue; } @@ -5194,8 +5119,8 @@ static uint compare_tables(TABLE *table, List *create_list, index_changed: /* Key modified. Add the offset of the key to both buffers. */ - index_drop_buffer[(*index_drop_count)++]= table_key - table->key_info; - index_add_buffer[(*index_add_count)++]= new_key - key_info_buffer; + (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info; + (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer; key_part= new_key->key_part; end= key_part + new_key->key_parts; for(; key_part != end; key_part++) @@ -5211,7 +5136,7 @@ static uint compare_tables(TABLE *table, List *create_list, /* Step through all keys of the new table and find matching old keys. */ - for (new_key= key_info_buffer; new_key < new_key_end; new_key++) + for (new_key= *key_info_buffer; new_key < new_key_end; new_key++) { /* Search an old key with the same name. */ for (table_key= table->key_info; table_key < table_key_end; table_key++) @@ -5222,7 +5147,7 @@ static uint compare_tables(TABLE *table, List *create_list, if (table_key >= table_key_end) { /* Key not found. Add the offset of the key to the add buffer. */ - index_add_buffer[(*index_add_count)++]= new_key - key_info_buffer; + (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer; key_part= new_key->key_part; end= key_part + new_key->key_parts; for(; key_part != end; key_part++) @@ -5237,12 +5162,19 @@ static uint compare_tables(TABLE *table, List *create_list, /* Check if changes are compatible with current handler without a copy */ if (table->file->check_if_incompatible_data(create_info, changes)) - DBUG_RETURN(ALTER_TABLE_DATA_CHANGED); + { + *need_copy_table= ALTER_TABLE_DATA_CHANGED; + DBUG_RETURN(0); + } if (*index_drop_count || *index_add_count) - DBUG_RETURN(ALTER_TABLE_INDEX_CHANGED); + { + *need_copy_table= ALTER_TABLE_INDEX_CHANGED; + DBUG_RETURN(0); + } - DBUG_RETURN(0); // Tables are compatible + *need_copy_table= ALTER_TABLE_METADATA_ONLY; // Tables are compatible + DBUG_RETURN(0); } @@ -5294,6 +5226,391 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, } +/** + Prepare column and key definitions for CREATE TABLE in ALTER TABLE. + + This function transforms parse output of ALTER TABLE - lists of + columns and keys to add, drop or modify into, essentially, + CREATE TABLE definition - a list of columns and keys of the new + table. While doing so, it also performs some (bug not all) + semantic checks. + + This function is invoked when we know that we're going to + perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE + is not possible, perhaps because the ALTER statement contains + instructions that require change in table data, not only in + table definition or indexes. + + @param[in,out] thd thread handle. Used as a memory pool + and source of environment information. + @param[in] table the source table, open and locked + Used as an interface to the storage engine + to acquire additional information about + the original table. + @param[in,out] create_info A blob with CREATE/ALTER TABLE + parameters + @param[in,out] alter_info Another blob with ALTER/CREATE parameters. + Originally create_info was used only in + CREATE TABLE and alter_info only in ALTER TABLE. + But since ALTER might end-up doing CREATE, + this distinction is gone and we just carry + around two structures. + + @return + Fills various create_info members based on information retrieved + from the storage engine. + Sets create_info->varchar if the table has a VARCHAR column. + Prepares alter_info->create_list and alter_info->key_list with + columns and keys of the new table. + @retval TRUE error, out of memory or a semantical error in ALTER + TABLE instructions + @retval FALSE success +*/ + +static bool +mysql_prepare_alter_table(THD *thd, TABLE *table, + HA_CREATE_INFO *create_info, + Alter_info *alter_info) +{ + /* New column definitions are added here */ + List new_create_list; + /* New key definitions are added here */ + List new_key_list; + List_iterator drop_it(alter_info->drop_list); + List_iterator def_it(alter_info->create_list); + List_iterator alter_it(alter_info->alter_list); + List_iterator key_it(alter_info->key_list); + List_iterator find_it(new_create_list); + List_iterator field_it(new_create_list); + List key_parts; + uint db_create_options= (table->s->db_create_options + & ~(HA_OPTION_PACK_RECORD)); + uint used_fields= create_info->used_fields; + KEY *key_info=table->key_info; + bool rc= TRUE; + + DBUG_ENTER("mysql_prepare_alter_table"); + + create_info->varchar= FALSE; + /* Let new create options override the old ones */ + if (!(used_fields & HA_CREATE_USED_MIN_ROWS)) + create_info->min_rows= table->s->min_rows; + if (!(used_fields & HA_CREATE_USED_MAX_ROWS)) + create_info->max_rows= table->s->max_rows; + if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH)) + create_info->avg_row_length= table->s->avg_row_length; + if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) + create_info->default_table_charset= table->s->table_charset; + if (!(used_fields & HA_CREATE_USED_AUTO) && table->found_next_number_field) + { + /* Table has an autoincrement, copy value to new table */ + table->file->info(HA_STATUS_AUTO); + create_info->auto_increment_value= table->file->stats.auto_increment_value; + } + if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) + create_info->key_block_size= table->s->key_block_size; + + if (!create_info->tablespace && create_info->storage_media != HA_SM_MEMORY) + { + char *tablespace= thd->alloc(FN_LEN); + /* + Regular alter table of disk stored table (no tablespace/storage change) + Copy tablespace name + */ + if (tablespace && + (table->file->get_tablespace_name(thd, tablespace, FN_LEN))) + create_info->tablespace= tablespace; + } + restore_record(table, s->default_values); // Empty record for DEFAULT + create_field *def; + + /* + First collect all fields from table which isn't in drop_list + */ + Field **f_ptr,*field; + for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++) + { + if (field->type() == MYSQL_TYPE_STRING) + create_info->varchar= TRUE; + /* Check if field should be dropped */ + Alter_drop *drop; + drop_it.rewind(); + while ((drop=drop_it++)) + { + if (drop->type == Alter_drop::COLUMN && + !my_strcasecmp(system_charset_info,field->field_name, drop->name)) + { + /* Reset auto_increment value if it was dropped */ + if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && + !(used_fields & HA_CREATE_USED_AUTO)) + { + create_info->auto_increment_value=0; + create_info->used_fields|=HA_CREATE_USED_AUTO; + } + break; + } + } + if (drop) + { + drop_it.remove(); + continue; + } + /* Check if field is changed */ + def_it.rewind(); + while ((def=def_it++)) + { + if (def->change && + !my_strcasecmp(system_charset_info,field->field_name, def->change)) + break; + } + if (def) + { // Field is changed + def->field=field; + if (!def->after) + { + new_create_list.push_back(def); + def_it.remove(); + } + } + else + { + /* + This field was not dropped and not changed, add it to the list + for the new table. + */ + def= new create_field(field, field); + new_create_list.push_back(def); + alter_it.rewind(); // Change default if ALTER + Alter_column *alter; + while ((alter=alter_it++)) + { + if (!my_strcasecmp(system_charset_info,field->field_name, alter->name)) + break; + } + if (alter) + { + if (def->sql_type == MYSQL_TYPE_BLOB) + { + my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change); + goto err; + } + if ((def->def=alter->def)) // Use new default + def->flags&= ~NO_DEFAULT_VALUE_FLAG; + else + def->flags|= NO_DEFAULT_VALUE_FLAG; + alter_it.remove(); + } + } + } + def_it.rewind(); + while ((def=def_it++)) // Add new columns + { + if (def->change && ! def->field) + { + my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name); + goto err; + } + if (!def->after) + new_create_list.push_back(def); + else if (def->after == first_keyword) + new_create_list.push_front(def); + else + { + create_field *find; + find_it.rewind(); + while ((find=find_it++)) // Add new columns + { + if (!my_strcasecmp(system_charset_info,def->after, find->field_name)) + break; + } + if (!find) + { + my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name); + goto err; + } + find_it.after(def); // Put element after this + } + } + if (alter_info->alter_list.elements) + { + my_error(ER_BAD_FIELD_ERROR, MYF(0), + alter_info->alter_list.head()->name, table->s->table_name); + goto err; + } + if (!new_create_list.elements) + { + my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS), + MYF(0)); + goto err; + } + + /* + Collect all keys which isn't in drop list. Add only those + for which some fields exists. + */ + + for (uint i=0 ; i < table->s->keys ; i++,key_info++) + { + char *key_name= key_info->name; + Alter_drop *drop; + drop_it.rewind(); + while ((drop=drop_it++)) + { + if (drop->type == Alter_drop::KEY && + !my_strcasecmp(system_charset_info,key_name, drop->name)) + break; + } + if (drop) + { + drop_it.remove(); + continue; + } + + KEY_PART_INFO *key_part= key_info->key_part; + key_parts.empty(); + for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) + { + if (!key_part->field) + continue; // Wrong field (from UNIREG) + const char *key_part_name=key_part->field->field_name; + create_field *cfield; + field_it.rewind(); + while ((cfield=field_it++)) + { + if (cfield->change) + { + if (!my_strcasecmp(system_charset_info, key_part_name, + cfield->change)) + break; + } + else if (!my_strcasecmp(system_charset_info, + key_part_name, cfield->field_name)) + break; + } + if (!cfield) + continue; // Field is removed + uint key_part_length=key_part->length; + if (cfield->field) // Not new field + { + /* + If the field can't have only a part used in a key according to its + new type, or should not be used partially according to its + previous type, or the field length is less than the key part + length, unset the key part length. + + We also unset the key part length if it is the same as the + old field's length, so the whole new field will be used. + + BLOBs may have cfield->length == 0, which is why we test it before + checking whether cfield->length < key_part_length (in chars). + */ + if (!Field::type_can_have_key_part(cfield->field->type()) || + !Field::type_can_have_key_part(cfield->sql_type) || + /* spatial keys can't have sub-key length */ + (key_info->flags & HA_SPATIAL) || + (cfield->field->field_length == key_part_length && + !f_is_blob(key_part->key_type)) || + (cfield->length && (cfield->length < key_part_length / + key_part->field->charset()->mbmaxlen))) + key_part_length= 0; // Use whole field + } + key_part_length /= key_part->field->charset()->mbmaxlen; + key_parts.push_back(new key_part_spec(cfield->field_name, + key_part_length)); + } + if (key_parts.elements) + { + KEY_CREATE_INFO key_create_info; + Key *key; + enum Key::Keytype key_type; + bzero((char*) &key_create_info, sizeof(key_create_info)); + + key_create_info.algorithm= key_info->algorithm; + if (key_info->flags & HA_USES_BLOCK_SIZE) + key_create_info.block_size= key_info->block_size; + if (key_info->flags & HA_USES_PARSER) + key_create_info.parser_name= *key_info->parser_name; + + if (key_info->flags & HA_SPATIAL) + key_type= Key::SPATIAL; + else if (key_info->flags & HA_NOSAME) + { + if (! my_strcasecmp(system_charset_info, key_name, primary_key_name)) + key_type= Key::PRIMARY; + else + key_type= Key::UNIQUE; + } + else if (key_info->flags & HA_FULLTEXT) + key_type= Key::FULLTEXT; + else + key_type= Key::MULTIPLE; + + key= new Key(key_type, key_name, + &key_create_info, + test(key_info->flags & HA_GENERATED_KEY), + key_parts); + new_key_list.push_back(key); + } + } + { + Key *key; + while ((key=key_it++)) // Add new keys + { + if (key->type != Key::FOREIGN_KEY) + new_key_list.push_back(key); + if (key->name && + !my_strcasecmp(system_charset_info,key->name,primary_key_name)) + { + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); + goto err; + } + } + } + + if (alter_info->drop_list.elements) + { + my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), + alter_info->drop_list.head()->name); + goto err; + } + if (alter_info->alter_list.elements) + { + my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), + alter_info->alter_list.head()->name); + goto err; + } + + if (!create_info->comment.str) + { + create_info->comment.str= table->s->comment.str; + create_info->comment.length= table->s->comment.length; + } + + table->file->update_create_info(create_info); + if ((create_info->table_options & + (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) || + (used_fields & HA_CREATE_USED_PACK_KEYS)) + db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); + if (create_info->table_options & + (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM)) + db_create_options&= ~(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM); + if (create_info->table_options & + (HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_NO_DELAY_KEY_WRITE)) + db_create_options&= ~(HA_OPTION_DELAY_KEY_WRITE | + HA_OPTION_NO_DELAY_KEY_WRITE); + create_info->table_options|= db_create_options; + + if (table->s->tmp_table) + create_info->options|=HA_LEX_CREATE_TMP_TABLE; + + rc= FALSE; + alter_info->create_list.swap(new_create_list); + alter_info->key_list.swap(new_key_list); +err: + DBUG_RETURN(rc); +} + + /* Alter table @@ -5302,21 +5619,14 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, thd Thread handle new_db If there is a RENAME clause new_name If there is a RENAME clause - lex_create_info Information from the parsing phase. Since some - clauses are common to CREATE and ALTER TABLE, the - data is stored in lex->create_info. The non-common - is stored in lex->alter_info. + create_info Information from the parsing phase about new + table properties. table_list The table to change. - fields lex->create_list - List of fields to be changed, - added or dropped. - keys lex->key_list - List of keys to be changed, added or - dropped. + alter_info Lists of fields, keys to be changed, added + or dropped. order_num How many ORDER BY fields has been specified. order List of fields to ORDER BY. ignore Whether we have ALTER IGNORE TABLE - alter_info Information from the parsing phase specific to ALTER - TABLE and not shared with CREATE TABLE. - do_send_ok Whether to call send_ok() on success. DESCRIPTION This is a veery long function and is everything but the kitchen sink :) @@ -5328,15 +5638,15 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, the table and/or enabling/disabling the keys. In this case, the FRM is not changed, directly by mysql_alter_table. However, if there is a RENAME + change of a field, or an index, the short cut is not used. - See how `fields` is used to generate the new FRM regarding the structure - of the fields. The same is done for the indices of the table. + See how `create_list` is used to generate the new FRM regarding the + structure of the fields. The same is done for the indices of the table. Important is the fact, that this function tries to do as little work as possible, by finding out whether a intermediate table is needed to copy data into and when finishing the altering to use it as the original table. For this reason the function compare_tables() is called, which decides based on all kind of data how similar are the new and the original - tables. + tables. RETURN VALUES FALSE OK @@ -5344,36 +5654,28 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, */ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, - HA_CREATE_INFO *lex_create_info, + HA_CREATE_INFO *create_info, TABLE_LIST *table_list, - List &fields, List &keys, - uint order_num, ORDER *order, bool ignore, - ALTER_INFO *alter_info, bool do_send_ok) + Alter_info *alter_info, + uint order_num, ORDER *order, bool ignore) { TABLE *table, *new_table= 0, *name_lock= 0; int error= 0; char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN]; char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; - char index_file[FN_REFLEN], data_file[FN_REFLEN], tablespace[FN_LEN]; + char index_file[FN_REFLEN], data_file[FN_REFLEN]; char path[FN_REFLEN]; char reg_path[FN_REFLEN+1]; ha_rows copied,deleted; - uint db_create_options, used_fields; handlerton *old_db_type, *new_db_type, *save_old_db_type; legacy_db_type table_type; - HA_CREATE_INFO *create_info; frm_type_enum frm_type; - uint need_copy_table= 0; - bool varchar= FALSE; + enum_compare_tables_result need_copy_table= ALTER_TABLE_METADATA_ONLY; #ifdef WITH_PARTITION_STORAGE_ENGINE uint fast_alter_partition= 0; bool partition_changed= FALSE; #endif - List prepared_create_list; - List prepared_key_list; bool need_lock_for_indexes= TRUE; - uint db_options= 0; - uint key_count; KEY *key_info_buffer; uint index_drop_count; uint *index_drop_buffer; @@ -5387,6 +5689,12 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, LINT_INIT(index_add_buffer); LINT_INIT(index_drop_buffer); + /* + Check if we attempt to alter mysql.slow_log or + mysql.general_log table and return an error if + it is the case. + TODO: this design is obsolete and will be removed. + */ if (table_list && table_list->db && table_list->table_name) { int table_kind= 0; @@ -5404,20 +5712,21 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, /* Disable alter of log tables to unsupported engine */ if (table_kind && - (lex_create_info->used_fields & HA_CREATE_USED_ENGINE) && - (!lex_create_info->db_type || /* unknown engine */ - !(lex_create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES))) + (create_info->used_fields & HA_CREATE_USED_ENGINE) && + (!create_info->db_type || /* unknown engine */ + !(create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES))) { my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0)); DBUG_RETURN(TRUE); } } + /* + Assign variables table_name, new_name, db, new_db, path, reg_path + to simplify further comparisions: we want to see if it's a RENAME + later just by comparing the pointers, avoiding the need for strcmp. + */ thd->proc_info="init"; - if (!(create_info= copy_create_info(lex_create_info))) - { - DBUG_RETURN(TRUE); - } table_name=table_list->table_name; alias= (lower_case_table_names == 2) ? table_list->alias : table_name; db=table_list->db; @@ -5426,7 +5735,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext, 0); build_table_filename(path, sizeof(path), db, table_name, "", 0); - used_fields=create_info->used_fields; mysql_ha_flush(thd, table_list, MYSQL_HA_CLOSE_FINAL, FALSE); @@ -5440,8 +5748,22 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, (void) unpack_filename(new_name_buff, new_name_buff); if (lower_case_table_names != 2) my_casedn_str(files_charset_info, new_name_buff); + /* + If this is just a rename of a view, short cut to the + following scenario: 1) lock LOCK_open 2) do a RENAME + 2) unlock LOCK_open. + This is a copy-paste added to make sure + ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled + as an independent branch in mysql_execute_command. The need + for a copy-paste arose because the main code flow of ALTER TABLE + ... RENAME tries to use open_ltable, which does not work for views + (open_ltable was never modified to merge table lists of child tables + into the main table list, like open_tables does). + This code is wrong and will be removed, please do not copy. + */ frm_type= mysql_frm_type(thd, new_name_buff, &table_type); /* Rename a view */ + /* Sic: there is a race here */ if (frm_type == FRMTYPE_VIEW && !(alter_info->flags & ~ALTER_RENAME)) { /* @@ -5487,18 +5809,6 @@ view_err: DBUG_RETURN(TRUE); table->use_all_columns(); - List_iterator drop_it(alter_info->drop_list); - List_iterator def_it(fields); - List_iterator alter_it(alter_info->alter_list); - List create_list; // Add new fields here - List key_list; // Add new keys here - List_iterator find_it(create_list); - List_iterator key_it(keys); - List_iterator field_it(create_list); - List key_parts; - - KEY *key_info=table->key_info; - /* Check that we are not trying to rename to an existing table */ if (new_name) { @@ -5581,14 +5891,17 @@ view_err: create_info->db_type= old_db_type; } -#ifdef WITH_PARTITION_STORAGE_ENGINE - if (prep_alter_part_table(thd, table, alter_info, create_info, old_db_type, - &partition_changed, &fast_alter_partition)) - goto err; -#endif if (check_engine(thd, new_name, create_info)) goto err; new_db_type= create_info->db_type; + + if (new_db_type != old_db_type && + !table->file->can_switch_engines()) + { + my_error(ER_ROW_IS_REFERENCED, MYF(0)); + goto err; + } + if (create_info->row_type == ROW_TYPE_NOT_USED) create_info->row_type= table->s->row_type; @@ -5704,8 +6017,7 @@ view_err: if (!error) { write_bin_log(thd, TRUE, thd->query, thd->query_length); - if (do_send_ok) - send_ok(thd); + send_ok(thd); } else if (error > 0) { @@ -5720,387 +6032,48 @@ view_err: DBUG_RETURN(error); } - /* We have to do full alter table */ - - /* Let new create options override the old ones */ - if (!(used_fields & HA_CREATE_USED_MIN_ROWS)) - create_info->min_rows= table->s->min_rows; - if (!(used_fields & HA_CREATE_USED_MAX_ROWS)) - create_info->max_rows= table->s->max_rows; - if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH)) - create_info->avg_row_length= table->s->avg_row_length; - if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) - create_info->default_table_charset= table->s->table_charset; - if (!(used_fields & HA_CREATE_USED_AUTO) && table->found_next_number_field) - { - /* Table has an autoincrement, copy value to new table */ - table->file->info(HA_STATUS_AUTO); - create_info->auto_increment_value= table->file->stats.auto_increment_value; - } - if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) - create_info->key_block_size= table->s->key_block_size; - - if (!create_info->tablespace && create_info->storage_media != HA_SM_MEMORY) - { - /* - Regular alter table of disk stored table (no tablespace/storage change) - Copy tablespace name - */ - if ((table->file->get_tablespace_name(thd, tablespace, FN_LEN))) - create_info->tablespace= tablespace; - } - restore_record(table, s->default_values); // Empty record for DEFAULT - create_field *def; + /* We have to do full alter table. */ +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (prep_alter_part_table(thd, table, alter_info, create_info, old_db_type, + &partition_changed, &fast_alter_partition)) + goto err; +#endif /* - First collect all fields from table which isn't in drop_list + If the old table had partitions and we are doing ALTER TABLE ... + engine= , the new table must preserve the original + partitioning. That means that the new engine is still the + partitioning engine, not the engine specified in the parser. + This is discovered in prep_alter_part_table, which in such case + updates create_info->db_type. + Now we need to update the stack copy of create_info->db_type, + as otherwise we won't be able to correctly move the files of the + temporary table to the result table files. */ + new_db_type= create_info->db_type; - Field **f_ptr,*field; - for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++) - { - if (field->type() == MYSQL_TYPE_STRING) - varchar= TRUE; - /* Check if field should be dropped */ - Alter_drop *drop; - drop_it.rewind(); - while ((drop=drop_it++)) - { - if (drop->type == Alter_drop::COLUMN && - !my_strcasecmp(system_charset_info,field->field_name, drop->name)) - { - /* Reset auto_increment value if it was dropped */ - if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && - !(used_fields & HA_CREATE_USED_AUTO)) - { - create_info->auto_increment_value=0; - create_info->used_fields|=HA_CREATE_USED_AUTO; - } - break; - } - } - if (drop) - { - drop_it.remove(); - continue; - } - /* Check if field is changed */ - def_it.rewind(); - while ((def=def_it++)) - { - if (def->change && - !my_strcasecmp(system_charset_info,field->field_name, def->change)) - break; - } - if (def) - { // Field is changed - def->field=field; - if (!def->after) - { - create_list.push_back(def); - def_it.remove(); - } - } - else - { - /* - This field was not dropped and not changed, add it to the list - for the new table. - */ - create_list.push_back(def=new create_field(field,field)); - alter_it.rewind(); // Change default if ALTER - Alter_column *alter; - while ((alter=alter_it++)) - { - if (!my_strcasecmp(system_charset_info,field->field_name, alter->name)) - break; - } - if (alter) - { - if (def->sql_type == MYSQL_TYPE_BLOB) - { - my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change); - goto err; - } - if ((def->def=alter->def)) // Use new default - def->flags&= ~NO_DEFAULT_VALUE_FLAG; - else - def->flags|= NO_DEFAULT_VALUE_FLAG; - alter_it.remove(); - } - } - } - def_it.rewind(); - while ((def=def_it++)) // Add new columns - { - if (def->change && ! def->field) - { - my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table_name); - goto err; - } - if (!def->after) - create_list.push_back(def); - else if (def->after == first_keyword) - create_list.push_front(def); - else - { - create_field *find; - find_it.rewind(); - while ((find=find_it++)) // Add new columns - { - if (!my_strcasecmp(system_charset_info,def->after, find->field_name)) - break; - } - if (!find) - { - my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table_name); - goto err; - } - find_it.after(def); // Put element after this - } - } - if (alter_info->alter_list.elements) - { - my_error(ER_BAD_FIELD_ERROR, MYF(0), - alter_info->alter_list.head()->name, table_name); + if (mysql_prepare_alter_table(thd, table, create_info, alter_info)) goto err; - } - if (!create_list.elements) - { - my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS), - MYF(0)); - goto err; - } - - /* - Collect all keys which isn't in drop list. Add only those - for which some fields exists. - */ - - for (uint i=0 ; i < table->s->keys ; i++,key_info++) - { - char *key_name= key_info->name; - Alter_drop *drop; - drop_it.rewind(); - while ((drop=drop_it++)) - { - if (drop->type == Alter_drop::KEY && - !my_strcasecmp(system_charset_info,key_name, drop->name)) - break; - } - if (drop) - { - drop_it.remove(); - continue; - } - - KEY_PART_INFO *key_part= key_info->key_part; - key_parts.empty(); - for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) - { - if (!key_part->field) - continue; // Wrong field (from UNIREG) - const char *key_part_name=key_part->field->field_name; - create_field *cfield; - field_it.rewind(); - while ((cfield=field_it++)) - { - if (cfield->change) - { - if (!my_strcasecmp(system_charset_info, key_part_name, - cfield->change)) - break; - } - else if (!my_strcasecmp(system_charset_info, - key_part_name, cfield->field_name)) - break; - } - if (!cfield) - continue; // Field is removed - uint key_part_length=key_part->length; - if (cfield->field) // Not new field - { - /* - If the field can't have only a part used in a key according to its - new type, or should not be used partially according to its - previous type, or the field length is less than the key part - length, unset the key part length. - - We also unset the key part length if it is the same as the - old field's length, so the whole new field will be used. - - BLOBs may have cfield->length == 0, which is why we test it before - checking whether cfield->length < key_part_length (in chars). - */ - if (!Field::type_can_have_key_part(cfield->field->type()) || - !Field::type_can_have_key_part(cfield->sql_type) || - /* spatial keys can't have sub-key length */ - (key_info->flags & HA_SPATIAL) || - (cfield->field->field_length == key_part_length && - !f_is_blob(key_part->key_type)) || - (cfield->length && (cfield->length < key_part_length / - key_part->field->charset()->mbmaxlen))) - key_part_length= 0; // Use whole field - } - key_part_length /= key_part->field->charset()->mbmaxlen; - key_parts.push_back(new key_part_spec(cfield->field_name, - key_part_length)); - } - if (key_parts.elements) - { - KEY_CREATE_INFO key_create_info; - bzero((char*) &key_create_info, sizeof(key_create_info)); - - key_create_info.algorithm= key_info->algorithm; - if (key_info->flags & HA_USES_BLOCK_SIZE) - key_create_info.block_size= key_info->block_size; - if (key_info->flags & HA_USES_PARSER) - key_create_info.parser_name= *key_info->parser_name; - - key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL : - (key_info->flags & HA_NOSAME ? - (!my_strcasecmp(system_charset_info, - key_name, primary_key_name) ? - Key::PRIMARY : Key::UNIQUE) : - (key_info->flags & HA_FULLTEXT ? - Key::FULLTEXT : Key::MULTIPLE)), - key_name, - &key_create_info, - test(key_info->flags & HA_GENERATED_KEY), - key_parts)); - } - } - { - Key *key; - while ((key=key_it++)) // Add new keys - { - if (key->type != Key::FOREIGN_KEY) - key_list.push_back(key); - if (key->name && - !my_strcasecmp(system_charset_info,key->name,primary_key_name)) - { - my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); - goto err; - } - } - } - - if (alter_info->drop_list.elements) - { - my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), - alter_info->drop_list.head()->name); - goto err; - } - if (alter_info->alter_list.elements) - { - my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), - alter_info->alter_list.head()->name); - goto err; - } - - db_create_options= table->s->db_create_options & ~(HA_OPTION_PACK_RECORD); - my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix, - current_pid, thd->thread_id); - /* Safety fix for innodb */ - if (lower_case_table_names) - my_casedn_str(files_charset_info, tmp_name); - if (new_db_type != old_db_type && !table->file->can_switch_engines()) { - my_error(ER_ROW_IS_REFERENCED, MYF(0)); - goto err; - } - create_info->db_type=new_db_type; - if (!create_info->comment.str) - { - create_info->comment.str= table->s->comment.str; - create_info->comment.length= table->s->comment.length; - } - - table->file->update_create_info(create_info); - if ((create_info->table_options & - (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) || - (used_fields & HA_CREATE_USED_PACK_KEYS)) - db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); - if (create_info->table_options & - (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM)) - db_create_options&= ~(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM); - if (create_info->table_options & - (HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_NO_DELAY_KEY_WRITE)) - db_create_options&= ~(HA_OPTION_DELAY_KEY_WRITE | - HA_OPTION_NO_DELAY_KEY_WRITE); - create_info->table_options|= db_create_options; - - if (table->s->tmp_table) - create_info->options|=HA_LEX_CREATE_TMP_TABLE; set_table_default_charset(thd, create_info, db); - { - /* - For some purposes we need prepared table structures and translated - key descriptions with proper default key name assignment. - - Unfortunately, mysql_prepare_table() modifies the field and key - lists. mysql_create_table() needs the unmodified lists. Hence, we - need to copy the lists and all their elements. The lists contain - pointers to the elements only. - - We cannot copy conditionally because the partition code always - needs prepared lists and compare_tables() needs them and is almost - always called. - */ - - /* Copy fields. */ - List_iterator prep_field_it(create_list); - create_field *prep_field; - while ((prep_field= prep_field_it++)) - prepared_create_list.push_back(new create_field(*prep_field)); - - /* Copy keys and key parts. */ - List_iterator prep_key_it(key_list); - Key *prep_key; - while ((prep_key= prep_key_it++)) - { - List prep_columns; - List_iterator prep_col_it(prep_key->columns); - key_part_spec *prep_col; - - while ((prep_col= prep_col_it++)) - prep_columns.push_back(new key_part_spec(*prep_col)); - prepared_key_list.push_back(new Key(prep_key->type, prep_key->name, - &prep_key->key_create_info, - prep_key->generated, prep_columns)); - } - - /* Create the prepared information. */ - if (mysql_prepare_table(thd, create_info, &prepared_create_list, - &prepared_key_list, - (table->s->tmp_table != NO_TMP_TABLE), &db_options, - table->file, &key_info_buffer, &key_count, 0)) - goto err; - } - if (thd->variables.old_alter_table || (table->s->db_type() != create_info->db_type) #ifdef WITH_PARTITION_STORAGE_ENGINE || partition_changed #endif ) - need_copy_table= 1; + need_copy_table= ALTER_TABLE_DATA_CHANGED; else { - /* Try to optimize ALTER TABLE. Allocate result buffers. */ - if (! (index_drop_buffer= - (uint*) thd->alloc(sizeof(uint) * table->s->keys)) || - ! (index_add_buffer= - (uint*) thd->alloc(sizeof(uint) * prepared_key_list.elements))) - goto err; /* Check how much the tables differ. */ - need_copy_table= compare_tables(table, &prepared_create_list, - key_info_buffer, key_count, - create_info, alter_info, order_num, - index_drop_buffer, &index_drop_count, - index_add_buffer, &index_add_count, - varchar); + if (compare_tables(table, alter_info, + create_info, order_num, + &need_copy_table, + &key_info_buffer, + &index_drop_buffer, &index_drop_count, + &index_add_buffer, &index_add_count)) + goto err; } /* @@ -6198,13 +6171,13 @@ view_err: if ((alter_flags & needed_online_flags) == needed_online_flags) { /* All required online flags are present. */ - need_copy_table= 0; + need_copy_table= ALTER_TABLE_METADATA_ONLY; need_lock_for_indexes= FALSE; } else if ((alter_flags & needed_fast_flags) == needed_fast_flags) { /* All required fast flags are present. */ - need_copy_table= 0; + need_copy_table= ALTER_TABLE_METADATA_ONLY; } } DBUG_PRINT("info", ("need_copy_table: %u need_lock: %d", @@ -6216,7 +6189,7 @@ view_err: alter_info->flags & ALTER_ADD_COLUMN|ALTER_ADD_INDEX|... so that ALTER TABLE won't break when somebody will add new flag */ - if (!need_copy_table) + if (need_copy_table == ALTER_TABLE_METADATA_ONLY) create_info->frm_only= 1; #ifdef WITH_PARTITION_STORAGE_ENGINE @@ -6225,12 +6198,17 @@ view_err: DBUG_ASSERT(!name_lock); DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info, create_info, table_list, - &create_list, &key_list, db, table_name, fast_alter_partition)); } #endif + my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix, + current_pid, thd->thread_id); + /* Safety fix for innodb */ + if (lower_case_table_names) + my_casedn_str(files_charset_info, tmp_name); + /* Handling of symlinked tables: If no rename: @@ -6284,14 +6262,15 @@ view_err: */ tmp_disable_binlog(thd); error= mysql_create_table_no_lock(thd, new_db, tmp_name, - create_info, create_list, - key_list, 1, 0, 0); + create_info, + alter_info, + 1, 0); reenable_binlog(thd); if (error) goto err; /* Open the table if we need to copy the data. */ - if (need_copy_table) + if (need_copy_table != ALTER_TABLE_METADATA_ONLY) { if (table->s->tmp_table) { @@ -6326,9 +6305,10 @@ view_err: /* We don't want update TIMESTAMP fields during ALTER TABLE. */ new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; new_table->next_number_field=new_table->found_next_number_field; - error=copy_data_between_tables(table, new_table, create_list, ignore, - order_num, order, &copied, &deleted, - alter_info->keys_onoff); + error= copy_data_between_tables(table, new_table, + alter_info->create_list, ignore, + order_num, order, &copied, &deleted, + alter_info->keys_onoff); } else { @@ -6358,26 +6338,6 @@ view_err: table->file->prepare_for_alter(); if (index_add_count) { -#ifdef XXX_TO_BE_DONE_LATER_BY_WL3020_AND_WL1892 - if (! need_lock_for_indexes) - { - /* Downgrade the write lock. */ - mysql_lock_downgrade_write(thd, table, TL_WRITE_ALLOW_WRITE); - } - - /* Create a new .frm file for crash recovery. */ - /* TODO: Must set INDEX_TO_BE_ADDED flags in the frm file. */ - VOID(pthread_mutex_lock(&LOCK_open)); - error= (mysql_create_frm(thd, reg_path, db, table_name, - create_info, prepared_create_list, key_count, - key_info_buffer, table->file) || - table->file->create_handler_files(reg_path, NULL, CHF_INDEX_FLAG, - create_info)); - VOID(pthread_mutex_unlock(&LOCK_open)); - if (error) - goto err1; -#endif - /* The add_index() method takes an array of KEY structs. */ key_info= (KEY*) thd->alloc(sizeof(KEY) * index_add_count); key= key_info; @@ -6410,36 +6370,6 @@ view_err: if (index_drop_count) { -#ifdef XXX_TO_BE_DONE_LATER_BY_WL3020_AND_WL1892 - /* Create a new .frm file for crash recovery. */ - /* TODO: Must set INDEX_IS_ADDED in the frm file. */ - /* TODO: Must set INDEX_TO_BE_DROPPED in the frm file. */ - VOID(pthread_mutex_lock(&LOCK_open)); - error= (mysql_create_frm(thd, reg_path, db, table_name, - create_info, prepared_create_list, key_count, - key_info_buffer, table->file) || - table->file->create_handler_files(reg_path, NULL, CHF_INDEX_FLAG, - create_info)); - VOID(pthread_mutex_unlock(&LOCK_open)); - if (error) - goto err1; - - if (! need_lock_for_indexes) - { - LOCK_PARAM_TYPE lpt; - - lpt.thd= thd; - lpt.table= table; - lpt.db= db; - lpt.table_name= table_name; - lpt.create_info= create_info; - lpt.create_list= &create_list; - lpt.key_count= key_count; - lpt.key_info_buffer= key_info_buffer; - abort_and_upgrade_lock(lpt); - } -#endif - /* The prepare_drop_index() method takes an array of key numbers. */ key_numbers= (uint*) thd->alloc(sizeof(uint) * index_drop_count); keyno_p= key_numbers; @@ -6459,27 +6389,6 @@ view_err: goto err1; } -#ifdef XXX_TO_BE_DONE_LATER_BY_WL3020 - if (! need_lock_for_indexes) - { - /* Downgrade the lock again. */ - if (table->reginfo.lock_type == TL_WRITE_ALLOW_READ) - { - LOCK_PARAM_TYPE lpt; - - lpt.thd= thd; - lpt.table= table; - lpt.db= db; - lpt.table_name= table_name; - lpt.create_info= create_info; - lpt.create_list= &create_list; - lpt.key_count= key_count; - lpt.key_info_buffer= key_info_buffer; - close_open_tables_and_downgrade(lpt); - } - } -#endif - /* Tell the handler to finally drop the indexes. */ if ((error= table->file->final_drop_index(table))) { @@ -6579,18 +6488,22 @@ view_err: table is renamed and the SE is also changed, then an intermediate table is created and the additional call will not take place. */ - if (!need_copy_table) - new_db_type=old_db_type= NULL; // this type cannot happen in regular ALTER + if (need_copy_table == ALTER_TABLE_METADATA_ONLY) + { + DBUG_ASSERT(new_db_type == old_db_type); + /* This type cannot happen in regular ALTER. */ + new_db_type= old_db_type= NULL; + } if (mysql_rename_table(old_db_type, db, table_name, db, old_name, FN_TO_IS_TMP)) { error=1; VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP)); } - else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db, + else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db, new_alias, FN_FROM_IS_TMP) || (new_name != table_name || new_db != db) && // we also do rename - (need_copy_table || + (need_copy_table != ALTER_TABLE_METADATA_ONLY || mysql_rename_table(save_old_db_type, db, table_name, new_db, new_alias, NO_FRM_RENAME)) && Table_triggers_list::change_table_name(thd, db, table_name, @@ -6610,7 +6523,7 @@ view_err: goto err_with_placeholders; } - if (! need_copy_table) + if (need_copy_table == ALTER_TABLE_METADATA_ONLY) { /* Now we have to inform handler that new .FRM file is in place. @@ -6691,7 +6604,7 @@ view_err: (create_info->options & HA_LEX_CREATE_TMP_TABLE))); write_bin_log(thd, TRUE, thd->query, thd->query_length); - if (ha_check_storage_engine_flag(old_db_type,HTON_FLUSH_AFTER_RENAME)) + if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME)) { /* For the alter table to be properly flushed to the logs, we @@ -6733,8 +6646,7 @@ end_temporary: my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO), (ulong) (copied + deleted), (ulong) deleted, (ulong) thd->cuted_fields); - if (do_send_ok) - send_ok(thd,copied+deleted,0L,tmp_name); + send_ok(thd, copied + deleted, 0L, tmp_name); thd->some_tables_deleted=0; DBUG_RETURN(FALSE); @@ -6975,31 +6887,26 @@ copy_data_between_tables(TABLE *from,TABLE *to, mysql_recreate_table() thd Thread handler tables Tables to recreate - do_send_ok If we should send_ok() or leave it to caller RETURN Like mysql_alter_table(). */ -bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, - bool do_send_ok) +bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list) { - DBUG_ENTER("mysql_recreate_table"); - LEX *lex= thd->lex; HA_CREATE_INFO create_info; - lex->create_list.empty(); - lex->key_list.empty(); - lex->col_list.empty(); - lex->alter_info.reset(); - bzero((char*) &create_info,sizeof(create_info)); + Alter_info alter_info; + + DBUG_ENTER("mysql_recreate_table"); + + bzero((char*) &create_info, sizeof(create_info)); create_info.db_type= 0; create_info.row_type=ROW_TYPE_NOT_USED; create_info.default_table_charset=default_charset_info; /* Force alter table to recreate table */ - lex->alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE); + alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE); DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info, - table_list, lex->create_list, - lex->key_list, 0, (ORDER *) 0, - 0, &lex->alter_info, do_send_ok)); + table_list, &alter_info, 0, + (ORDER *) 0, 0)); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 93df7db0605..3092b35a012 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -491,7 +491,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %pure_parser /* We have threads */ /* - Currently there is 287 shift/reduce conflict. We should not introduce + Currently there is 286 shift/reduce conflict. We should not introduce new conflicts any more. */ %expect 286 @@ -1569,8 +1569,7 @@ create: TL_OPTION_UPDATING, TL_WRITE)) MYSQL_YYABORT; - lex->create_list.empty(); - lex->key_list.empty(); + lex->alter_info.reset(); lex->col_list.empty(); lex->change=NullS; bzero((char*) &lex->create_info,sizeof(lex->create_info)); @@ -1603,21 +1602,23 @@ create: NULL, TL_OPTION_UPDATING)) MYSQL_YYABORT; - lex->create_list.empty(); - lex->key_list.empty(); + lex->alter_info.reset(); + lex->alter_info.flags= ALTER_ADD_INDEX; lex->col_list.empty(); lex->change=NullS; } '(' key_list ')' key_options { LEX *lex=Lex; + Key *key; if ($2 != Key::FULLTEXT && lex->key_create_info.parser_name.str) { my_parse_error(ER(ER_SYNTAX_ERROR)); MYSQL_YYABORT; } - lex->key_list.push_back(new Key($2, $4.str, &lex->key_create_info, 0, - lex->col_list)); + key= new Key($2, $4.str, &lex->key_create_info, 0, + lex->col_list); + lex->alter_info.key_list.push_back(key); lex->col_list.empty(); } | CREATE DATABASE opt_if_not_exists ident @@ -3931,7 +3932,7 @@ opt_part_values: /* empty */ { LEX *lex= Lex; - if (!is_partition_management(lex)) + if (! lex->is_partition_management()) { if (lex->part_info->part_type == RANGE_PARTITION) { @@ -3952,7 +3953,7 @@ opt_part_values: | VALUES LESS_SYM THAN_SYM part_func_max { LEX *lex= Lex; - if (!is_partition_management(lex)) + if (! lex->is_partition_management()) { if (Lex->part_info->part_type != RANGE_PARTITION) { @@ -3967,7 +3968,7 @@ opt_part_values: | VALUES IN_SYM '(' part_list_func ')' { LEX *lex= Lex; - if (!is_partition_management(lex)) + if (! lex->is_partition_management()) { if (Lex->part_info->part_type != LIST_PARTITION) { @@ -4478,8 +4479,9 @@ key_def: my_parse_error(ER(ER_SYNTAX_ERROR)); MYSQL_YYABORT; } - lex->key_list.push_back(new Key($1,$2, &lex->key_create_info, 0, - lex->col_list)); + Key *key= new Key($1, $2, &lex->key_create_info, 0, + lex->col_list); + lex->alter_info.key_list.push_back(key); lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint constraint_key_type opt_ident key_alg @@ -4487,24 +4489,27 @@ key_def: { LEX *lex=Lex; const char *key_name= $3 ? $3 : $1; - lex->key_list.push_back(new Key($2, key_name, &lex->key_create_info, 0, - lex->col_list)); + Key *key= new Key($2, key_name, &lex->key_create_info, 0, + lex->col_list); + lex->alter_info.key_list.push_back(key); lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references { LEX *lex=Lex; - lex->key_list.push_back(new foreign_key($4 ? $4:$1, lex->col_list, - $8, - lex->ref_list, - lex->fk_delete_opt, - lex->fk_update_opt, - lex->fk_match_option)); - lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4 : $1, - &default_key_create_info, 1, - lex->col_list)); + const char *key_name= $4 ? $4 : $1; + Key *key= new foreign_key(key_name, lex->col_list, + $8, + lex->ref_list, + lex->fk_delete_opt, + lex->fk_update_opt, + lex->fk_match_option); + lex->alter_info.key_list.push_back(key); + key= new Key(Key::MULTIPLE, key_name, + &default_key_create_info, 1, + lex->col_list); + lex->alter_info.key_list.push_back(key); lex->col_list.empty(); /* Alloced by sql_alloc */ - /* Only used for ALTER TABLE. Ignored otherwise. */ lex->alter_info.flags|= ALTER_FOREIGN_KEY; } @@ -5095,8 +5100,7 @@ alter: if (!lex->select_lex.add_table_to_list(thd, $4, NULL, TL_OPTION_UPDATING)) MYSQL_YYABORT; - lex->create_list.empty(); - lex->key_list.empty(); + lex->alter_info.reset(); lex->col_list.empty(); lex->select_lex.init_order(); lex->select_lex.db= @@ -5105,8 +5109,7 @@ alter: lex->create_info.db_type= 0; lex->create_info.default_table_charset= NULL; lex->create_info.row_type= ROW_TYPE_NOT_USED; - lex->alter_info.reset(); - lex->alter_info.flags= 0; + lex->alter_info.reset(); lex->no_write_to_binlog= 0; lex->create_info.storage_media= HA_SM_DEFAULT; } @@ -8141,7 +8144,8 @@ drop: { LEX *lex=Lex; lex->sql_command= SQLCOM_DROP_INDEX; - lex->alter_info.drop_list.empty(); + lex->alter_info.reset(); + lex->alter_info.flags= ALTER_DROP_INDEX; lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, $3.str)); if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL, From 96d16d96d12560b54da550d79ff0017d2976aacc Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 May 2007 13:50:33 +0200 Subject: [PATCH 34/74] Bug#24988 FLUSH PRIVILEGES causes brief unavailability - A race condition caused brief unavailablility when trying to acccess a table. - The unprotected variable 'grant_option' wasn't intended to alternate during normal execution. Variable initialization moved to grant_init a lines responsible for the alternation are removed. sql/mysqld.cc: - Added documentation to describe grant_option flag. sql/sql_acl.cc: - This patch removes lines which causes grant_option to alternate and moves variable initialization to the grant_init()-function. --- sql/mysqld.cc | 10 +++++++++- sql/sql_acl.cc | 11 ++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e5abef25b62..2253e67a1d7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -346,7 +346,15 @@ bool opt_endinfo, using_udf_functions; my_bool locked_in_memory; bool opt_using_transactions, using_update_log; bool volatile abort_loop; -bool volatile shutdown_in_progress, grant_option; +bool volatile shutdown_in_progress; +/** + @brief 'grant_option' is used to indicate if privileges needs + to be checked, in which case the lock, LOCK_grant, is used + to protect access to the grant table. + @note This flag is dropped in 5.1 + @see grant_init() + */ +bool volatile grant_option; my_bool opt_skip_slave_start = 0; // If set, slave is not autostarted my_bool opt_reckless_slave = 0; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ebf9385d177..ba6d03d6063 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2995,7 +2995,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, } } } - grant_option=TRUE; + thd->mem_root= old_root; pthread_mutex_unlock(&acl_cache->lock); @@ -3162,7 +3162,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, continue; } } - grant_option=TRUE; + thd->mem_root= old_root; pthread_mutex_unlock(&acl_cache->lock); if (!result && !no_error) @@ -3338,6 +3338,8 @@ my_bool grant_init() delete thd; /* Remember that we don't have a THD */ my_pthread_setspecific_ptr(THR_THD, 0); + /* Set the grant option flag so we will check grants */ + grant_option= TRUE; DBUG_RETURN(return_val); } @@ -3367,7 +3369,6 @@ static my_bool grant_load(TABLE_LIST *tables) THR_MALLOC); DBUG_ENTER("grant_load"); - grant_option = FALSE; (void) hash_init(&column_priv_hash,system_charset_info, 0,0,0, (hash_get_key) get_grant_table, (hash_free_key) free_grant_table,0); @@ -3478,7 +3479,6 @@ static my_bool grant_load(TABLE_LIST *tables) } while (!p_table->file->index_next(p_table->record[0])); } - grant_option= TRUE; return_val=0; // Return ok end_unlock: @@ -3511,7 +3511,6 @@ my_bool grant_reload(THD *thd) { TABLE_LIST tables[3]; HASH old_column_priv_hash, old_proc_priv_hash, old_func_priv_hash; - bool old_grant_option; MEM_ROOT old_mem; my_bool return_val= 1; DBUG_ENTER("grant_reload"); @@ -3541,7 +3540,6 @@ my_bool grant_reload(THD *thd) old_column_priv_hash= column_priv_hash; old_proc_priv_hash= proc_priv_hash; old_func_priv_hash= func_priv_hash; - old_grant_option= grant_option; old_mem= memex; if ((return_val= grant_load(tables))) @@ -3551,7 +3549,6 @@ my_bool grant_reload(THD *thd) column_priv_hash= old_column_priv_hash; /* purecov: deadcode */ proc_priv_hash= old_proc_priv_hash; func_priv_hash= old_func_priv_hash; - grant_option= old_grant_option; /* purecov: deadcode */ memex= old_mem; /* purecov: deadcode */ } else From 416122b29c0f73b6f70cf63a0411cf465fd307a8 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 May 2007 14:08:04 +0200 Subject: [PATCH 35/74] Bug#24988 FLUSH PRIVILEGES causes brief unavailability - A race condition caused brief unavailablility when trying to acccess a table. - The variable 'grant_option' was removed to resolve the race condition and to simplify the design pattern. This flag was originally intended to optimize grant checks. sql/mysql_priv.h: - removed 'grant_option' flag. sql/sql_acl.cc: - removed 'grant_option' flag. sql/sql_db.cc: - removed 'grant_option' flag. sql/sql_insert.cc: - removed 'grant_option' flag. sql/sql_parse.cc: - removed 'grant_option' flag. - removed unnecessary variables found_access, found sql/sql_show.cc: - removed 'grant_option' flag. sql/sql_update.cc: - removed 'grant_option' flag. sql/sql_view.cc: - removed 'grant_option' flag. --- sql/mysql_priv.h | 2 +- sql/sql_acl.cc | 38 ++++----------- sql/sql_db.cc | 2 +- sql/sql_insert.cc | 15 +++--- sql/sql_parse.cc | 121 ++++++++++++++++++---------------------------- sql/sql_show.cc | 6 +-- sql/sql_update.cc | 2 +- sql/sql_view.cc | 6 +-- 8 files changed, 71 insertions(+), 121 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 0b843d5610d..28611babf94 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1678,7 +1678,7 @@ extern ulong log_output_options; extern my_bool opt_log_queries_not_using_indexes; extern bool opt_disable_networking, opt_skip_show_db; extern my_bool opt_character_set_client_handshake; -extern bool volatile abort_loop, shutdown_in_progress, grant_option; +extern bool volatile abort_loop, shutdown_in_progress; extern uint volatile thread_count, thread_running, global_read_lock; extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types; extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 193ed5a92c8..119b1a49828 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3136,7 +3136,6 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, } } } - thd->mem_root= old_root; pthread_mutex_unlock(&acl_cache->lock); @@ -3310,7 +3309,6 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, continue; } } - thd->mem_root= old_root; pthread_mutex_unlock(&acl_cache->lock); if (!result && !no_error) @@ -3458,7 +3456,6 @@ bool mysql_grant(THD *thd, const char *db, List &list, void grant_free(void) { DBUG_ENTER("grant_free"); - grant_option = FALSE; hash_free(&column_priv_hash); hash_free(&proc_priv_hash); hash_free(&func_priv_hash); @@ -3493,8 +3490,6 @@ my_bool grant_init() delete thd; /* Remember that we don't have a THD */ my_pthread_setspecific_ptr(THR_THD, 0); - /* Set the grant option flag so we will check grants */ - grant_option= TRUE; DBUG_RETURN(return_val); } @@ -3553,7 +3548,6 @@ static my_bool grant_load(TABLE_LIST *tables) if (!(mem_check=new (memex_ptr) GRANT_TABLE(t_table,c_table))) { /* This could only happen if we are out memory */ - grant_option= FALSE; goto end_unlock; } @@ -3576,7 +3570,6 @@ static my_bool grant_load(TABLE_LIST *tables) else if (my_hash_insert(&column_priv_hash,(byte*) mem_check)) { delete mem_check; - grant_option= FALSE; goto end_unlock; } } @@ -3593,7 +3586,6 @@ static my_bool grant_load(TABLE_LIST *tables) if (!(mem_check=new (&memex) GRANT_NAME(p_table))) { /* This could only happen if we are out memory */ - grant_option= FALSE; goto end_unlock; } @@ -3632,7 +3624,6 @@ static my_bool grant_load(TABLE_LIST *tables) else if (my_hash_insert(hash, (byte*) mem_check)) { delete mem_check; - grant_option= FALSE; goto end_unlock; } } @@ -4004,8 +3995,6 @@ bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant, want_access &= ~grant->privilege; if (!want_access) return 0; // Already checked - if (!grant_option) - goto err2; rw_rdlock(&LOCK_grant); @@ -4195,18 +4184,15 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name, bool is_proc) { bool no_routine_acl= 1; - if (grant_option) - { - GRANT_NAME *grant_proc; - Security_context *sctx= thd->security_ctx; - rw_rdlock(&LOCK_grant); - if ((grant_proc= routine_hash_search(sctx->priv_host, - sctx->ip, db, - sctx->priv_user, - name, is_proc, 0))) - no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS); - rw_unlock(&LOCK_grant); - } + GRANT_NAME *grant_proc; + Security_context *sctx= thd->security_ctx; + rw_rdlock(&LOCK_grant); + if ((grant_proc= routine_hash_search(sctx->priv_host, + sctx->ip, db, + sctx->priv_user, + name, is_proc, 0))) + no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS); + rw_unlock(&LOCK_grant); return no_routine_acl; } @@ -6400,12 +6386,6 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, /* db privileges */ grant->privilege|= acl_get(sctx->host, sctx->ip, sctx->priv_user, db, 0); - if (!grant_option) - { - DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege)); - DBUG_VOID_RETURN; - } - /* table privileges */ rw_rdlock(&LOCK_grant); if (grant->version != grant_version) diff --git a/sql/sql_db.cc b/sql/sql_db.cc index cfd610638ce..a8f7eaa6394 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1448,7 +1448,7 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch) if (!force_switch && !(db_access & DB_ACLS) && - (!grant_option || check_grant_db(thd, new_db_file_name.str))) + check_grant_db(thd, new_db_file_name.str)) { my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 0268e1d3a41..8798714736a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -189,15 +189,12 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, return -1; } #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (grant_option) - { - Field_iterator_table field_it; - field_it.set_table(table); - if (check_grant_all_columns(thd, INSERT_ACL, &table->grant, - table->s->db.str, table->s->table_name.str, - &field_it)) - return -1; - } + Field_iterator_table field_it; + field_it.set_table(table); + if (check_grant_all_columns(thd, INSERT_ACL, &table->grant, + table->s->db.str, table->s->table_name.str, + &field_it)) + return -1; #endif clear_timestamp_auto_bits(table->timestamp_field_type, TIMESTAMP_AUTO_SET_ON_INSERT); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5ddfd7fd688..eb7a3c02667 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -987,8 +987,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege, 0, 0, test(table_list.schema_table))) break; - if (grant_option && - check_grant(thd, SELECT_ACL, &table_list, 2, UINT_MAX, 0)) + if (check_grant(thd, SELECT_ACL, &table_list, 2, UINT_MAX, 0)) break; /* init structures for VIEW processing */ table_list.select_lex= &(thd->lex->select_lex); @@ -2049,12 +2048,10 @@ mysql_execute_command(THD *thd) &first_table->grant.privilege, 0, 0, test(first_table->schema_table))) goto error; /* purecov: inspected */ - if (grant_option) - { - /* Check that the first table has CREATE privilege */ - if (check_grant(thd, CREATE_ACL, all_tables, 0, 1, 0)) - goto error; - } + /* Check that the first table has CREATE privilege */ + if (check_grant(thd, CREATE_ACL, all_tables, 0, 1, 0)) + goto error; + pthread_mutex_lock(&LOCK_active_mi); /* fetch_master_table will send the error to the client on failure. @@ -2320,22 +2317,20 @@ end_with_restore_list: (TABLE_LIST *) lex->create_info.merge_list.first)) goto error; /* purecov: inspected */ - if (grant_option) - { - if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0)) - goto error; - if (lex->name.str && !test_all_bits(priv,INSERT_ACL | CREATE_ACL)) - { // Rename of table - TABLE_LIST tmp_table; - bzero((char*) &tmp_table,sizeof(tmp_table)); - tmp_table.table_name= lex->name.str; - tmp_table.db=select_lex->db; - tmp_table.grant.privilege=priv; - if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, 0, - UINT_MAX, 0)) - goto error; - } + if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0)) + goto error; + if (lex->name.str && !test_all_bits(priv,INSERT_ACL | CREATE_ACL)) + { // Rename of table + TABLE_LIST tmp_table; + bzero((char*) &tmp_table,sizeof(tmp_table)); + tmp_table.table_name= lex->name.str; + tmp_table.db=select_lex->db; + tmp_table.grant.privilege=priv; + if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, 0, + UINT_MAX, 0)) + goto error; } + /* Don't yet allow changing of symlinks with ALTER TABLE */ if (lex->create_info.data_file_name) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0, @@ -2377,21 +2372,18 @@ end_with_restore_list: &table->next_local->grant.privilege, 0, 0, test(table->next_local->schema_table))) goto error; - if (grant_option) - { - TABLE_LIST old_list, new_list; - /* - we do not need initialize old_list and new_list because we will - come table[0] and table->next[0] there - */ - old_list= table[0]; - new_list= table->next_local[0]; - if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) || - (!test_all_bits(table->next_local->grant.privilege, - INSERT_ACL | CREATE_ACL) && - check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0))) - goto error; - } + TABLE_LIST old_list, new_list; + /* + we do not need initialize old_list and new_list because we will + come table[0] and table->next[0] there + */ + old_list= table[0]; + new_list= table->next_local[0]; + if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) || + (!test_all_bits(table->next_local->grant.privilege, + INSERT_ACL | CREATE_ACL) && + check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0))) + goto error; } query_cache_invalidate3(thd, first_table, 0); if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0)) @@ -2898,7 +2890,7 @@ end_with_restore_list: goto error; #else { - if (grant_option && check_access(thd, FILE_ACL, any_db,0,0,0,0)) + if (check_access(thd, FILE_ACL, any_db,0,0,0,0)) goto error; res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS); break; @@ -3345,8 +3337,7 @@ end_with_restore_list: uint grants= lex->all_privileges ? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL) : lex->grant; - if (grant_option && - check_grant_routine(thd, grants | GRANT_ACL, all_tables, + if (check_grant_routine(thd, grants | GRANT_ACL, all_tables, lex->type == TYPE_ENUM_PROCEDURE, 0)) goto error; /* Conditionally writes to binlog */ @@ -3357,10 +3348,8 @@ end_with_restore_list: } else { - if (grant_option && check_grant(thd, - (lex->grant | lex->grant_tot_col | - GRANT_ACL), - all_tables, 0, UINT_MAX, 0)) + if (check_grant(thd,(lex->grant | lex->grant_tot_col | GRANT_ACL), + all_tables, 0, UINT_MAX, 0)) goto error; /* Conditionally writes to binlog */ res= mysql_table_grant(thd, all_tables, lex->users_list, @@ -4475,8 +4464,7 @@ bool check_single_table_access(THD *thd, ulong privilege, goto deny; /* Show only 1 table for check_grant */ - if (grant_option && - !(all_tables->belong_to_view && + if (!(all_tables->belong_to_view && (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) && check_grant(thd, privilege, all_tables, 0, 1, no_errors)) goto deny; @@ -4644,9 +4632,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, db_access, want_access)); db_access= ((*save_priv=(db_access | sctx->master_access)) & want_access); - /* grant_option is set if there exists a single table or column grant */ if (db_access == want_access || - (grant_option && !dont_check_global_grants && + (!dont_check_global_grants && !(want_access & ~(db_access | TABLE_ACLS | PROC_ACLS)))) DBUG_RETURN(FALSE); /* Ok */ @@ -4745,8 +4732,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) test(dst_table->schema_table))) return FALSE; - return (grant_option && - check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE)); + return (check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE)); } default: break; @@ -4783,8 +4769,6 @@ bool check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, bool no_errors) { - uint found=0; - ulong found_access=0; #ifndef NO_EMBEDDED_ACCESS_CHECKS TABLE_LIST *org_tables= tables; #endif @@ -4835,26 +4819,17 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, tables->grant.privilege= want_access; else if (tables->db && thd->db && strcmp(tables->db, thd->db) == 0) { - if (found && !grant_option) // db already checked - tables->grant.privilege=found_access; - else - { - if (check_access(thd,want_access,tables->db,&tables->grant.privilege, + if (check_access(thd,want_access,tables->db,&tables->grant.privilege, 0, no_errors, test(tables->schema_table))) - goto deny; // Access denied - found_access=tables->grant.privilege; - found=1; - } + goto deny; // Access denied } else if (check_access(thd,want_access,tables->db,&tables->grant.privilege, 0, no_errors, test(tables->schema_table))) goto deny; } thd->security_ctx= backup_ctx; - if (grant_option) - return check_grant(thd,want_access & ~EXTRA_ACL,org_tables, + return check_grant(thd,want_access & ~EXTRA_ACL,org_tables, test(want_access & EXTRA_ACL), UINT_MAX, no_errors); - return FALSE; deny: thd->security_ctx= backup_ctx; return TRUE; @@ -4884,11 +4859,10 @@ check_routine_access(THD *thd, ulong want_access,char *db, char *name, return TRUE; #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (grant_option) return check_grant_routine(thd, want_access, tables, is_proc, no_errors); -#endif - +#else return FALSE; +#endif } @@ -4950,7 +4924,7 @@ bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table) if (!check_access(thd, access, table->db, &table->grant.privilege, 0, 1, test(table->schema_table)) && - !grant_option || !check_grant(thd, access, table, 0, 1, 1)) + !check_grant(thd, access, table, 0, 1, 1)) DBUG_RETURN(0); } } @@ -6611,12 +6585,11 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) else if ((check_access(thd, UPDATE_ACL, table->db, &table->grant.privilege, 0, 1, test(table->schema_table)) || - grant_option && check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) && (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0, test(table->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))) + check_grant(thd, SELECT_ACL, table, 0, 1, 0))) DBUG_RETURN(TRUE); table->table_in_first_from_clause= 1; @@ -6634,7 +6607,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) if (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0, test(table->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0)) + check_grant(thd, SELECT_ACL, table, 0, 1, 0)) DBUG_RETURN(TRUE); } } @@ -6856,7 +6829,7 @@ static bool check_show_create_table_access(THD *thd, TABLE_LIST *table) return check_access(thd, SELECT_ACL | EXTRA_ACL, table->db, &table->grant.privilege, 0, 0, test(table->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0); + check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0); } @@ -6893,7 +6866,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, (TABLE_LIST *) lex->create_info.merge_list.first)) goto err; - if (grant_option && want_priv != CREATE_TMP_ACL && + if (want_priv != CREATE_TMP_ACL && check_grant(thd, want_priv, create_table, 0, 1, 0)) goto err; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 175588368b3..dd9285c29d4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -706,7 +706,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname, else db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) | sctx->master_access); - if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) + if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname)) { my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), sctx->priv_user, sctx->host_or_ip, dbname); @@ -2649,7 +2649,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) &thd->col_access, 0, 1, with_i_schema) || sctx->master_access & (DB_ACLS | SHOW_DB_ACL) || acl_get(sctx->host, sctx->ip, sctx->priv_user, base_name,0) || - (grant_option && !check_grant_db(thd, base_name))) + !check_grant_db(thd, base_name)) #endif { List files; @@ -2849,7 +2849,7 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) #ifndef NO_EMBEDDED_ACCESS_CHECKS if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) || acl_get(sctx->host, sctx->ip, sctx->priv_user, file_name,0) || - (grant_option && !check_grant_db(thd, file_name))) + !check_grant_db(thd, file_name)) #endif { load_db_opt_by_name(thd, file_name, &create); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index ef384c30b59..33261963fcc 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -936,7 +936,7 @@ reopen_tables: if (check_access(thd, want_privilege, tl->db, &tl->grant.privilege, 0, 0, test(tl->schema_table)) || - (grant_option && check_grant(thd, want_privilege, tl, 0, 1, 0))) + check_grant(thd, want_privilege, tl, 0, 1, 0)) DBUG_RETURN(TRUE); } } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index bf48cd0094a..33ce0e78838 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -322,11 +322,11 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, */ if ((check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege, 0, 0, is_schema_db(view->db)) || - grant_option && check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) || + check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) || (mode != VIEW_CREATE_NEW && (check_access(thd, DROP_ACL, view->db, &view->grant.privilege, 0, 0, is_schema_db(view->db)) || - grant_option && check_grant(thd, DROP_ACL, view, 0, 1, 0)))) + check_grant(thd, DROP_ACL, view, 0, 1, 0)))) { res= TRUE; goto err; @@ -379,7 +379,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, { if (check_access(thd, SELECT_ACL, tbl->db, &tbl->grant.privilege, 0, 0, test(tbl->schema_table)) || - grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 0)) + check_grant(thd, SELECT_ACL, tbl, 0, 1, 0)) { res= TRUE; goto err; From 90b517adfe4b78e56c36b1ec59b3a7343649527a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 May 2007 16:31:16 +0400 Subject: [PATCH 36/74] Fix a compile-time warning. --- sql/sql_table.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d9f50549ac0..0662747d6b2 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -49,7 +49,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, handler *file, KEY **key_info_buffer, uint *key_count, int select_field_count); static bool -mysql_prepare_alter_table(THD *thd, HA_CREATE_INFO *create_info, +mysql_prepare_alter_table(THD *thd, TABLE *table, + HA_CREATE_INFO *create_info, Alter_info *alter_info); #define MYSQL50_TABLE_NAME_PREFIX "#mysql50#" From aae1ff670bd847feb0ecf2352dc8c9a156318c72 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 May 2007 15:23:12 +0200 Subject: [PATCH 37/74] Added missing result file mysql-test/r/rpl_critical_errors.result: Missing result file --- mysql-test/r/rpl_critical_errors.result | 1 + 1 file changed, 1 insertion(+) create mode 100644 mysql-test/r/rpl_critical_errors.result diff --git a/mysql-test/r/rpl_critical_errors.result b/mysql-test/r/rpl_critical_errors.result new file mode 100644 index 00000000000..bcc53565084 --- /dev/null +++ b/mysql-test/r/rpl_critical_errors.result @@ -0,0 +1 @@ +Turn on parsing to run this test From 32dd4b0b19c98cff48f1fb87e6ebb6c2b9ba4973 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 May 2007 16:46:22 +0200 Subject: [PATCH 38/74] Safemalloc memory dump reported as memory leak although it isn't. Waiting for fix in PB. --- mysql-test/t/disabled.def | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 12c5f38c680..464c4dae3f6 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -41,3 +41,6 @@ plugin : Bug#25659 memory leak via "plugins" test rpl_ndb_stm_innodb : Bug#26783 ndb_partition_error2 : HF is not sure if the test can work as internded on all the platforms + +mysql_client_test : safemalloc memory dump reported as memory leak although it isn't. Fix PB! + From f27bf2b4635202d73b2da712c2bb0f522083cc24 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 28 May 2007 22:20:22 +0300 Subject: [PATCH 39/74] Bug#22725 Replication outages from ER_SERVER_SHUTDOWN (1053) set in replication events The reason for the bug was that replaying of a query on slave could not be possible since its event was recorded with the killed error. Due to the specific of handling INSERT, which per-row-while-loop is unbreakable to killing, the query on transactional table should have not appeared in binlog unless there was a call to a stored routine that got interrupted with killing (and then there must be an error returned out of the loop). The offered solution added the following rule for binlogging of INSERT that accounts the above specifics: For INSERT on transactional-table if the error was not set the only raised flag is harmless and is ignored via masking out on time of creation of binlog event. For both table types the combination of raised error and KILLED flag indicates that there was potentially partial execution on master and consistency is under the question. In that case the code continues to binlog an event with an appropriate killed error. The fix relies on the specified behaviour of stored routine that must propagate the error to the top level query handling if the thd->killed flag was raised in the routine execution. The patch adds an arg with the default killed-status-unset value to Query_log_event::Query_log_event. sql/log_event.cc: killed_status as the value of thd->killed can be passed as an arg to the constructor. if the value is different from the default the arg is set to the current thd->killed value. A caller might need to masquerade thd->killed with THD::NOT_KILLED. So far only mysql_insert() uses such explicit way to tell the constructor about killing status. sql/log_event.h: default arg to the constructor with meaning of killed status of the query. if the arg is not explicitly provided the status of thd->killed will be snapshot inside of the constuctor, which is potentially incorrect (see bug#27571) sql/sql_class.h: extending killed_state with no-state member. sql/sql_insert.cc: ignore the KILLED flag incl KILL_BAD_DATA when the INSERT query event is created without an `error'; sql/sql_update.cc: Suggestion how to fix bug#27571 as comments. mysql-test/r/binlog_killed.result: new result file mysql-test/t/binlog_killed.test: regression tests also apply for bug27563, BUG#27565 --- mysql-test/r/binlog_killed.result | 106 +++++++++++++++ mysql-test/t/binlog_killed.test | 206 ++++++++++++++++++++++++++++++ sql/log_event.cc | 29 ++++- sql/log_event.h | 3 +- sql/sql_class.h | 12 +- sql/sql_insert.cc | 28 +++- sql/sql_update.cc | 31 +++++ 7 files changed, 406 insertions(+), 9 deletions(-) create mode 100644 mysql-test/r/binlog_killed.result create mode 100644 mysql-test/t/binlog_killed.test diff --git a/mysql-test/r/binlog_killed.result b/mysql-test/r/binlog_killed.result new file mode 100644 index 00000000000..196400eaf9e --- /dev/null +++ b/mysql-test/r/binlog_killed.result @@ -0,0 +1,106 @@ +create function bug27563() +RETURNS int(11) +DETERMINISTIC +begin +select get_lock("a", 10) into @a; +return 1; +end| +create function bug27565() +RETURNS int(11) +DETERMINISTIC +begin +select a from t1 where a=1 into @a for update; +return 1; +end| +create table t1 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; +create table t2 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=MyISAM; +create table t3 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; +reset master; +select get_lock("a", 20); +get_lock("a", 20) +1 +insert into t1 values (bug27563(),1); +kill query 3; +affected rows: 1 +show master status /* must be only FD event unless Bug#27563 */; +File Position Binlog_Do_DB Binlog_Ignore_DB +master-bin.000001 260 +select count(*) from t1 /* must be zero unless Bug#27563 */; +count(*) +1 +begin; +insert into t1 values (bug27563(),1); +kill query 3; +affected rows: 1 +select count(*) from t1 /* must be zero unless Bug#27563 */; +count(*) +2 +commit; +reset master; +insert into t2 values (bug27563(),1); +kill query 3; +select count(*) from t2 /* must be one */; +count(*) +1 +show master status /* must have the insert event more to FD */; +File Position Binlog_Do_DB Binlog_Ignore_DB +master-bin.000001 225 +select RELEASE_LOCK("a"); +RELEASE_LOCK("a") +1 +delete from t1; +delete from t2; +insert into t1 values (1,1); +insert into t2 values (1,1); +begin; +update t1 set b=0 where a=1; +update t2 set b=bug27565()-1 where a=1; +kill query 3; +commit; +Got one of the listed errors +select * from t1 /* must be: (1,0) */; +a b +1 0 +select * from t2 /* must be as before: (1,1) */; +a b +1 1 +delete from t3; +reset master; +begin; +update t1 set b=0 where a=1; +insert into t3 values (0,0),(1,bug27565()); +kill query 3; +rollback; +Got one of the listed errors +select count(*) from t3 /* must be zero */; +count(*) +0 +show master status /* nothing in binlog */; +File Position Binlog_Do_DB Binlog_Ignore_DB +master-bin.000001 98 +delete from t2; +reset master; +begin; +update t1 set b=0 where a=1; +insert into t2 values (0,0),(1,bug27565()) /* non-ta t2 */; +kill query 3; +rollback; +Got one of the listed errors +select count(*) from t2 /* count must be one */; +count(*) +1 +show master status /* insert into non-ta must be in binlog */; +File Position Binlog_Do_DB Binlog_Ignore_DB +master-bin.000001 247 +select +(@a:=load_file("MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) +is not null; +(@a:=load_file("MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) +is not null +1 +select @a like "%#%error_code=1317%" /* must return 1 */; +@a like "%#%error_code=1317%" +1 +drop table t1,t2,t3; +drop function bug27563; +drop function bug27565; diff --git a/mysql-test/t/binlog_killed.test b/mysql-test/t/binlog_killed.test new file mode 100644 index 00000000000..4e92632c218 --- /dev/null +++ b/mysql-test/t/binlog_killed.test @@ -0,0 +1,206 @@ +-- source include/have_innodb.inc + +### +### bug#22725 : incorrect killed error in binlogged query +### and +### Bug#27563 killing noticed in SF() stack but the error gets missed in action +### Bug#27565 killed query of SF() is not reported correctly and +### + +connect (con1, localhost, root,,); +connect (con2, localhost, root,,); + +# the function is *insensitive* to killing - TO FIX IN BUG#27563 +# the function is used in the test anyway with `TODO' left +# to correct results afterwards + +delimiter |; +create function bug27563() +RETURNS int(11) +DETERMINISTIC +begin + select get_lock("a", 10) into @a; + return 1; +end| +delimiter ;| + +# the function is sensitive to killing requiring innodb though with wrong client error +# TO FIX in BUG#27565; TODO: remove --error 1105 afterwards +delimiter |; +create function bug27565() +RETURNS int(11) +DETERMINISTIC +begin + select a from t1 where a=1 into @a for update; + return 1; +end| +delimiter ;| + +create table t1 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; +create table t2 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=MyISAM; +create table t3 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; +reset master; + + +### ta table case: killing causes rollback + +# A. autocommit ON +connection con1; +select get_lock("a", 20); + +connection con2; +let $ID= `select connection_id()`; +send insert into t1 values (bug27563(),1); + +connection con1; +eval kill query $ID; + +connection con2; +# todo (re-record test): after bugs 27563,27565 got fixed affected rows will report zero +--enable_info +# todo: remove 0 return after fixing Bug#27563 +--error 0,ER_QUERY_INTERRUPTED +reap; +--disable_info +###--replace_column 2 # 5 # +### show binlog events from 98 /* nothing in binlog unless Bug#27563 */; +show master status /* must be only FD event unless Bug#27563 */; +select count(*) from t1 /* must be zero unless Bug#27563 */; + +# M. multi-statement-ta +connection con2; +let $ID= `select connection_id()`; +begin; +send insert into t1 values (bug27563(),1); + +connection con1; +eval kill query $ID; +connection con2; +# todo (re-record test): after bugs 27563,27565 got fixed affected rows will report zero +--enable_info +# todo: remove 0 return after fixing Bug#27563 +--error 0,ER_QUERY_INTERRUPTED +reap; +--disable_info +select count(*) from t1 /* must be zero unless Bug#27563 */; +commit; + + +### non-ta table case: killing must be recorded in binlog + +reset master; + +connection con2; +let $ID= `select connection_id()`; +send insert into t2 values (bug27563(),1); + +connection con1; +eval kill query $ID; + +connection con2; +# todo: remove 0 return after fixing Bug#27563 +--error 0,ER_QUERY_INTERRUPTED +reap; +select count(*) from t2 /* must be one */; +#show binlog events from 98 /* must have the insert on non-ta table */; +show master status /* must have the insert event more to FD */; +# the value of the error flag of KILLED_QUERY is tested further + +connection con1; +select RELEASE_LOCK("a"); + +### test with effective killing of SF() + +delete from t1; +delete from t2; +insert into t1 values (1,1); +insert into t2 values (1,1); + +# +# Bug#27565 +# test where KILL is propagated as error to the top level +# still another bug with the error message to the user +# todo: fix reexecute the result file after fixing +# +begin; update t1 set b=0 where a=1; + +connection con2; +let $ID= `select connection_id()`; +send update t2 set b=bug27565()-1 where a=1; + +connection con1; +eval kill query $ID; +commit; + +connection con2; +# todo: fix Bug #27565 killed query of SF() is not reported correctly and +# remove 1105 (wrong) +#--error ER_QUERY_INTERRUPTED +--error 1105,ER_QUERY_INTERRUPTED +reap; +select * from t1 /* must be: (1,0) */; +select * from t2 /* must be as before: (1,1) */; + +## bug#22725 with effective and propagating killing +# +# top-level ta-table +connection con1; +delete from t3; +reset master; +begin; update t1 set b=0 where a=1; + +connection con2; +let $ID= `select connection_id()`; +# the query won't perform completely since the function gets interrupted +send insert into t3 values (0,0),(1,bug27565()); + +connection con1; +eval kill query $ID; +rollback; + +connection con2; +# todo: fix Bug #27565 killed query of SF() is not reported correctly and +# remove 1105 (wrong) +#--error ER_QUERY_INTERRUPTED +--error 1105,ER_QUERY_INTERRUPTED +reap; +select count(*) from t3 /* must be zero */; +show master status /* nothing in binlog */; + +# top-level non-ta-table +connection con1; +delete from t2; +reset master; +begin; update t1 set b=0 where a=1; + +connection con2; +let $ID= `select connection_id()`; +# the query won't perform completely since the function gets intrurrupted +send insert into t2 values (0,0),(1,bug27565()) /* non-ta t2 */; + +connection con1; +eval kill query $ID; +rollback; + +connection con2; +# todo: fix Bug #27565 killed query of SF() is not reported correctly and +# remove 1105 (wrong) +#--error ER_QUERY_INTERRUPTED +--error 1105,ER_QUERY_INTERRUPTED +reap; + +select count(*) from t2 /* count must be one */; +show master status /* insert into non-ta must be in binlog */; +--exec $MYSQL_BINLOG --start-position=126 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval select +(@a:=load_file("$MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) +is not null; +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +eval select @a like "%#%error_code=1317%" /* must return 1 */; +system rm $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog ; + +drop table t1,t2,t3; +drop function bug27563; +drop function bug27565; + diff --git a/sql/log_event.cc b/sql/log_event.cc index 173ca6232ee..6eb247488b0 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1279,20 +1279,31 @@ Query_log_event::Query_log_event() /* - Query_log_event::Query_log_event() + SYNOPSIS + Query_log_event::Query_log_event() + thd - thread handle + query_arg - array of char representing the query + query_length - size of the `query_arg' array + using_trans - there is a modified transactional table + suppress_use - suppress the generation of 'USE' statements + killed_status_arg - an optional with default to THD::KILLED_NO_VALUE + if the value is different from the default, the arg + is set to the current thd->killed value. + A caller might need to masquerade thd->killed with + THD::NOT_KILLED. + DESCRIPTION + Creates an event for binlogging + The value for local `killed_status' can be supplied by caller. */ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, bool using_trans, - bool suppress_use) + bool suppress_use, THD::killed_state killed_status_arg) :Log_event(thd_arg, ((thd_arg->tmp_table_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0) | (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0)), using_trans), data_buf(0), query(query_arg), catalog(thd_arg->catalog), db(thd_arg->db), q_len((uint32) query_length), - error_code((thd_arg->killed != THD::NOT_KILLED) ? - ((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? - 0 : thd->killed_errno()) : thd_arg->net.last_errno), thread_id(thd_arg->thread_id), /* save the original thread id; we already know the server id */ slave_proxy_id(thd_arg->variables.pseudo_thread_id), @@ -1304,6 +1315,14 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, charset_database_number(0) { time_t end_time; + + if (killed_status_arg == THD::KILLED_NO_VALUE) + killed_status_arg= thd_arg->killed; + error_code= + (killed_status_arg == THD::NOT_KILLED) ? thd_arg->net.last_errno : + ((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? 0 : + thd->killed_errno()); + time(&end_time); exec_time = (ulong) (end_time - thd->start_time); catalog_len = (catalog) ? (uint32) strlen(catalog) : 0; diff --git a/sql/log_event.h b/sql/log_event.h index a1e7adb6487..04aac5d08fc 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -804,7 +804,8 @@ public: #ifndef MYSQL_CLIENT Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, - bool using_trans, bool suppress_use); + bool using_trans, bool suppress_use, + THD::killed_state killed_err_arg= THD::KILLED_NO_VALUE); const char* get_db() { return db; } #ifdef HAVE_REPLICATION void pack_info(Protocol* protocol); diff --git a/sql/sql_class.h b/sql/sql_class.h index bef679806d0..62f4df0719f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1397,7 +1397,14 @@ public: DYNAMIC_ARRAY user_var_events; /* For user variables replication */ MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */ - enum killed_state { NOT_KILLED=0, KILL_BAD_DATA=1, KILL_CONNECTION=ER_SERVER_SHUTDOWN, KILL_QUERY=ER_QUERY_INTERRUPTED }; + enum killed_state + { + NOT_KILLED=0, + KILL_BAD_DATA=1, + KILL_CONNECTION=ER_SERVER_SHUTDOWN, + KILL_QUERY=ER_QUERY_INTERRUPTED, + KILLED_NO_VALUE /* means neither of the states */ + }; killed_state volatile killed; /* scramble - random string sent to client on handshake */ @@ -1670,7 +1677,8 @@ public: void end_statement(); inline int killed_errno() const { - return killed != KILL_BAD_DATA ? killed : 0; + killed_state killed_val; /* to cache the volatile 'killed' */ + return (killed_val= killed) != KILL_BAD_DATA ? killed_val : 0; } inline void send_kill_message() const { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 5720758128e..647681cdc1a 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -870,9 +870,35 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (mysql_bin_log.is_open()) { if (error <= 0) + { + /* + [Guilhem wrote] Temporary errors may have filled + thd->net.last_error/errno. For example if there has + been a disk full error when writing the row, and it was + MyISAM, then thd->net.last_error/errno will be set to + "disk full"... and the my_pwrite() will wait until free + space appears, and so when it finishes then the + write_row() was entirely successful + */ + /* todo: consider removing */ thd->clear_error(); + } + /* bug#22725: + + A query which per-row-loop can not be interrupted with + KILLED, like INSERT, and that does not invoke stored + routines can be binlogged with neglecting the KILLED error. + + If there was no error (error == zero) until after the end of + inserting loop the KILLED flag that appeared later can be + disregarded since previously possible invocation of stored + routines did not result in any error due to the KILLED. In + such case the flag is ignored for constructing binlog event. + */ Query_log_event qinfo(thd, thd->query, thd->query_length, - transactional_table, FALSE); + transactional_table, FALSE, + (error>0) ? thd->killed : THD::NOT_KILLED); + assert(thd->killed != THD::KILL_BAD_DATA || error > 0); if (mysql_bin_log.write(&qinfo) && transactional_table) error=1; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 222e33345cc..3f78c091d9b 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -521,6 +521,37 @@ int mysql_update(THD *thd, table->file->unlock_row(); thd->row_count++; } + + /* + todo bug#27571: to avoid asynchronization of `error' and + `error_code' of binlog event constructor + + The concept, which is a bit different for insert(!), is to + replace `error' assignment with the following lines + + killed_status= thd->killed; // get the status of the volatile + + Notice: thd->killed is type of "state" whereas the lhs has + "status" the suffix which translates according to WordNet: a state + at a particular time - at the time of the end of per-row loop in + our case. Binlogging ops are conducted with the status. + + error= (killed_status == THD::NOT_KILLED)? error : 1; + + which applies to most mysql_$query functions. + Event's constructor will accept `killed_status' as an argument: + + Query_log_event qinfo(..., killed_status); + + thd->killed might be changed after killed_status had got cached and this + won't affect binlogging event but other effects remain. + + Open issue: In a case the error happened not because of KILLED - + and then KILLED was caught later still within the loop - we shall + do something to avoid binlogging of incorrect ER_SERVER_SHUTDOWN + error_code. + */ + if (thd->killed && !error) error= 1; // Aborted end_read_record(&info); From 07485d9e0d3adc6c8528ee1f8af75d5c0418e0d3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 12:44:44 +0200 Subject: [PATCH 40/74] Fix for bug #28310 Server reports events which never were created Fix a race Wait at the end of the test for all events to finish. Then continue to the next result. This should be done, as the server won't be restarted, and although events are dropped with drop database, they could still be executing in memory. mysql-test/r/events_restart_phase3.result: fix result mysql-test/t/events_restart_phase3.test: Fix a race Wait at the end of the test for all events to finish. Then continue to the next result. This should be done, as the server won't be restarted, and although events are dropped with drop database, they could still be executing in memory. --- mysql-test/r/events_restart_phase3.result | 6 ------ mysql-test/t/events_restart_phase3.test | 6 ++++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/events_restart_phase3.result b/mysql-test/r/events_restart_phase3.result index 8ac00fdc70d..abed0a2babc 100644 --- a/mysql-test/r/events_restart_phase3.result +++ b/mysql-test/r/events_restart_phase3.result @@ -2,11 +2,5 @@ use events_test; select @@event_scheduler; @@event_scheduler ON -"Should get 3 rows : abc1, abc2, abc3 -select distinct name from execution_log order by name; -name -abc1 -abc2 -abc3 drop table execution_log; drop database events_test; diff --git a/mysql-test/t/events_restart_phase3.test b/mysql-test/t/events_restart_phase3.test index 1be40c72717..f5eeb1af2d9 100644 --- a/mysql-test/t/events_restart_phase3.test +++ b/mysql-test/t/events_restart_phase3.test @@ -11,8 +11,10 @@ use events_test; select @@event_scheduler; let $wait_condition=select count(distinct name)=3 from execution_log; --source include/wait_condition.inc ---echo "Should get 3 rows : abc1, abc2, abc3 -select distinct name from execution_log order by name; drop table execution_log; # Will drop all events drop database events_test; + +let $wait_condition= + select count(*) = 0 from information_schema.processlist + where db='events_test' and command = 'Connect' and user=current_user(); From 6cd313b86052acdf6f4f4fe3f731a3530d53239b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 13:37:38 +0200 Subject: [PATCH 41/74] Removed broken test from list of test to execute. To be restored when PB is patched to ignore requested safemalloc memory dumps. mysql-test/t/disabled.def: Restored disabled test file. --- mysql-test/t/disabled.def | 2 -- tests/mysql_client_test.c | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index d3bf05f4d33..10cea507ffe 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -41,5 +41,3 @@ rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly rpl_ndb_stm_innodb : Bug#26783 ndb_partition_error2 : HF is not sure if the test can work as internded on all the platforms -mysql_client_test : safemalloc memory dump reported as memory leak although it isn't. Fix PB! - diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 7af90480e2a..e614d44d83d 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16077,8 +16077,8 @@ static void test_bug24179() /* Bug#28075 "COM_DEBUG crashes mysqld" + Note: Test disabled because of failure in PushBuild. */ - static void test_bug28075() { int rc; @@ -16095,7 +16095,6 @@ static void test_bug28075() DBUG_VOID_RETURN; } - /* Read and parse arguments and MySQL options from my.cnf */ @@ -16380,7 +16379,9 @@ static struct my_tests_st my_tests[]= { { "test_status", test_status }, { "test_bug24179", test_bug24179 }, { "test_ps_query_cache", test_ps_query_cache }, +#ifdef fix_bug_in_pb_first { "test_bug28075", test_bug28075 }, +#endif { 0, 0 } }; From d4b3c91e63d09f78915691d37ea180af3969b508 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 15:05:35 +0200 Subject: [PATCH 42/74] Undefined unused function causing red in PushBuild. --- tests/mysql_client_test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index e614d44d83d..66eff66398f 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16079,6 +16079,7 @@ static void test_bug24179() Bug#28075 "COM_DEBUG crashes mysqld" Note: Test disabled because of failure in PushBuild. */ +#ifdef fix_bug_in_pb_first static void test_bug28075() { int rc; @@ -16094,6 +16095,7 @@ static void test_bug28075() DBUG_VOID_RETURN; } +#endif /* Read and parse arguments and MySQL options from my.cnf From 00710d17bbfac52eaac4a5283f4e08e8ffeefaf9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 16:27:55 +0300 Subject: [PATCH 43/74] Bug#22725 Replication outages from ER_SERVER_SHUTDOWN (1053) set in replication events Refining the tests since pb revealed the older version's fragality - the error from SF() due to killed may be different on different env:s. DBUG_ASSERT instead of assert. mysql-test/r/binlog_killed.result: new result file mysql-test/t/binlog_killed.test: regression for bug#22725 simplified. tests for bug27563, BUG#27565 made inactive. sql/sql_insert.cc: DBUG_ASSERT --- mysql-test/r/binlog_killed.result | 94 ++----------------------------- mysql-test/t/binlog_killed.test | 70 +++++++++++++++-------- sql/sql_insert.cc | 2 +- 3 files changed, 54 insertions(+), 112 deletions(-) diff --git a/mysql-test/r/binlog_killed.result b/mysql-test/r/binlog_killed.result index 196400eaf9e..cb5683a4792 100644 --- a/mysql-test/r/binlog_killed.result +++ b/mysql-test/r/binlog_killed.result @@ -1,106 +1,22 @@ -create function bug27563() -RETURNS int(11) -DETERMINISTIC -begin -select get_lock("a", 10) into @a; -return 1; -end| -create function bug27565() -RETURNS int(11) -DETERMINISTIC -begin -select a from t1 where a=1 into @a for update; -return 1; -end| create table t1 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; create table t2 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=MyISAM; create table t3 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; -reset master; select get_lock("a", 20); get_lock("a", 20) 1 -insert into t1 values (bug27563(),1); -kill query 3; -affected rows: 1 -show master status /* must be only FD event unless Bug#27563 */; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 260 -select count(*) from t1 /* must be zero unless Bug#27563 */; -count(*) -1 -begin; -insert into t1 values (bug27563(),1); -kill query 3; -affected rows: 1 -select count(*) from t1 /* must be zero unless Bug#27563 */; -count(*) -2 -commit; reset master; -insert into t2 values (bug27563(),1); +insert into t2 values (null, null), (null, get_lock("a", 10)),(null, get_lock("a", 10)); kill query 3; -select count(*) from t2 /* must be one */; +select count(*) from t2 /* must be 3 */; count(*) -1 -show master status /* must have the insert event more to FD */; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 225 -select RELEASE_LOCK("a"); -RELEASE_LOCK("a") -1 -delete from t1; -delete from t2; -insert into t1 values (1,1); -insert into t2 values (1,1); -begin; -update t1 set b=0 where a=1; -update t2 set b=bug27565()-1 where a=1; -kill query 3; -commit; -Got one of the listed errors -select * from t1 /* must be: (1,0) */; -a b -1 0 -select * from t2 /* must be as before: (1,1) */; -a b -1 1 -delete from t3; -reset master; -begin; -update t1 set b=0 where a=1; -insert into t3 values (0,0),(1,bug27565()); -kill query 3; -rollback; -Got one of the listed errors -select count(*) from t3 /* must be zero */; -count(*) -0 -show master status /* nothing in binlog */; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 98 -delete from t2; -reset master; -begin; -update t1 set b=0 where a=1; -insert into t2 values (0,0),(1,bug27565()) /* non-ta t2 */; -kill query 3; -rollback; -Got one of the listed errors -select count(*) from t2 /* count must be one */; -count(*) -1 -show master status /* insert into non-ta must be in binlog */; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 247 +3 select (@a:=load_file("MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) is not null; (@a:=load_file("MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) is not null 1 -select @a like "%#%error_code=1317%" /* must return 1 */; +select @a like "%#%error_code=1317%" /* must return 0 */; @a like "%#%error_code=1317%" -1 +0 drop table t1,t2,t3; -drop function bug27563; -drop function bug27565; diff --git a/mysql-test/t/binlog_killed.test b/mysql-test/t/binlog_killed.test index 4e92632c218..0bba72df867 100644 --- a/mysql-test/t/binlog_killed.test +++ b/mysql-test/t/binlog_killed.test @@ -2,18 +2,51 @@ ### ### bug#22725 : incorrect killed error in binlogged query -### and -### Bug#27563 killing noticed in SF() stack but the error gets missed in action -### Bug#27565 killed query of SF() is not reported correctly and ### connect (con1, localhost, root,,); connect (con2, localhost, root,,); -# the function is *insensitive* to killing - TO FIX IN BUG#27563 -# the function is used in the test anyway with `TODO' left -# to correct results afterwards +create table t1 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; +create table t2 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=MyISAM; +create table t3 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; +# +# effective test for bug#22725 +# + +connection con1; +select get_lock("a", 20); + +connection con2; +let $ID= `select connection_id()`; +reset master; +send insert into t2 values (null, null), (null, get_lock("a", 10)),(null, get_lock("a", 10)); + + +connection con1; +eval kill query $ID; + +connection con2; +reap; +select count(*) from t2 /* must be 3 */; + +--exec $MYSQL_BINLOG --start-position=126 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval select +(@a:=load_file("$MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) +is not null; +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +eval select @a like "%#%error_code=0%" /* must return 1 */; +eval select @a like "%insert%" /* must return 1 */; +# the functions are either *insensitive* to killing or killing can cause +# strange problmes with the error propagation out of SF's stack +# Bug#27563, Bug#27565, BUG#24971 +# +# TODO: use if's block as regression test for the bugs or remove +# +if (0) +{ delimiter |; create function bug27563() RETURNS int(11) @@ -36,9 +69,6 @@ begin end| delimiter ;| -create table t1 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; -create table t2 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=MyISAM; -create table t3 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; reset master; @@ -60,7 +90,7 @@ connection con2; --enable_info # todo: remove 0 return after fixing Bug#27563 --error 0,ER_QUERY_INTERRUPTED -reap; +reap; ### pb: wrong error --disable_info ###--replace_column 2 # 5 # ### show binlog events from 98 /* nothing in binlog unless Bug#27563 */; @@ -137,7 +167,7 @@ connection con2; # remove 1105 (wrong) #--error ER_QUERY_INTERRUPTED --error 1105,ER_QUERY_INTERRUPTED -reap; +reap; ### pb: wrong error select * from t1 /* must be: (1,0) */; select * from t2 /* must be as before: (1,1) */; @@ -163,7 +193,7 @@ connection con2; # remove 1105 (wrong) #--error ER_QUERY_INTERRUPTED --error 1105,ER_QUERY_INTERRUPTED -reap; +reap; ### pb: wrong error select count(*) from t3 /* must be zero */; show master status /* nothing in binlog */; @@ -187,20 +217,16 @@ connection con2; # remove 1105 (wrong) #--error ER_QUERY_INTERRUPTED --error 1105,ER_QUERY_INTERRUPTED -reap; +reap; ### pb: wrong error select count(*) from t2 /* count must be one */; show master status /* insert into non-ta must be in binlog */; ---exec $MYSQL_BINLOG --start-position=126 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR -eval select -(@a:=load_file("$MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) -is not null; ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR -eval select @a like "%#%error_code=1317%" /* must return 1 */; + +drop function bug27563; +drop function bug27565; +} + system rm $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog ; drop table t1,t2,t3; -drop function bug27563; -drop function bug27565; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 647681cdc1a..bf37a3d6d69 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -898,7 +898,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, Query_log_event qinfo(thd, thd->query, thd->query_length, transactional_table, FALSE, (error>0) ? thd->killed : THD::NOT_KILLED); - assert(thd->killed != THD::KILL_BAD_DATA || error > 0); + DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0); if (mysql_bin_log.write(&qinfo) && transactional_table) error=1; } From 814e4dd238b7a12764fc307dfa5945eb3ea670f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 16:36:05 +0300 Subject: [PATCH 44/74] Bug#27044 replicated with unique field ndb table allows duplkey inserts The bug in that slave version of a table with unique field still was able to execute INSERT query as replace whereas it's impossible on master. The reason of this artifact is wrong usage of ndb->extra:s. Fixed with resetting flags at do_after. There is open issue with symmetrical resetting table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY) which i had to hand to bug#27077. The test for the current bug was committed in a cset for bug#27320. sql/log_event.cc: fixing do_after_row_operation to reset the effect of the extra engine's flags set at do_before; comments on meaning of extra flags added; execution of table->file->ha_end_bulk_insert() in do_after is not dependant on error; --- sql/log_event.cc | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 9289cf9b12c..edf6851e424 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -6601,10 +6601,23 @@ int Write_rows_log_event::do_before_row_operations(TABLE *table) lex->duplicates flag. */ thd->lex->sql_command= SQLCOM_REPLACE; - - table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); // Needed for ndbcluster - table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); // Needed for ndbcluster - table->file->extra(HA_EXTRA_IGNORE_NO_KEY); // Needed for ndbcluster + /* + Do not raise the error flag in case of hitting to an unique attribute + */ + table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); + /* + NDB specific: update from ndb master wrapped as Write_rows + */ + /* + so that the event should be applied to replace slave's row + */ + table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); + /* + NDB specific: if update from ndb master wrapped as Write_rows + does not find the row it's assumed idempotent binlog applying + is taking place; don't raise the error. + */ + table->file->extra(HA_EXTRA_IGNORE_NO_KEY); /* TODO: the cluster team (Tomas?) says that it's better if the engine knows how many rows are going to be inserted, then it can allocate needed memory @@ -6632,9 +6645,20 @@ int Write_rows_log_event::do_before_row_operations(TABLE *table) int Write_rows_log_event::do_after_row_operations(TABLE *table, int error) { - if (error == 0) - error= table->file->ha_end_bulk_insert(); - return error; + int local_error= 0; + table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); + table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); + /* + reseting the extra with + table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY); + fires bug#27077 + todo: explain or fix + */ + if (local_error= table->file->ha_end_bulk_insert()) + { + table->file->print_error(local_error, MYF(0)); + } + return error? error : local_error; } int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, From daa7b8a5b2dab1fc11b5546b9fd62aebd424a27a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 18:38:47 +0300 Subject: [PATCH 45/74] bug#22725 result file updated mysql-test/r/binlog_killed.result: results updated --- mysql-test/r/binlog_killed.result | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/binlog_killed.result b/mysql-test/r/binlog_killed.result index cb5683a4792..38184463cc1 100644 --- a/mysql-test/r/binlog_killed.result +++ b/mysql-test/r/binlog_killed.result @@ -16,7 +16,10 @@ is not null; (@a:=load_file("MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) is not null 1 -select @a like "%#%error_code=1317%" /* must return 0 */; -@a like "%#%error_code=1317%" -0 +select @a like "%#%error_code=0%" /* must return 1 */; +@a like "%#%error_code=0%" +1 +select @a like "%insert%" /* must return 1 */; +@a like "%insert%" +1 drop table t1,t2,t3; From 0e9f4eaaf3498fb3247defd032d4711746e4ec4b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 21:22:33 +0400 Subject: [PATCH 46/74] Refactoring patch: 1. Refactor sp_show_create_function() and sp_show_create_procedure() into show_create_routine(). 2. Code cleanup: eliminate proxy functions. sql/sp.cc: Code cleanup: eliminate proxy functions. sql/sp.h: Code cleanup: eliminate proxy functions. sql/sp_head.cc: 1. Refactor sp_show_create_function() and sp_show_create_procedure() into show_create_routine(). 2. Code cleanup: eliminate proxy functions. sql/sp_head.h: 1. Refactor sp_show_create_function() and sp_show_create_procedure() into show_create_routine(). 2. Code cleanup: eliminate proxy functions. sql/sql_parse.cc: Code cleanup: use new functions. --- sql/sp.cc | 326 +++++++++++++++++++++++------------------------ sql/sp.h | 29 +---- sql/sp_head.cc | 151 +++++++++++----------- sql/sp_head.h | 7 +- sql/sql_parse.cc | 40 +++--- 5 files changed, 262 insertions(+), 291 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index f21186de021..79daed9a627 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -442,16 +442,36 @@ sp_returns_type(THD *thd, String &result, sp_head *sp) delete field; } -static int -db_create_routine(THD *thd, int type, sp_head *sp) + +/** + Write stored-routine object into mysql.proc. + + This operation stores attributes of the stored procedure/function into + the mysql.proc. + + @param thd Thread context. + @param type Stored routine type + (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION). + @param sp Stored routine object to store. + + @return Error code. SP_OK is returned on success. Other SP_ constants are + used to indicate about errors. +*/ + +int +sp_create_routine(THD *thd, int type, sp_head *sp) { int ret; TABLE *table; char definer[USER_HOST_BUFF_SIZE]; - DBUG_ENTER("db_create_routine"); + + DBUG_ENTER("sp_create_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s",type,sp->m_name.length, sp->m_name.str)); + DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || + type == TYPE_ENUM_FUNCTION); + /* This statement will be replicated as a statement, even when using row-based replication. The flag will be reset at the end of the @@ -586,15 +606,33 @@ done: } -static int -db_drop_routine(THD *thd, int type, sp_name *name) +/** + Delete the record for the stored routine object from mysql.proc. + + The operation deletes the record for the stored routine specified by name + from the mysql.proc table and invalidates the stored-routine cache. + + @param thd Thread context. + @param type Stored routine type + (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION) + @param name Stored routine name. + + @return Error code. SP_OK is returned on success. Other SP_ constants are + used to indicate about errors. +*/ + +int +sp_drop_routine(THD *thd, int type, sp_name *name) { TABLE *table; int ret; - DBUG_ENTER("db_drop_routine"); + DBUG_ENTER("sp_drop_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s", type, name->m_name.length, name->m_name.str)); + DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || + type == TYPE_ENUM_FUNCTION); + /* This statement will be replicated as a statement, even when using row-based replication. The flag will be reset at the end of the @@ -618,6 +656,8 @@ db_drop_routine(THD *thd, int type, sp_name *name) thd->binlog_query(THD::MYSQL_QUERY_TYPE, thd->query, thd->query_length, FALSE, FALSE); } + + sp_cache_invalidate(); } close_thread_tables(thd); @@ -625,15 +665,35 @@ db_drop_routine(THD *thd, int type, sp_name *name) } -static int -db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) +/** + Find and updated the record for the stored routine object in mysql.proc. + + The operation finds the record for the stored routine specified by name + in the mysql.proc table and updates it with new attributes. After + successful update, the cache is invalidated. + + @param thd Thread context. + @param type Stored routine type + (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION) + @param name Stored routine name. + @param chistics New values of stored routine attributes to write. + + @return Error code. SP_OK is returned on success. Other SP_ constants are + used to indicate about errors. +*/ + +int +sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) { TABLE *table; int ret; - DBUG_ENTER("db_update_routine"); + DBUG_ENTER("sp_update_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s", type, name->m_name.length, name->m_name.str)); + + DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || + type == TYPE_ENUM_FUNCTION); /* This statement will be replicated as a statement, even when using row-based replication. The flag will be reset at the end of the @@ -670,6 +730,8 @@ db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) thd->binlog_query(THD::MYSQL_QUERY_TYPE, thd->query, thd->query_length, FALSE, FALSE); } + + sp_cache_invalidate(); } close_thread_tables(thd); @@ -755,13 +817,28 @@ print_field_values(THD *thd, TABLE *table, } -static int -db_show_routine_status(THD *thd, int type, const char *wild) +/** + Implement SHOW STATUS statement for stored routines. + + @param thd Thread context. + @param type Stored routine type + (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION) + @param name_pattern Stored routine name pattern. + + @return Error code. SP_OK is returned on success. Other SP_ constants are + used to indicate about errors. +*/ + +int +sp_show_status_routine(THD *thd, int type, const char *name_pattern) { TABLE *table; TABLE_LIST tables; int res; - DBUG_ENTER("db_show_routine_status"); + DBUG_ENTER("sp_show_status_routine"); + + DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || + type == TYPE_ENUM_FUNCTION); memset(&tables, 0, sizeof(tables)); tables.db= (char*)"mysql"; @@ -789,14 +866,14 @@ db_show_routine_status(THD *thd, int type, const char *wild) { switch (used_field->field_type) { case MYSQL_TYPE_TIMESTAMP: - field_list.push_back(item= - new Item_return_date_time(used_field->field_name, - MYSQL_TYPE_DATETIME)); + item= new Item_return_date_time(used_field->field_name, + MYSQL_TYPE_DATETIME); + field_list.push_back(item); break; default: - field_list.push_back(item=new Item_empty_string(used_field->field_name, - used_field-> - field_length)); + item= new Item_empty_string(used_field->field_name, + used_field->field_length); + field_list.push_back(item); break; } } @@ -840,13 +917,16 @@ db_show_routine_status(THD *thd, int type, const char *wild) res= (res == HA_ERR_END_OF_FILE) ? 0 : SP_INTERNAL_ERROR; goto err_case1; } - if ((res= print_field_values(thd, table, used_fields, type, wild))) - goto err_case1; - while (!table->file->index_next(table->record[0])) + + do { - if ((res= print_field_values(thd, table, used_fields, type, wild))) + res= print_field_values(thd, table, used_fields, type, name_pattern); + + if (res) goto err_case1; } + while (!table->file->index_next(table->record[0])); + res= SP_OK; } @@ -913,9 +993,60 @@ err: } -/***************************************************************************** - PROCEDURE -******************************************************************************/ +/** + Implement SHOW CREATE statement for stored routines. + + The operation finds the stored routine object specified by name and then + calls sp_head::show_create_routine() for the object. + + @param thd Thread context. + @param type Stored routine type + (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION) + @param name Stored routine name. + + @return Error status. + @retval FALSE on success + @retval TRUE on error +*/ + +bool +sp_show_create_routine(THD *thd, int type, sp_name *name) +{ + bool err_status= TRUE; + sp_head *sp; + sp_cache *cache = type == TYPE_ENUM_PROCEDURE ? + thd->sp_proc_cache : thd->sp_func_cache; + + DBUG_ENTER("sp_show_create_routine"); + DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); + + DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || + type == TYPE_ENUM_FUNCTION); + + if (type == TYPE_ENUM_PROCEDURE) + { + /* + SHOW CREATE PROCEDURE may require two instances of one sp_head + object when SHOW CREATE PROCEDURE is called for the procedure that + is being executed. Basically, there is no actual recursion, so we + increase the recursion limit for this statement (kind of hack). + + SHOW CREATE FUNCTION does not require this because SHOW CREATE + statements are prohibitted within stored functions. + */ + + thd->variables.max_sp_recursion_depth++; + } + + if ((sp= sp_find_routine(thd, type, name, &cache, FALSE))) + err_status= sp->show_create_routine(thd, type); + + if (type == TYPE_ENUM_PROCEDURE) + thd->variables.max_sp_recursion_depth--; + + DBUG_RETURN(err_status); +} + /* Obtain object representing stored procedure/function by its name from @@ -1109,151 +1240,6 @@ sp_routine_exists_in_table(THD *thd, int type, sp_name *name) } -int -sp_create_procedure(THD *thd, sp_head *sp) -{ - int ret; - DBUG_ENTER("sp_create_procedure"); - DBUG_PRINT("enter", ("name: %.*s", sp->m_name.length, sp->m_name.str)); - - ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, sp); - DBUG_RETURN(ret); -} - - -int -sp_drop_procedure(THD *thd, sp_name *name) -{ - int ret; - DBUG_ENTER("sp_drop_procedure"); - DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); - - ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name); - if (!ret) - sp_cache_invalidate(); - DBUG_RETURN(ret); -} - - -int -sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics) -{ - int ret; - DBUG_ENTER("sp_update_procedure"); - DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); - - ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, chistics); - if (!ret) - sp_cache_invalidate(); - DBUG_RETURN(ret); -} - - -int -sp_show_create_procedure(THD *thd, sp_name *name) -{ - int ret= SP_KEY_NOT_FOUND; - sp_head *sp; - DBUG_ENTER("sp_show_create_procedure"); - DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); - - /* - Increase the recursion limit for this statement. SHOW CREATE PROCEDURE - does not do actual recursion. - */ - thd->variables.max_sp_recursion_depth++; - if ((sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name, - &thd->sp_proc_cache, FALSE))) - ret= sp->show_create_procedure(thd); - - thd->variables.max_sp_recursion_depth--; - DBUG_RETURN(ret); -} - - -int -sp_show_status_procedure(THD *thd, const char *wild) -{ - int ret; - DBUG_ENTER("sp_show_status_procedure"); - - ret= db_show_routine_status(thd, TYPE_ENUM_PROCEDURE, wild); - DBUG_RETURN(ret); -} - - -/***************************************************************************** - FUNCTION -******************************************************************************/ - -int -sp_create_function(THD *thd, sp_head *sp) -{ - int ret; - DBUG_ENTER("sp_create_function"); - DBUG_PRINT("enter", ("name: %.*s", sp->m_name.length, sp->m_name.str)); - - ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, sp); - DBUG_RETURN(ret); -} - - -int -sp_drop_function(THD *thd, sp_name *name) -{ - int ret; - DBUG_ENTER("sp_drop_function"); - DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); - - ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name); - if (!ret) - sp_cache_invalidate(); - DBUG_RETURN(ret); -} - - -int -sp_update_function(THD *thd, sp_name *name, st_sp_chistics *chistics) -{ - int ret; - DBUG_ENTER("sp_update_procedure"); - DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); - - ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, chistics); - if (!ret) - sp_cache_invalidate(); - DBUG_RETURN(ret); -} - - -int -sp_show_create_function(THD *thd, sp_name *name) -{ - sp_head *sp; - DBUG_ENTER("sp_show_create_function"); - DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); - - if ((sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, name, - &thd->sp_func_cache, FALSE))) - { - int ret= sp->show_create_function(thd); - - DBUG_RETURN(ret); - } - DBUG_RETURN(SP_KEY_NOT_FOUND); -} - - -int -sp_show_status_function(THD *thd, const char *wild) -{ - int ret; - DBUG_ENTER("sp_show_status_function"); - ret= db_show_routine_status(thd, TYPE_ENUM_FUNCTION, wild); - DBUG_RETURN(ret); -} - - /* Structure that represents element in the set of stored routines used by statement or routine. diff --git a/sql/sp.h b/sql/sp.h index 24c0756c426..b134adbb9a0 100644 --- a/sql/sp.h +++ b/sql/sp.h @@ -44,37 +44,20 @@ sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any, bool no_error); int sp_routine_exists_in_table(THD *thd, int type, sp_name *name); -int -sp_create_procedure(THD *thd, sp_head *sp); +bool +sp_show_create_routine(THD *thd, int type, sp_name *name); int -sp_drop_procedure(THD *thd, sp_name *name); - +sp_show_status_routine(THD *thd, int type, const char *wild); int -sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics); +sp_create_routine(THD *thd, int type, sp_head *sp); int -sp_show_create_procedure(THD *thd, sp_name *name); +sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics); int -sp_show_status_procedure(THD *thd, const char *wild); - -int -sp_create_function(THD *thd, sp_head *sp); - -int -sp_drop_function(THD *thd, sp_name *name); - -int -sp_update_function(THD *thd, sp_name *name, st_sp_chistics *chistics); - -int -sp_show_create_function(THD *thd, sp_name *name); - -int -sp_show_status_function(THD *thd, const char *wild); - +sp_drop_routine(THD *thd, int type, sp_name *name); /* Procedures for pre-caching of stored routines and building table list diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 2f78f0b24dd..5aa0409e001 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -637,17 +637,10 @@ int sp_head::create(THD *thd) { DBUG_ENTER("sp_head::create"); - int ret; - DBUG_PRINT("info", ("type: %d name: %s params: %s body: %s", m_type, m_name.str, m_params.str, m_body.str)); - if (m_type == TYPE_ENUM_FUNCTION) - ret= sp_create_function(thd, this); - else - ret= sp_create_procedure(thd, this); - - DBUG_RETURN(ret); + DBUG_RETURN(sp_create_routine(thd, m_type, this)); } sp_head::~sp_head() @@ -2104,49 +2097,97 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access) } -int -sp_head::show_create_procedure(THD *thd) +/** + Implement SHOW CREATE statement for stored routines. + + @param thd Thread context. + @param type Stored routine type + (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION) + + @return Error status. + @retval FALSE on success + @retval TRUE on error +*/ + +bool +sp_head::show_create_routine(THD *thd, int type) { + const char *col1_caption= type == TYPE_ENUM_PROCEDURE ? + "Procedure" : "Function"; + + const char *col3_caption= type == TYPE_ENUM_PROCEDURE ? + "Create Procedure" : "Create Function"; + + bool err_status; + Protocol *protocol= thd->protocol; - char buff[2048]; - String buffer(buff, sizeof(buff), system_charset_info); - int res; - List field_list; + List fields; + LEX_STRING sql_mode; + bool full_access; - DBUG_ENTER("sp_head::show_create_procedure"); - DBUG_PRINT("info", ("procedure %s", m_name.str)); + + DBUG_ENTER("sp_head::show_create_routine"); + DBUG_PRINT("info", ("routine %s", m_name.str)); + + DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || + type == TYPE_ENUM_FUNCTION); if (check_show_routine_access(thd, this, &full_access)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); - sys_var_thd_sql_mode::symbolic_mode_representation(thd, m_sql_mode, - &sql_mode); - field_list.push_back(new Item_empty_string("Procedure", NAME_CHAR_LEN)); - field_list.push_back(new Item_empty_string("sql_mode", sql_mode.length)); - // 1024 is for not to confuse old clients - Item_empty_string *definition= - new Item_empty_string("Create Procedure", max(buffer.length(),1024)); - definition->maybe_null= TRUE; - field_list.push_back(definition); + sys_var_thd_sql_mode::symbolic_mode_representation( + thd, m_sql_mode, &sql_mode); + + /* Send header. */ + + fields.push_back(new Item_empty_string(col1_caption, NAME_LEN)); + fields.push_back(new Item_empty_string("sql_mode", sql_mode.length)); + + { + /* + NOTE: SQL statement field must be not less than 1024 in order not to + confuse old clients. + */ + + Item_empty_string *stmt_fld= + new Item_empty_string(col3_caption, + max(m_defstr.length, 1024)); + + stmt_fld->maybe_null= TRUE; + + fields.push_back(stmt_fld); + } + + if (protocol->send_fields(&fields, + Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) + { + DBUG_RETURN(TRUE); + } + + /* Send data. */ - if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | - Protocol::SEND_EOF)) - DBUG_RETURN(1); protocol->prepare_for_resend(); + protocol->store(m_name.str, m_name.length, system_charset_info); - protocol->store((char*) sql_mode.str, sql_mode.length, system_charset_info); + protocol->store(sql_mode.str, sql_mode.length, system_charset_info); + if (full_access) - protocol->store(m_defstr.str, m_defstr.length, system_charset_info); + protocol->store(m_defstr.str, m_defstr.length, &my_charset_bin); else protocol->store_null(); - res= protocol->write(); - send_eof(thd); - DBUG_RETURN(res); + err_status= protocol->write(); + + if (!err_status) + send_eof(thd); + + DBUG_RETURN(err_status); } + + /* Add instruction to SP @@ -2170,48 +2211,6 @@ void sp_head::add_instr(sp_instr *instr) } -int -sp_head::show_create_function(THD *thd) -{ - Protocol *protocol= thd->protocol; - char buff[2048]; - String buffer(buff, sizeof(buff), system_charset_info); - int res; - List field_list; - LEX_STRING sql_mode; - bool full_access; - DBUG_ENTER("sp_head::show_create_function"); - DBUG_PRINT("info", ("procedure %s", m_name.str)); - - if (check_show_routine_access(thd, this, &full_access)) - DBUG_RETURN(1); - - sys_var_thd_sql_mode::symbolic_mode_representation(thd, m_sql_mode, - &sql_mode); - field_list.push_back(new Item_empty_string("Function",NAME_CHAR_LEN)); - field_list.push_back(new Item_empty_string("sql_mode", sql_mode.length)); - Item_empty_string *definition= - new Item_empty_string("Create Function", max(buffer.length(),1024)); - definition->maybe_null= TRUE; - field_list.push_back(definition); - - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - protocol->prepare_for_resend(); - protocol->store(m_name.str, m_name.length, system_charset_info); - protocol->store(sql_mode.str, sql_mode.length, system_charset_info); - if (full_access) - protocol->store(m_defstr.str, m_defstr.length, system_charset_info); - else - protocol->store_null(); - res= protocol->write(); - send_eof(thd); - - DBUG_RETURN(res); -} - - /* Do some minimal optimization of the code: 1) Mark used instructions diff --git a/sql/sp_head.h b/sql/sp_head.h index 8ebba314ec5..4e3e11e468d 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -225,11 +225,8 @@ public: bool execute_procedure(THD *thd, List *args); - int - show_create_procedure(THD *thd); - - int - show_create_function(THD *thd); + bool + show_create_routine(THD *thd, int type); void add_instr(sp_instr *instr); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6d6f159a299..b791491ab08 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3928,11 +3928,15 @@ create_sp_error: already puts on CREATE FUNCTION. */ /* Conditionally writes to binlog */ - if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) - sp_result= sp_update_procedure(thd, lex->spname, - &lex->sp_chistics); - else - sp_result= sp_update_function(thd, lex->spname, &lex->sp_chistics); + + int type= lex->sql_command == SQLCOM_ALTER_PROCEDURE ? + TYPE_ENUM_PROCEDURE : + TYPE_ENUM_FUNCTION; + + sp_result= sp_update_routine(thd, + type, + lex->spname, + &lex->sp_chistics); } } switch (sp_result) @@ -3982,10 +3986,12 @@ create_sp_error: } #endif /* Conditionally writes to binlog */ - if (lex->sql_command == SQLCOM_DROP_PROCEDURE) - sp_result= sp_drop_procedure(thd, lex->spname); - else - sp_result= sp_drop_function(thd, lex->spname); + + int type= lex->sql_command == SQLCOM_DROP_PROCEDURE ? + TYPE_ENUM_PROCEDURE : + TYPE_ENUM_FUNCTION; + + sp_result= sp_drop_routine(thd, type, lex->spname); } else { @@ -4042,8 +4048,8 @@ create_sp_error: } case SQLCOM_SHOW_CREATE_PROC: { - if (sp_show_create_procedure(thd, lex->spname) != SP_OK) - { /* We don't distinguish between errors for now */ + if (sp_show_create_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname)) + { my_error(ER_SP_DOES_NOT_EXIST, MYF(0), SP_COM_STRING(lex), lex->spname->m_name.str); goto error; @@ -4052,8 +4058,8 @@ create_sp_error: } case SQLCOM_SHOW_CREATE_FUNC: { - if (sp_show_create_function(thd, lex->spname) != SP_OK) - { /* We don't distinguish between errors for now */ + if (sp_show_create_routine(thd, TYPE_ENUM_FUNCTION, lex->spname)) + { my_error(ER_SP_DOES_NOT_EXIST, MYF(0), SP_COM_STRING(lex), lex->spname->m_name.str); goto error; @@ -4063,14 +4069,14 @@ create_sp_error: #ifdef NOT_USED case SQLCOM_SHOW_STATUS_PROC: { - res= sp_show_status_procedure(thd, (lex->wild ? - lex->wild->ptr() : NullS)); + res= sp_show_status_routine(thd, TYPE_ENUM_PROCEDURE, + (lex->wild ? lex->wild->ptr() : NullS)); break; } case SQLCOM_SHOW_STATUS_FUNC: { - res= sp_show_status_function(thd, (lex->wild ? - lex->wild->ptr() : NullS)); + res= sp_show_status_routine(thd, TYPE_ENUM_FUNCTION, + (lex->wild ? lex->wild->ptr() : NullS)); break; } #endif From 70a530e4014d386b41998c67ebb57be583e876f4 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 21:05:08 +0300 Subject: [PATCH 47/74] bug#22725 refining the test. mysql-test/t/binlog_killed.test: due to killing reap may catch an error though it's indeterministic. --- mysql-test/t/binlog_killed.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/binlog_killed.test b/mysql-test/t/binlog_killed.test index 0bba72df867..219065a3579 100644 --- a/mysql-test/t/binlog_killed.test +++ b/mysql-test/t/binlog_killed.test @@ -28,6 +28,7 @@ connection con1; eval kill query $ID; connection con2; +--error 0,ER_QUERY_INTERRUPTED reap; select count(*) from t2 /* must be 3 */; From 5aec3d0f8d68ef3932de43f16ced48b0b3950f7a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 22:17:09 +0300 Subject: [PATCH 48/74] bug#22725 merge with 5.0 sql/sql_class.cc: THD::binlog_query receives killed status arg with default the same for Query_log_event sql/sql_class.h: relocation public binlog_query down to the point where killed_state is declared --- sql/sql_class.cc | 9 ++++---- sql/sql_class.h | 53 ++++++++++++++++++++++++------------------------ 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 87cf9b16d24..2359c5c4ae0 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3048,9 +3048,9 @@ void THD::binlog_delete_pending_rows_event() RETURN VALUE Error code, or 0 if no error. */ -int THD::binlog_query(THD::enum_binlog_query_type qtype, - char const *query, ulong query_len, - bool is_trans, bool suppress_use) +int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query, + ulong query_len, bool is_trans, bool suppress_use, + THD::killed_state killed_status_arg) { DBUG_ENTER("THD::binlog_query"); DBUG_PRINT("enter", ("qtype=%d, query='%s'", qtype, query)); @@ -3089,7 +3089,8 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, flush the pending rows event if necessary. */ { - Query_log_event qinfo(this, query, query_len, is_trans, suppress_use); + Query_log_event qinfo(this, query, query_len, is_trans, suppress_use, + killed_status_arg); qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F; /* Binlog table maps will be irrelevant after a Query_log_event diff --git a/sql/sql_class.h b/sql/sql_class.h index a75b774b7a3..9a527323dfe 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1079,32 +1079,6 @@ public: } #endif /* MYSQL_CLIENT */ -#ifndef MYSQL_CLIENT -public: - enum enum_binlog_query_type { - /* - The query can be logged row-based or statement-based - */ - ROW_QUERY_TYPE, - - /* - The query has to be logged statement-based - */ - STMT_QUERY_TYPE, - - /* - The query represents a change to a table in the "mysql" - database and is currently mapped to ROW_QUERY_TYPE. - */ - MYSQL_QUERY_TYPE, - QUERY_TYPE_COUNT - }; - - int binlog_query(enum_binlog_query_type qtype, - char const *query, ulong query_len, - bool is_trans, bool suppress_use); -#endif - public: struct st_transactions { @@ -1491,6 +1465,33 @@ public: void close_active_vio(); #endif void awake(THD::killed_state state_to_set); + +#ifndef MYSQL_CLIENT + enum enum_binlog_query_type { + /* + The query can be logged row-based or statement-based + */ + ROW_QUERY_TYPE, + + /* + The query has to be logged statement-based + */ + STMT_QUERY_TYPE, + + /* + The query represents a change to a table in the "mysql" + database and is currently mapped to ROW_QUERY_TYPE. + */ + MYSQL_QUERY_TYPE, + QUERY_TYPE_COUNT + }; + + int binlog_query(enum_binlog_query_type qtype, + char const *query, ulong query_len, + bool is_trans, bool suppress_use, + THD::killed_state killed_err_arg= THD::KILLED_NO_VALUE); +#endif + /* For enter_cond() / exit_cond() to work the mutex must be got before enter_cond(); this mutex is then released by exit_cond(). From 54e1f2f0ced6a347e836778dcba3eb2f0d54b140 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 23:16:50 +0300 Subject: [PATCH 49/74] bug#22725 tests refining, see binlog_killed.test file for details mysql-test/r/binlog_killed.result: results changed mysql-test/t/binlog_killed.test: killer conn waits for the first row to appear; log-disabling kill query since prey's id is not deterministic; correcting pattern to search in binlog for insert query; --- mysql-test/r/binlog_killed.result | 5 ++--- mysql-test/t/binlog_killed.test | 22 ++++++++++++++++++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/binlog_killed.result b/mysql-test/r/binlog_killed.result index 38184463cc1..368df408cb8 100644 --- a/mysql-test/r/binlog_killed.result +++ b/mysql-test/r/binlog_killed.result @@ -6,7 +6,6 @@ get_lock("a", 20) 1 reset master; insert into t2 values (null, null), (null, get_lock("a", 10)),(null, get_lock("a", 10)); -kill query 3; select count(*) from t2 /* must be 3 */; count(*) 3 @@ -19,7 +18,7 @@ is not null select @a like "%#%error_code=0%" /* must return 1 */; @a like "%#%error_code=0%" 1 -select @a like "%insert%" /* must return 1 */; -@a like "%insert%" +select @a like "%insert into%" /* must return 1 */; +@a like "%insert into%" 1 drop table t1,t2,t3; diff --git a/mysql-test/t/binlog_killed.test b/mysql-test/t/binlog_killed.test index 219065a3579..a5c9dea81ec 100644 --- a/mysql-test/t/binlog_killed.test +++ b/mysql-test/t/binlog_killed.test @@ -15,6 +15,7 @@ create table t3 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; # effective test for bug#22725 # +let $counter=200; # max 20 seconds to wait for insert performed the 1st row connection con1; select get_lock("a", 20); @@ -25,7 +26,24 @@ send insert into t2 values (null, null), (null, get_lock("a", 10)),(null, get_lo connection con1; + +disable_abort_on_error; +disable_query_log; +disable_result_log; + +while (`select count(*) from t2`) +{ + sleep 0.1; + dec $counter; + if (!$counter) + { + die("Waited too long for query to suceed"); + } +} eval kill query $ID; +enable_abort_on_error; +enable_query_log; +enable_result_log; connection con2; --error 0,ER_QUERY_INTERRUPTED @@ -39,7 +57,7 @@ eval select is not null; --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR eval select @a like "%#%error_code=0%" /* must return 1 */; -eval select @a like "%insert%" /* must return 1 */; +eval select @a like "%insert into%" /* must return 1 */; # the functions are either *insensitive* to killing or killing can cause # strange problmes with the error propagation out of SF's stack # Bug#27563, Bug#27565, BUG#24971 @@ -227,7 +245,7 @@ drop function bug27563; drop function bug27565; } -system rm $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog ; +#system rm $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog ; drop table t1,t2,t3; From 5817bdffe73f70c46cc848c76a8721e16fdf31f7 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 May 2007 14:52:17 -0600 Subject: [PATCH 50/74] Manual merge sql/sp_head.cc: Manual merge, bug#27876 sql/sql_lex.cc: Manual merge, bug#27876 sql/sql_lex.h: Manual merge, bug#27876 sql/sql_view.cc: Manual merge, bug#27876 tests/mysql_client_test.c: Manual merge, bug#27876 --- sql/sp_head.cc | 2 +- sql/sql_lex.cc | 9 ++++-- sql/sql_lex.h | 3 +- sql/sql_view.cc | 2 +- tests/mysql_client_test.c | 65 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 6 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 2f78f0b24dd..5627d6139ac 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -571,7 +571,7 @@ sp_head::init_strings(THD *thd, LEX *lex) Trim "garbage" at the end. This is sometimes needed with the "/ * ! VERSION... * /" wrapper in dump files. */ - endp= skip_rear_comments(m_body_begin, endp); + endp= skip_rear_comments(thd->charset(), m_body_begin, endp); m_body.length= endp - m_body_begin; m_body.str= strmake_root(root, m_body_begin, m_body.length); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 535a2492159..c19c224f0a3 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1151,6 +1151,7 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) SYNOPSIS skip_rear_comments() + cs character set begin pointer to the beginning of statement end pointer to the end of statement @@ -1161,10 +1162,12 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) Pointer to the last non-comment symbol of the statement. */ -const char *skip_rear_comments(const char *begin, const char *end) +const char *skip_rear_comments(CHARSET_INFO *cs, const char *begin, + const char *end) { - while (begin < end && (end[-1] <= ' ' || end[-1] == '*' || - end[-1] == '/' || end[-1] == ';')) + while (begin < end && (end[-1] == '*' || + end[-1] == '/' || end[-1] == ';' || + my_isspace(cs, end[-1]))) end-= 1; return end; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 400535babf0..68a3092cd77 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1417,7 +1417,8 @@ extern void lex_free(void); extern void lex_start(THD *thd); extern void lex_end(LEX *lex); extern int MYSQLlex(void *arg, void *yythd); -extern const char *skip_rear_comments(const char *ubegin, const char *uend); +extern const char *skip_rear_comments(CHARSET_INFO *cs, const char *ubegin, + const char *uend); extern bool is_lex_native_function(const LEX_STRING *name); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index bf48cd0094a..bbdd347ae7b 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -775,7 +775,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, view->query.length= str.length()-1; // we do not need last \0 view->source.str= thd->query + thd->lex->create_view_select_start; endp= view->source.str; - endp= skip_rear_comments(endp, thd->query + thd->query_length); + endp= skip_rear_comments(thd->charset(), endp, thd->query + thd->query_length); view->source.length= endp - view->source.str; view->file_version= 1; view->calc_md5(md5); diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 66eff66398f..ceb7e59a97b 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16097,6 +16097,70 @@ static void test_bug28075() } #endif + +/* + Bug#27876 (SF with cyrillic variable name fails during execution (regression)) +*/ +static void test_bug27876() +{ + int rc; + MYSQL_RES *result; + + char utf8_func[] = + { + 0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba, + 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba, + 0xd0, 0xb0, + 0x00 + }; + + char utf8_param[] = + { + 0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0, + 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a, + 0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, + 0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f, + 0x00 + }; + + char query[500]; + + DBUG_ENTER("test_bug27876"); + myheader("test_bug27876"); + + rc= mysql_query(mysql, "set names utf8"); + myquery(rc); + + rc= mysql_query(mysql, "select version()"); + myquery(rc); + result= mysql_store_result(mysql); + mytest(result); + + sprintf(query, "DROP FUNCTION IF EXISTS %s", utf8_func); + rc= mysql_query(mysql, query); + myquery(rc); + + sprintf(query, + "CREATE FUNCTION %s( %s VARCHAR(25))" + " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s", + utf8_func, utf8_param, utf8_param); + rc= mysql_query(mysql, query); + myquery(rc); + sprintf(query, "SELECT %s(VERSION())", utf8_func); + rc= mysql_query(mysql, query); + myquery(rc); + result= mysql_store_result(mysql); + mytest(result); + + sprintf(query, "DROP FUNCTION %s", utf8_func); + rc= mysql_query(mysql, query); + myquery(rc); + + rc= mysql_query(mysql, "set names default"); + myquery(rc); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -16384,6 +16448,7 @@ static struct my_tests_st my_tests[]= { #ifdef fix_bug_in_pb_first { "test_bug28075", test_bug28075 }, #endif + { "test_bug27876", test_bug27876 }, { 0, 0 } }; From 9a1e9de91f87e565224398ea020203e552d157a8 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 00:22:24 +0300 Subject: [PATCH 51/74] bug#22725 combining the final result variable in such way that either option of the test execution will yield zero. mysql-test/r/binlog_killed.result: results changed mysql-test/t/binlog_killed.test: there are two options for the test passing: 1. no rows inserted and the INSERT gets killed, then there is no INSERT query in binlog 2. all rows inserted, then INSERT gets to binlog and error_code is zero --- mysql-test/r/binlog_killed.result | 18 +++--------------- mysql-test/t/binlog_killed.test | 28 ++++++++++++---------------- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/mysql-test/r/binlog_killed.result b/mysql-test/r/binlog_killed.result index 368df408cb8..60fc403aeb3 100644 --- a/mysql-test/r/binlog_killed.result +++ b/mysql-test/r/binlog_killed.result @@ -6,19 +6,7 @@ get_lock("a", 20) 1 reset master; insert into t2 values (null, null), (null, get_lock("a", 10)),(null, get_lock("a", 10)); -select count(*) from t2 /* must be 3 */; -count(*) -3 -select -(@a:=load_file("MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) -is not null; -(@a:=load_file("MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) -is not null -1 -select @a like "%#%error_code=0%" /* must return 1 */; -@a like "%#%error_code=0%" -1 -select @a like "%insert into%" /* must return 1 */; -@a like "%insert into%" -1 +select @result /* must be zero either way */; +@result +0 drop table t1,t2,t3; diff --git a/mysql-test/t/binlog_killed.test b/mysql-test/t/binlog_killed.test index a5c9dea81ec..269362b5584 100644 --- a/mysql-test/t/binlog_killed.test +++ b/mysql-test/t/binlog_killed.test @@ -31,24 +31,12 @@ disable_abort_on_error; disable_query_log; disable_result_log; -while (`select count(*) from t2`) -{ - sleep 0.1; - dec $counter; - if (!$counter) - { - die("Waited too long for query to suceed"); - } -} eval kill query $ID; -enable_abort_on_error; -enable_query_log; -enable_result_log; connection con2; --error 0,ER_QUERY_INTERRUPTED reap; -select count(*) from t2 /* must be 3 */; +let $rows= `select count(*) from t2 /* must be 1 or 0 */`; --exec $MYSQL_BINLOG --start-position=126 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR @@ -56,8 +44,16 @@ eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) is not null; --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR -eval select @a like "%#%error_code=0%" /* must return 1 */; -eval select @a like "%insert into%" /* must return 1 */; +let $error_code= `select @a like "%#%error_code=0%" /* must return 1 or 0*/`; +let $insert_binlogged= `select @a like "%insert into%" /* must return 1 or 0 */`; +eval set @result= $rows-2*$error_code - $insert_binlogged; + +enable_abort_on_error; +enable_query_log; +enable_result_log; + +select @result /* must be zero either way */; + # the functions are either *insensitive* to killing or killing can cause # strange problmes with the error propagation out of SF's stack # Bug#27563, Bug#27565, BUG#24971 @@ -245,7 +241,7 @@ drop function bug27563; drop function bug27565; } -#system rm $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog ; +system rm $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog ; drop table t1,t2,t3; From 9f15fe64bd966fe7dd4e3d412934ebd94659dc09 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 11:53:50 +0400 Subject: [PATCH 52/74] Disable IM-tests. --- mysql-test/t/disabled.def | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 85685234de9..a0d05e4be2a 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -14,3 +14,6 @@ ndb_load : Bug#17233 user_limits : Bug#23921 random failure of user_limits.test im_life_cycle : Bug#27851: Instance manager test im_life_cycle fails randomly im_daemon_life_cycle : Bug#20294: Instance manager tests fail randomly +im_options_set : Bug#20294: Instance manager tests fail randomly +im_options_unset : Bug#20294: Instance manager tests fail randomly +im_utils : Bug#20294: Instance manager tests fail randomly From e5c4d97c9ef653bdb906002b6e3849711053ab30 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 10:56:18 +0300 Subject: [PATCH 53/74] bug#22725 test comments correction mysql-test/r/binlog_killed.result: changed mysql-test/t/binlog_killed.test: wrong comments (but important ones) left; little refinement in result calc --- mysql-test/r/binlog_killed.result | 2 +- mysql-test/t/binlog_killed.test | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/binlog_killed.result b/mysql-test/r/binlog_killed.result index 60fc403aeb3..ba4f38fb4c1 100644 --- a/mysql-test/r/binlog_killed.result +++ b/mysql-test/r/binlog_killed.result @@ -5,7 +5,7 @@ select get_lock("a", 20); get_lock("a", 20) 1 reset master; -insert into t2 values (null, null), (null, get_lock("a", 10)),(null, get_lock("a", 10)); +insert into t2 values (null, null), (null, get_lock("a", 10)); select @result /* must be zero either way */; @result 0 diff --git a/mysql-test/t/binlog_killed.test b/mysql-test/t/binlog_killed.test index 269362b5584..6e221f2ee29 100644 --- a/mysql-test/t/binlog_killed.test +++ b/mysql-test/t/binlog_killed.test @@ -22,7 +22,7 @@ select get_lock("a", 20); connection con2; let $ID= `select connection_id()`; reset master; -send insert into t2 values (null, null), (null, get_lock("a", 10)),(null, get_lock("a", 10)); +send insert into t2 values (null, null), (null, get_lock("a", 10)); connection con1; @@ -36,7 +36,7 @@ eval kill query $ID; connection con2; --error 0,ER_QUERY_INTERRUPTED reap; -let $rows= `select count(*) from t2 /* must be 1 or 0 */`; +let $rows= `select count(*) from t2 /* must be 2 or 0 */`; --exec $MYSQL_BINLOG --start-position=126 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR @@ -46,7 +46,7 @@ is not null; --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR let $error_code= `select @a like "%#%error_code=0%" /* must return 1 or 0*/`; let $insert_binlogged= `select @a like "%insert into%" /* must return 1 or 0 */`; -eval set @result= $rows-2*$error_code - $insert_binlogged; +eval set @result= $rows- $error_code - $insert_binlogged; enable_abort_on_error; enable_query_log; From 9e600f43bcd497dddcd128bbd49905791e556c26 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 12:06:07 +0400 Subject: [PATCH 54/74] Disable IM tests. --- mysql-test/t/disabled.def | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 10cea507ffe..357e8009231 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -14,6 +14,8 @@ user_limits : Bug#23921 random failure of user_limits.test im_options : Bug#20294 2006-07-24 stewart Instance manager test im_options fails randomly im_daemon_life_cycle : Bug#20294 2007-05-14 alik Instance manager tests fail randomly im_cmd_line : Bug#20294 2007-05-14 alik Instance manager tests fail randomly +im_utils : Bug#20294 2007-05-30 alik Instance manager tests fail randomly +im_instance_conf : Bug#20294 2007-05-30 alik Instance manager tests fail randomly im_life_cycle : BUG#27851 Instance manager dies on ASSERT in ~Thread_registry() or from not being able to close a mysqld instance. concurrent_innodb : BUG#21579 2006-08-11 mleich innodb_concurrent random failures with varying differences ndb_autodiscover : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog From 73acdb3569d959f390ed70ebb82e1e4959372e48 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 11:18:55 +0300 Subject: [PATCH 55/74] bug#22725 merge 5.0 with 5.1 mysql-test/t/binlog_killed.test: offset change in 5.1 --- mysql-test/t/binlog_killed.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/binlog_killed.test b/mysql-test/t/binlog_killed.test index 6e221f2ee29..06dda79b7ff 100644 --- a/mysql-test/t/binlog_killed.test +++ b/mysql-test/t/binlog_killed.test @@ -38,7 +38,7 @@ connection con2; reap; let $rows= `select count(*) from t2 /* must be 2 or 0 */`; ---exec $MYSQL_BINLOG --start-position=126 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog +--exec $MYSQL_BINLOG --start-position=134 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval select (@a:=load_file("$MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog")) From 42eab5a2b1824ad0896100259441a881deff4378 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 14:03:35 +0500 Subject: [PATCH 56/74] Fixing wrong memory read problem detected by Valgrind in "xml" test. The source of the problem was in my_vsnprintf() implementation. strings/my_vsnprintf.c: Fixing a problem in vsnprintf('%.*s', len, ptr) When processing the above format, it's incorrect to use strlen() because the string is not necessarily a null terminated string. Changing strlen() followed by set_if_smaller() to strnlen() - which covers both cases - limiting by '\0' and by "len". --- strings/my_vsnprintf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 93d228a1954..befdb1a81c2 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -95,8 +95,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) reg2 char *par = va_arg(ap, char *); uint plen,left_len = (uint)(end-to)+1; if (!par) par = (char*)"(null)"; - plen = (uint) strlen(par); - set_if_smaller(plen,width); + plen= (uint) strnlen(par, width); if (left_len <= plen) plen = left_len - 1; to=strnmov(to,par,plen); From d57f3bbbe1073cb0f3c72a00539bc60c96739b17 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 11:55:56 +0200 Subject: [PATCH 57/74] Added extra parenthesis to remove compiler warning Fixed test case rpl_incident.test (synchronize drop table, masked IO thread behaviour) mysql-test/r/rpl_incident.result: Masking master_log_file since IO thread is not synchronized in rpl_incident.test mysql-test/t/rpl_incident.test: Masking master_log_file since IO thread is not synchronized in rpl_incident.test Correcting drop of table so it is synchronized sql/log_event.cc: Added extra parenthesis to remove compiler warning --- mysql-test/r/rpl_incident.result | 5 ++--- mysql-test/t/rpl_incident.test | 7 +++---- sql/log_event.cc | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/rpl_incident.result b/mysql-test/r/rpl_incident.result index aea35c5f477..1a0da45f3e1 100644 --- a/mysql-test/r/rpl_incident.result +++ b/mysql-test/r/rpl_incident.result @@ -31,7 +31,7 @@ Master_Host 127.0.0.1 Master_User root Master_Port MASTER_PORT Connect_Retry 1 -Master_Log_File master-bin.000002 +Master_Log_File # Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # @@ -74,7 +74,7 @@ Master_Host 127.0.0.1 Master_User root Master_Port MASTER_PORT Connect_Retry 1 -Master_Log_File master-bin.000002 +Master_Log_File # Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # @@ -104,4 +104,3 @@ Master_SSL_Key Seconds_Behind_Master # Master_SSL_Verify_Server_Cert No DROP TABLE t1; -DROP TABLE t1; diff --git a/mysql-test/t/rpl_incident.test b/mysql-test/t/rpl_incident.test index c52f26317ad..507cd0e0798 100644 --- a/mysql-test/t/rpl_incident.test +++ b/mysql-test/t/rpl_incident.test @@ -22,7 +22,7 @@ connection slave; SELECT * FROM t1; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 6 # 7 # 8 # 9 # 22 # 23 # 33 # --query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; @@ -34,10 +34,9 @@ START SLAVE; SELECT * FROM t1; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 6 # 7 # 8 # 9 # 22 # 23 # 33 # --query_vertical SHOW SLAVE STATUS -DROP TABLE t1; connection master; DROP TABLE t1; - +--sync_slave_with_master diff --git a/sql/log_event.cc b/sql/log_event.cc index 906e55704d7..3cca8d53f07 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -6809,7 +6809,7 @@ int Write_rows_log_event::do_after_row_operations(TABLE *table, int error) fires bug#27077 todo: explain or fix */ - if (local_error= table->file->ha_end_bulk_insert()) + if ((local_error= table->file->ha_end_bulk_insert())) { table->file->print_error(local_error, MYF(0)); } From 2eba9378353c0a7e93a4ec807803c7224253aaab Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 16:02:54 +0500 Subject: [PATCH 58/74] Define HAVE_STRNLEN correctly. include/config-win.h: strnlen() presents in the build in library only starting from Visual Studio 2005, identified by _MSC_VER 1400. Previous versions of Visual Studio didn't have this function, so they need the MySQL replacement function to be compiled. --- include/config-win.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/config-win.h b/include/config-win.h index 8d6f8885626..6622be81038 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -350,7 +350,10 @@ inline double ulonglong2double(ulonglong value) #define SPRINTF_RETURNS_INT #define HAVE_SETFILEPOINTER #define HAVE_VIO_READ_BUFF +#if defined(_MSC_VER) && _MSC_VER >= 1400 +/* strnlen() appeared in Studio 2005 */ #define HAVE_STRNLEN +#endif #define HAVE_WINSOCK2 #define strcasecmp stricmp From db8df69cbce7cbaa59ce937231af0ba7fc4dc239 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 14:29:34 +0300 Subject: [PATCH 59/74] bug#17654 --read-from-remote-server causes core fixing FD event issue that showed up on pb. client/mysqlbinlog.cc: resetting temp_buf specially for FD event to avoid double-freeing --- client/mysqlbinlog.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index d2357aa10ec..179d0e9fd9e 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -635,6 +635,7 @@ Create_file event for file_id: %u\n",exv->file_id); print_event_info->common_header_len= glob_description_event->common_header_len; ev->print(result_file, print_event_info); + ev->temp_buf= 0; // as the event ref is zeroed /* We don't want this event to be deleted now, so let's hide it (I (Guilhem) should later see if this triggers a non-serious Valgrind From 9e25cfba001c12d1ff0608520efef8574983202c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 16:24:21 +0400 Subject: [PATCH 60/74] 1. Fix memory leak. 2. Use multibyte-safe constant. sql/sp.cc: Fix memory leak. sql/sp_head.cc: Use multibyte-safe constant. --- sql/sp.cc | 6 +++--- sql/sp_head.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index 79daed9a627..9ce245785d7 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1014,8 +1014,8 @@ sp_show_create_routine(THD *thd, int type, sp_name *name) { bool err_status= TRUE; sp_head *sp; - sp_cache *cache = type == TYPE_ENUM_PROCEDURE ? - thd->sp_proc_cache : thd->sp_func_cache; + sp_cache **cache = type == TYPE_ENUM_PROCEDURE ? + &thd->sp_proc_cache : &thd->sp_func_cache; DBUG_ENTER("sp_show_create_routine"); DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); @@ -1038,7 +1038,7 @@ sp_show_create_routine(THD *thd, int type, sp_name *name) thd->variables.max_sp_recursion_depth++; } - if ((sp= sp_find_routine(thd, type, name, &cache, FALSE))) + if ((sp= sp_find_routine(thd, type, name, cache, FALSE))) err_status= sp->show_create_routine(thd, type); if (type == TYPE_ENUM_PROCEDURE) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 746fc17ce4e..566aadcc864 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2141,7 +2141,7 @@ sp_head::show_create_routine(THD *thd, int type) /* Send header. */ - fields.push_back(new Item_empty_string(col1_caption, NAME_LEN)); + fields.push_back(new Item_empty_string(col1_caption, NAME_CHAR_LEN)); fields.push_back(new Item_empty_string("sql_mode", sql_mode.length)); { From 3c6a4bc5b29339dbf559c13910428689437f0f9e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 17:29:05 +0500 Subject: [PATCH 61/74] CMakeLists.txt: Adding strnlen.c into the list of source files. strings/CMakeLists.txt: Adding strnlen.c into the list of source files. --- strings/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt index dd9b500841f..ac7c75ec56c 100644 --- a/strings/CMakeLists.txt +++ b/strings/CMakeLists.txt @@ -24,4 +24,4 @@ ADD_LIBRARY(strings bchange.c bcmp.c bfill.c bmove512.c bmove_upp.c ctype-big5.c is_prefix.c llstr.c longlong2str.c my_strtoll10.c my_vsnprintf.c r_strinstr.c str2int.c str_alloc.c strcend.c strend.c strfill.c strmake.c strmov.c strnmov.c strtod.c strtol.c strtoll.c strtoul.c strtoull.c strxmov.c strxnmov.c xml.c - my_strchr.c strcont.c strinstr.c) + my_strchr.c strcont.c strinstr.c strnlen.c) From 45a6e67fd5b143e0ce30ff2e71b010d9b9eabe56 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 16:14:55 +0300 Subject: [PATCH 62/74] bug#22725 the test is not supposed for row format. the include-guard is set. mysql-test/t/binlog_killed.test: the test does not apply to rbr --- mysql-test/t/binlog_killed.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/binlog_killed.test b/mysql-test/t/binlog_killed.test index 06dda79b7ff..9b799e41598 100644 --- a/mysql-test/t/binlog_killed.test +++ b/mysql-test/t/binlog_killed.test @@ -1,4 +1,5 @@ -- source include/have_innodb.inc +-- source include/have_binlog_format_mixed_or_statement.inc ### ### bug#22725 : incorrect killed error in binlogged query From 647923f9e99248e87f1723304b5e6c986f6d4737 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 15:56:05 +0200 Subject: [PATCH 63/74] Masking out error that is not generated by the test (rpl_ndb_basic.test) itself mysql-test/r/rpl_ndb_basic.result: Masking out error that is not generated by the test itself mysql-test/t/rpl_ndb_basic.test: Masking out error that is not generated by the test itself --- mysql-test/r/rpl_ndb_basic.result | 4 ++-- mysql-test/t/rpl_ndb_basic.test | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/rpl_ndb_basic.result b/mysql-test/r/rpl_ndb_basic.result index 4dab05b31de..37217bf0ad1 100644 --- a/mysql-test/r/rpl_ndb_basic.result +++ b/mysql-test/r/rpl_ndb_basic.result @@ -159,8 +159,8 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1105 -Last_Error Unknown error +Last_Errno +Last_Error Skip_Counter 0 Exec_Master_Log_Pos Relay_Log_Space diff --git a/mysql-test/t/rpl_ndb_basic.test b/mysql-test/t/rpl_ndb_basic.test index 04c855f8730..e485b1d1bde 100644 --- a/mysql-test/t/rpl_ndb_basic.test +++ b/mysql-test/t/rpl_ndb_basic.test @@ -197,7 +197,7 @@ UPDATE t1 SET `nom`="DEAD" WHERE `nid`=1; --connection slave --echo **** On Slave **** --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 7 8 9 16 22 23 33 +--replace_column 1 7 8 9 16 19 20 22 23 33 --query_vertical SHOW SLAVE STATUS; # now set max retries high enough to succeed, and start slave again From a10cc7180107ce22a93ea1badd311bf6f8cc050d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 17:00:48 +0200 Subject: [PATCH 64/74] Changed to vertical output for rpl_row_until.test --- mysql-test/r/rpl_row_until.result | 152 +++++++++++++++++++++++++++--- mysql-test/t/rpl_row_until.test | 8 +- 2 files changed, 144 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/rpl_row_until.result b/mysql-test/r/rpl_row_until.result index c691185650a..d71cc479f7a 100644 --- a/mysql-test/r/rpl_row_until.result +++ b/mysql-test/r/rpl_row_until.result @@ -19,9 +19,41 @@ n 2 3 4 -show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 315 # Master master-bin.000001 311 No # No +SHOW SLAVE STATUS;; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 744 +Relay_Log_File slave-relay-bin.000004 +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running # +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 315 +Relay_Log_Space # +Until_Condition Master +Until_Log_File master-bin.000001 +Until_Log_Pos 311 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; select * from t1; n @@ -29,23 +61,119 @@ n 2 3 4 -show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 315 # Master master-no-such-bin.000001 291 No # No +SHOW SLAVE STATUS;; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 744 +Relay_Log_File slave-relay-bin.000004 +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running # +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 315 +Relay_Log_Space # +Until_Condition Master +Until_Log_File master-no-such-bin.000001 +Until_Log_Pos 291 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728; select * from t2; n 1 2 -show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 590 # Relay slave-relay-bin.000004 728 No # No +SHOW SLAVE STATUS;; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 744 +Relay_Log_File slave-relay-bin.000004 +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running # +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 590 +Relay_Log_Space # +Until_Condition Relay +Until_Log_File slave-relay-bin.000004 +Until_Log_Pos 728 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No start slave; stop slave; start slave until master_log_file='master-bin.000001', master_log_pos=740; -show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 744 # Master master-bin.000001 740 No # No +SHOW SLAVE STATUS;; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_MYPORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 744 +Relay_Log_File slave-relay-bin.000004 +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 744 +Relay_Log_Space # +Until_Condition Master +Until_Log_File master-bin.000001 +Until_Log_Pos 740 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No start slave until master_log_file='master-bin', master_log_pos=561; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12; diff --git a/mysql-test/t/rpl_row_until.test b/mysql-test/t/rpl_row_until.test index f2a4229cdc4..f1d21e65a4c 100644 --- a/mysql-test/t/rpl_row_until.test +++ b/mysql-test/t/rpl_row_until.test @@ -33,7 +33,7 @@ wait_for_slave_to_stop; select * from t1; --replace_result $MASTER_MYPORT MASTER_MYPORT --replace_column 1 # 9 # 11 # 23 # 33 # -show slave status; +--query_vertical SHOW SLAVE STATUS; # this should fail right after start start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; @@ -43,7 +43,7 @@ sleep 2; wait_for_slave_to_stop; --replace_result $MASTER_MYPORT MASTER_MYPORT --replace_column 1 # 9 # 11 # 23 # 33 # -show slave status; +--query_vertical SHOW SLAVE STATUS; # try replicate all up to and not including the second insert to t2; start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728; @@ -52,7 +52,7 @@ wait_for_slave_to_stop; select * from t2; --replace_result $MASTER_MYPORT MASTER_MYPORT --replace_column 1 # 9 # 11 # 23 # 33 # -show slave status; +--query_vertical SHOW SLAVE STATUS; # clean up start slave; @@ -69,7 +69,7 @@ wait_for_slave_to_stop; # here the sql slave thread should be stopped --replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004 --replace_column 1 # 9 # 23 # 33 # -show slave status; +--query_vertical SHOW SLAVE STATUS; #testing various error conditions --error 1277 From dd190b0e6b05d3cf7552a0999554a636e426471a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 22:29:15 +0300 Subject: [PATCH 65/74] bug#22725 refining the test because of Bug #28786 'reset master' does not reset binlogging on embeded server mysql-test/t/binlog_killed.test: the test can not pass on embedded server. Setting the include-guard. --- mysql-test/t/binlog_killed.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/binlog_killed.test b/mysql-test/t/binlog_killed.test index 6e221f2ee29..1c4f1272691 100644 --- a/mysql-test/t/binlog_killed.test +++ b/mysql-test/t/binlog_killed.test @@ -1,4 +1,5 @@ -- source include/have_innodb.inc +--source include/not_embedded.inc ### ### bug#22725 : incorrect killed error in binlogged query @@ -15,7 +16,6 @@ create table t3 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB; # effective test for bug#22725 # -let $counter=200; # max 20 seconds to wait for insert performed the 1st row connection con1; select get_lock("a", 20); From 0e78deec27a53c72e28f828ef42a5629e40d4d34 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 May 2007 17:46:28 -0600 Subject: [PATCH 66/74] Build warning cleanup --- sql/sql_acl.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 119b1a49828..02cd527c544 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -4025,7 +4025,6 @@ bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant, err: rw_unlock(&LOCK_grant); -err2: char command[128]; get_privilege_desc(command, sizeof(command), want_access); my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), From 80af30efe10621b7c2b64f98cf957e0c1b5b5f8d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 May 2007 10:34:22 +0200 Subject: [PATCH 67/74] Disabled due to valgrind failure (talked to Tomas) --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index ffa59ed10ed..1f96de1ea85 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -31,6 +31,7 @@ rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after C rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement #rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly +rpl_ndb_ddl : BUG#28798 2007-05-31 lars Valgrind failure in NDB # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open #ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events From 0519057a8724d532e009fae988cb23fc43fb4560 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Jun 2007 13:33:57 +0400 Subject: [PATCH 68/74] A post-merge fix. --- sql/sql_table.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index dbcd7cf07c6..bb0f7649272 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5315,7 +5315,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, if (!create_info->tablespace && create_info->storage_media != HA_SM_MEMORY) { - char *tablespace= thd->alloc(FN_LEN); + char *tablespace= static_cast(thd->alloc(FN_LEN)); /* Regular alter table of disk stored table (no tablespace/storage change) Copy tablespace name From 108429c99e840389f806a6af761cd5d630448d92 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Jun 2007 14:17:23 +0400 Subject: [PATCH 69/74] Fix a warning. sql/sp.cc: Fix a warning "field precision should have type "int", but argument 2 has type "size_t" --- sql/sp.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/sp.cc b/sql/sp.cc index a73569fdcd9..49e86f9d07e 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1017,7 +1017,9 @@ sp_show_create_routine(THD *thd, int type, sp_name *name) &thd->sp_proc_cache : &thd->sp_func_cache; DBUG_ENTER("sp_show_create_routine"); - DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); + DBUG_PRINT("enter", ("name: %.*s", + (int) name->m_name.length, + name->m_name.str)); DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || type == TYPE_ENUM_FUNCTION); From d8cd88cd2aa823131c5dafaa1bd65042a7c02f22 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Jun 2007 17:49:01 +0400 Subject: [PATCH 70/74] Fix some mysqltest warnings. mysql-test/r/sp.result: Update results. mysql-test/t/mysql.test: Fix a typo. mysql-test/t/mysqltest.test: Fix a typo. mysql-test/t/order_by.test: Fix a typo. mysql-test/t/row.test: Remove an unsupported command. mysql-test/t/sp.test: Fix a typo. mysql-test/t/subselect3.test: Fix mysqltest warnings - now it warns when sees some suspicious -- comment --- mysql-test/r/sp.result | 11 +++++++++++ mysql-test/t/mysql.test | 2 +- mysql-test/t/mysqltest.test | 2 +- mysql-test/t/order_by.test | 4 ++-- mysql-test/t/row.test | 2 -- mysql-test/t/sp.test | 2 +- mysql-test/t/subselect3.test | 4 ++-- 7 files changed, 18 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index b5b79af031e..a503106c81e 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6018,6 +6018,8 @@ select bug20777(9223372036854775810) as '9223372036854775810 2**63+2'; select bug20777(-9223372036854775808) as 'lower bounds signed bigint'; lower bounds signed bigint 0 +Warnings: +Warning 1264 Out of range value adjusted for column 'f1' at row 1 select bug20777(9223372036854775807) as 'upper bounds signed bigint'; upper bounds signed bigint 9223372036854775807 @@ -6030,9 +6032,13 @@ upper bounds unsigned bigint select bug20777(18446744073709551616) as 'upper bounds unsigned bigint + 1'; upper bounds unsigned bigint + 1 18446744073709551615 +Warnings: +Warning 1264 Out of range value adjusted for column 'f1' at row 1 select bug20777(-1) as 'lower bounds unsigned bigint - 1'; lower bounds unsigned bigint - 1 0 +Warnings: +Warning 1264 Out of range value adjusted for column 'f1' at row 1 create table examplebug20777 as select 0 as 'i', bug20777(9223372036854775806) as '2**63-2', @@ -6044,7 +6050,12 @@ bug20777(18446744073709551615) as '2**64-1', bug20777(18446744073709551616) as '2**64', bug20777(0) as '0', bug20777(-1) as '-1'; +Warnings: +Warning 1264 Out of range value adjusted for column 'f1' at row 1 +Warning 1264 Out of range value adjusted for column 'f1' at row 1 insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616, 0, -1); +Warnings: +Warning 1264 Out of range value adjusted for column '-1' at row 1 show create table examplebug20777; Table Create Table examplebug20777 CREATE TABLE `examplebug20777` ( diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 0732559e7e1..37bbca77d9f 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -262,7 +262,7 @@ EOF --exec $MYSQL test -e "show status" 2>&1 > /dev/null --exec $MYSQL --help 2>&1 > /dev/null --exec $MYSQL --version 2>&1 > /dev/null ---enable_quary_log +--enable_query_log # # bug #26851: Mysql Client --pager Buffer Overflow diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 057432d37fd..24e59eeb89b 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1871,7 +1871,7 @@ DROP TABLE t1; --disable_query_log --exec $MYSQL_TEST --help 2>&1 > /dev/null --exec $MYSQL_TEST --version 2>&1 > /dev/null ---enable_quary_log +--enable_query_log --disable_abort_on_error --error 1 --exec $MYSQL_TEST a b c 2>&1 > /dev/null diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 3e8fa07dfb7..29a290c7fbf 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -719,10 +719,10 @@ CREATE TABLE t1 (a INT UNSIGNED NOT NULL, b TIME); INSERT INTO t1 (a) VALUES (100000), (0), (100), (1000000),(10000), (1000), (10); UPDATE t1 SET b = SEC_TO_TIME(a); --- Correct ORDER +# Correct ORDER SELECT a, b FROM t1 ORDER BY b DESC; --- must be ordered as the above +# must be ordered as the above SELECT a, b FROM t1 ORDER BY SEC_TO_TIME(a) DESC; DROP TABLE t1; diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test index d2750fecbac..20d044306a6 100644 --- a/mysql-test/t/row.test +++ b/mysql-test/t/row.test @@ -7,10 +7,8 @@ select (1,2,3) IN ((3,2,3), (1,2,3), (1,3,3)); select row(10,2,3) IN (row(3,2,3), row(1,2,3), row(1,3,3)); select row(1,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3)); select row(10,2,3) IN (row(3,NULL,3), row(1,2,3), row(1,3,3)); ---disable_ps_warnings select row('a',1.5,3) IN (row(1,2,3), row('a',1.5,3), row('a','a','a')); select row('a',0,3) IN (row(3,2,3), row('a','a','3'), row(1,3,3)); ---enable_ps_warnings select row('a',0,3) IN (row(3,2,3), row('a','0','3'), row(1,3,3)); select row('a',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3)); select row('b',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3)); diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index ff203a85ef7..2dc2c09ab2d 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -6975,7 +6975,7 @@ use test| --disable_warnings drop function if exists bug20777| drop table if exists examplebug20777| ---enabled_warnings +--enable_warnings create function bug20777(f1 bigint unsigned) returns bigint unsigned begin set f1 = (f1 - 10); set f1 = (f1 + 10); diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test index 65556012588..14dbb72de7b 100644 --- a/mysql-test/t/subselect3.test +++ b/mysql-test/t/subselect3.test @@ -260,11 +260,11 @@ insert into t2 values ('dd', 1, NULL); alter table t1 add index idx(ie1,ie2); ---cc 3 NULL NULL +# cc 3 NULL NULL select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=3 and b is null ; insert into t2 values ('new1', 10,10); insert into t1 values ('new1', 1234, 10, NULL); --- new1, 10, 10, NULL, +# new1, 10, 10, NULL, select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=10 and b=10; explain extended select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=10 and b=10; From 82047fab57573e187892663adbf23d384b06bc25 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Jun 2007 17:53:38 +0400 Subject: [PATCH 71/74] A post-merge fix. --- mysql-test/r/sp.result | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index e6dea250355..34945f0cb60 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6127,6 +6127,8 @@ select bug20777(9223372036854775810) as '9223372036854775810 2**63+2'; select bug20777(-9223372036854775808) as 'lower bounds signed bigint'; lower bounds signed bigint 0 +Warnings: +Warning 1264 Out of range value for column 'f1' at row 1 select bug20777(9223372036854775807) as 'upper bounds signed bigint'; upper bounds signed bigint 9223372036854775807 @@ -6139,9 +6141,13 @@ upper bounds unsigned bigint select bug20777(18446744073709551616) as 'upper bounds unsigned bigint + 1'; upper bounds unsigned bigint + 1 18446744073709551615 +Warnings: +Warning 1264 Out of range value for column 'f1' at row 1 select bug20777(-1) as 'lower bounds unsigned bigint - 1'; lower bounds unsigned bigint - 1 0 +Warnings: +Warning 1264 Out of range value for column 'f1' at row 1 create table examplebug20777 as select 0 as 'i', bug20777(9223372036854775806) as '2**63-2', @@ -6153,7 +6159,12 @@ bug20777(18446744073709551615) as '2**64-1', bug20777(18446744073709551616) as '2**64', bug20777(0) as '0', bug20777(-1) as '-1'; +Warnings: +Warning 1264 Out of range value for column 'f1' at row 1 +Warning 1264 Out of range value for column 'f1' at row 1 insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616, 0, -1); +Warnings: +Warning 1264 Out of range value for column '-1' at row 1 show create table examplebug20777; Table Create Table examplebug20777 CREATE TABLE `examplebug20777` ( From 68cc0a34b7843a13004c5811f45576633190701c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Jun 2007 18:04:25 +0400 Subject: [PATCH 72/74] Fix a typo in the test case. mysql-test/r/rpl_loaddata.result: Update result. mysql-test/t/rpl_loaddata.test: Fix a typo in the test file. --- mysql-test/r/rpl_loaddata.result | 2 +- mysql-test/t/rpl_loaddata.test | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index b4b8d8b9a07..be137079c7a 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -83,4 +83,4 @@ drop table t1; CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB; LOAD DATA INFILE "../std_data_ln/words.dat" INTO TABLE t1; ERROR 23000: Duplicate entry 'Aarhus' for key 1 -DROP TABLE IF EXISTS t1; +DROP TABLE t1; diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test index 27fa7fb95a6..a4781ed4faa 100644 --- a/mysql-test/t/rpl_loaddata.test +++ b/mysql-test/t/rpl_loaddata.test @@ -158,9 +158,7 @@ CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB; --error 1062 LOAD DATA INFILE "../std_data_ln/words.dat" INTO TABLE t1; ---disable warnings -DROP TABLE IF EXISTS t1; ---enable warnings +DROP TABLE t1; sync_with_master; # End of 4.1 tests From a00e5c6896e4a2d128aa7da5fabcb508ebd67f0f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Jun 2007 18:06:40 +0400 Subject: [PATCH 73/74] Do not ignore mysqltest language interpreter warnings. --- .bzrignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.bzrignore b/.bzrignore index d1de21857db..8c632f8f890 100644 --- a/.bzrignore +++ b/.bzrignore @@ -708,7 +708,6 @@ mysql-test/r/*.err mysql-test/r/*.log mysql-test/r/*.out mysql-test/r/*.reject -mysql-test/r/*.warnings mysql-test/r/alter_table.err mysql-test/r/archive.err mysql-test/r/bdb-alter-table-1.err From e21076463c4c1721bfd7150ff2350d634009755a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 1 Jun 2007 20:05:34 +0400 Subject: [PATCH 74/74] Fix more mysqltest warnings. --- mysql-test/t/mysqltest.test | 11 +++-------- mysql-test/t/strict.test | 2 -- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 24e59eeb89b..54d17df1fd9 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -46,11 +46,6 @@ select otto from (select 1 as otto) as t1; --error 0 select otto from (select 1 as otto) as t1; -# expectation <> response --- // --error 1054 --- // select otto from (select 1 as otto) as t1; - - # ---------------------------------------------------------------------------- # Negative case(statement): # The derived table t1 does not contain a column named 'friedrich' . @@ -331,9 +326,9 @@ select 3 from t1 ; # This is a comment # This is a ; comment # This is a -- comment --- This is also a comment --- # This is also a comment --- This is also a ; comment +# -- This is also a comment +# -- # This is also a comment +# -- This is also a ; comment # ---------------------------------------------------------------------------- # Test comments with embedded command diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index fc663853174..a66ab464a11 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -975,9 +975,7 @@ select * from t1; # Check that select don't abort even in strict mode (for now) set sql_mode='traditional'; ---disable_ps_warnings select count(*) from t1 where STR_TO_DATE('2004.12.12 10:22:61','%Y.%m.%d %T') IS NULL; ---enable_ps_warnings drop table t1;