summaryrefslogtreecommitdiff
path: root/sql/sql_lex.h
diff options
context:
space:
mode:
authorunknown <kostja@bodhi.local>2006-12-08 02:20:09 +0300
committerunknown <kostja@bodhi.local>2006-12-08 02:20:09 +0300
commite47ded8114f0b692a2ecf010998edcad46e6c2b3 (patch)
tree2c202eec217475270d843b44b724293b2c2c43eb /sql/sql_lex.h
parent73079a24064db262e2e0f4000e321485530dce5f (diff)
downloadmariadb-git-e47ded8114f0b692a2ecf010998edcad46e6c2b3.tar.gz
A fix and test cases for
Bug#4968 "Stored procedure crash if cursor opened on altered table" Bug#19733 "Repeated alter, or repeated create/drop, fails" Bug#19182 "CREATE TABLE bar (m INT) SELECT n FROM foo; doesn't work from stored procedure." Bug#6895 "Prepared Statements: ALTER TABLE DROP COLUMN does nothing" Bug#22060 "ALTER TABLE x AUTO_INCREMENT=y in SP crashes server" Test cases for bugs 4968, 19733, 6895 will be added 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 were not re-execution friendly: during their operation they used to 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 (note that code in 5.1 already creates and uses a copy of this structure in mysql_create_table()/alter_table(), but this approach didn't work well for CREATE TABLE SELECT statement). mysql-test/r/ps.result: Update test results (Bug#19182, Bug#22060) mysql-test/t/ps.test: Add a test case for Bug#19182, Bug#22060 (4.1-only parts) 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. sql/sql_class.h: Replace pair<columns, keys> 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). 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. sql/sql_list.h: Implement a copy constructor of class List that makes 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 is a bug. Just like CREATE INDEX, DROP INDEX is currently done via complete table rebuild and is rightfully a slow administrative statement. sql/sql_show.cc: Adjust mysqld_show_create_db to a new signature. sql/sql_table.cc: Adjust mysql_alter_table, mysql_recreate_table, mysql_create_table, mysql_prepare_table to new signatures. sql/sql_yacc.yy: LEX::key_list and LEX::create_list moved to class Alter_info
Diffstat (limited to 'sql/sql_lex.h')
-rw-r--r--sql/sql_lex.h56
1 files changed, 48 insertions, 8 deletions
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 12f89202e2d..7faeb8046c7 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -571,19 +571,61 @@ typedef class st_select_lex SELECT_LEX;
#define ALTER_ORDER 64
#define ALTER_OPTIONS 128
-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<Alter_drop> drop_list;
List<Alter_column> alter_list;
+ List<Key> key_list;
+ List<create_field> create_list;
uint flags;
enum enum_enable_or_disable keys_onoff;
enum tablespace_op_type tablespace_op;
bool is_simple;
- st_alter_info(){clear();}
- void clear(){keys_onoff= LEAVE_AS_IS;tablespace_op= NO_TABLESPACE_OP;}
- void reset(){drop_list.empty();alter_list.empty();clear();}
-} ALTER_INFO;
+ Alter_info() :
+ flags(0),
+ keys_onoff(LEAVE_AS_IS),
+ tablespace_op(NO_TABLESPACE_OP),
+ is_simple(1)
+ {}
+ 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;
+ is_simple= 1;
+ }
+ /**
+ 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.
+ The constructed copy still shares key Key, Alter_drop, create_field
+ and Alter_column elements of the lists - these structures are not
+ modified and thus are not copied.
+
+ @note You need to use check thd->is_fatal_error 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
+};
+
/* The state of the lex parsing. This is saved in the THD struct */
@@ -620,8 +662,6 @@ typedef struct st_lex
List<String> interval_list;
List<LEX_USER> users_list;
List<LEX_COLUMN> columns;
- List<Key> key_list;
- List<create_field> create_list;
List<Item> *insert_list,field_list,value_list,update_list;
List<List_item> many_values;
List<set_var_base> var_list;
@@ -654,7 +694,7 @@ typedef struct st_lex
bool derived_tables;
bool safe_to_cache_query;
bool subqueries, ignore;
- ALTER_INFO alter_info;
+ Alter_info alter_info;
/* Prepared statements SQL syntax:*/
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
/*