Commit 3e399043 authored by unknown's avatar unknown

Merge bodhi.local:/opt/local/work/mysql-4.1-4968

into  bodhi.local:/opt/local/work/mysql-5.0-4968-pull-from-4.1


sql/sql_insert.cc:
  Auto merged
mysql-test/r/ps.result:
  Manual merge.
mysql-test/t/ps.test:
  Manual merge.
sql/mysql_priv.h:
  Manual merge.
sql/sql_class.h:
  Manual merge.
sql/sql_lex.cc:
  Manual merge.
sql/sql_lex.h:
  Manual merge.
sql/sql_list.h:
  Manual merge.
sql/sql_parse.cc:
  Manual merge.
sql/sql_show.cc:
  Manual merge.
sql/sql_table.cc:
  Manual merge.
sql/sql_yacc.yy:
  Manual merge.
parents fe84b016 e47ded81
...@@ -1055,6 +1055,297 @@ EXECUTE stmt USING @a; ...@@ -1055,6 +1055,297 @@ EXECUTE stmt USING @a;
0 0 0 0
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
DROP TABLE t1; DROP TABLE t1;
ERROR HY000: Unknown error
show status like 'prepared_stmt_count';
Variable_name Value
Prepared_stmt_count 0
set global max_prepared_stmt_count=1;
prepare stmt from "select 1";
show status like 'prepared_stmt_count';
Variable_name Value
Prepared_stmt_count 1
prepare stmt1 from "select 1";
ERROR HY000: Unknown error
show status like 'prepared_stmt_count';
Variable_name Value
Prepared_stmt_count 1
deallocate prepare stmt;
show status like 'prepared_stmt_count';
Variable_name Value
Prepared_stmt_count 0
prepare stmt from "select 1";
show status like 'prepared_stmt_count';
Variable_name Value
Prepared_stmt_count 1
prepare stmt from "select 2";
show status like 'prepared_stmt_count';
Variable_name Value
Prepared_stmt_count 1
show status like 'prepared_stmt_count';
Variable_name Value
Prepared_stmt_count 1
select @@max_prepared_stmt_count;
@@max_prepared_stmt_count
1
set global max_prepared_stmt_count=0;
prepare stmt from "select 1";
ERROR HY000: Unknown error
execute stmt;
ERROR HY000: Unknown prepared statement handler (stmt) given to EXECUTE
show status like 'prepared_stmt_count';
Variable_name Value
Prepared_stmt_count 0
prepare stmt from "select 1";
ERROR HY000: Unknown error
show status like 'prepared_stmt_count';
Variable_name Value
Prepared_stmt_count 0
set global max_prepared_stmt_count=3;
select @@max_prepared_stmt_count;
@@max_prepared_stmt_count
3
show status like 'prepared_stmt_count';
Variable_name Value
Prepared_stmt_count 0
prepare stmt from "select 1";
prepare stmt from "select 2";
prepare stmt1 from "select 3";
prepare stmt2 from "select 4";
ERROR HY000: Unknown error
prepare stmt2 from "select 4";
ERROR HY000: Unknown error
select @@max_prepared_stmt_count;
@@max_prepared_stmt_count
3
show status like 'prepared_stmt_count';
Variable_name Value
Prepared_stmt_count 3
deallocate prepare stmt;
set global max_prepared_stmt_count= @old_max_prepared_stmt_count;
drop table if exists t1;
create temporary table if not exists t1 (a1 int);
prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1";
drop temporary table t1;
create temporary table if not exists t1 (a1 int);
execute stmt;
drop temporary table t1;
create temporary table if not exists t1 (a1 int);
execute stmt;
drop temporary table t1;
create temporary table if not exists t1 (a1 int);
execute stmt;
drop temporary table t1;
deallocate prepare stmt;
CREATE TABLE t1(
ID int(10) unsigned NOT NULL auto_increment,
Member_ID varchar(15) NOT NULL default '',
Action varchar(12) NOT NULL,
Action_Date datetime NOT NULL,
Track varchar(15) default NULL,
User varchar(12) default NULL,
Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
CURRENT_TIMESTAMP,
PRIMARY KEY (ID),
KEY Action (Action),
KEY Action_Date (Action_Date)
);
INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
('111111', 'Enrolled', '2006-03-01', 'CAD' ),
('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
('222222', 'Enrolled', '2006-03-07', 'CAD' ),
('222222', 'Enrolled', '2006-03-07', 'CHF' ),
('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
('333333', 'Enrolled', '2006-03-01', 'CAD' ),
('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
('444444', 'Enrolled', '2006-03-01', 'CAD' ),
('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
('555555', 'Enrolled', '2006-07-21', 'CAD' ),
('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
('666666', 'Enrolled', '2006-02-09', 'CAD' ),
('666666', 'Enrolled', '2006-05-12', 'CHF' ),
('666666', 'Disenrolled', '2006-06-01', 'CAD' );
PREPARE STMT FROM
"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
WHERE Member_ID=? AND Action='Enrolled' AND
(Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
WHERE Member_ID=?
GROUP BY Track
HAVING Track>='CAD' AND
MAX(Action_Date)>'2006-03-01')";
SET @id='111111';
EXECUTE STMT USING @id,@id;
GROUP_CONCAT(Track SEPARATOR ', ')
NULL
SET @id='222222';
EXECUTE STMT USING @id,@id;
GROUP_CONCAT(Track SEPARATOR ', ')
CAD
DEALLOCATE PREPARE STMT;
DROP TABLE t1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (i INT, INDEX(i));
INSERT INTO t1 VALUES (1);
PREPARE stmt FROM "SELECT (COUNT(i) = 1), COUNT(i) FROM t1 WHERE i = ?";
SET @a = 0;
EXECUTE stmt USING @a;
(COUNT(i) = 1) COUNT(i)
0 0
SET @a = 1;
EXECUTE stmt USING @a;
(COUNT(i) = 1) COUNT(i)
1 1
SET @a = 0;
EXECUTE stmt USING @a;
(COUNT(i) = 1) COUNT(i)
0 0
PREPARE stmt FROM "SELECT (AVG(i) = 1), AVG(i) FROM t1 WHERE i = ?";
SET @a = 0;
EXECUTE stmt USING @a;
(AVG(i) = 1) AVG(i)
NULL NULL
SET @a = 1;
EXECUTE stmt USING @a;
(AVG(i) = 1) AVG(i)
1 1.0000
SET @a = 0;
EXECUTE stmt USING @a;
(AVG(i) = 1) AVG(i)
NULL NULL
PREPARE stmt FROM "SELECT (VARIANCE(i) = 1), VARIANCE(i) FROM t1 WHERE i = ?";
SET @a = 0;
EXECUTE stmt USING @a;
(VARIANCE(i) = 1) VARIANCE(i)
NULL NULL
SET @a = 1;
EXECUTE stmt USING @a;
(VARIANCE(i) = 1) VARIANCE(i)
0 0.0000
SET @a = 0;
EXECUTE stmt USING @a;
(VARIANCE(i) = 1) VARIANCE(i)
NULL NULL
PREPARE stmt FROM "SELECT (STDDEV(i) = 1), STDDEV(i) FROM t1 WHERE i = ?";
SET @a = 0;
EXECUTE stmt USING @a;
(STDDEV(i) = 1) STDDEV(i)
NULL NULL
SET @a = 1;
EXECUTE stmt USING @a;
(STDDEV(i) = 1) STDDEV(i)
0 0.0000
SET @a = 0;
EXECUTE stmt USING @a;
(STDDEV(i) = 1) STDDEV(i)
NULL NULL
PREPARE stmt FROM "SELECT (BIT_OR(i) = 1), BIT_OR(i) FROM t1 WHERE i = ?";
SET @a = 0;
EXECUTE stmt USING @a;
(BIT_OR(i) = 1) BIT_OR(i)
0 0
SET @a = 1;
EXECUTE stmt USING @a;
(BIT_OR(i) = 1) BIT_OR(i)
1 1
SET @a = 0;
EXECUTE stmt USING @a;
(BIT_OR(i) = 1) BIT_OR(i)
0 0
PREPARE stmt FROM "SELECT (BIT_AND(i) = 1), BIT_AND(i) FROM t1 WHERE i = ?";
SET @a = 0;
EXECUTE stmt USING @a;
(BIT_AND(i) = 1) BIT_AND(i)
0 18446744073709551615
SET @a = 1;
EXECUTE stmt USING @a;
(BIT_AND(i) = 1) BIT_AND(i)
1 1
SET @a = 0;
EXECUTE stmt USING @a;
(BIT_AND(i) = 1) BIT_AND(i)
0 18446744073709551615
PREPARE stmt FROM "SELECT (BIT_XOR(i) = 1), BIT_XOR(i) FROM t1 WHERE i = ?";
SET @a = 0;
EXECUTE stmt USING @a;
(BIT_XOR(i) = 1) BIT_XOR(i)
0 0
SET @a = 1;
EXECUTE stmt USING @a;
(BIT_XOR(i) = 1) BIT_XOR(i)
1 1
SET @a = 0;
EXECUTE stmt USING @a;
(BIT_XOR(i) = 1) BIT_XOR(i)
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` char(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) character set utf8 default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show create table mysqltest.t2;
Table Create Table
t2 CREATE TABLE `t2` (
`test` char(4) NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop database mysqltest;
deallocate prepare stmt1;
deallocate prepare stmt2;
execute stmt;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` char(10) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/'
drop table t1;
execute stmt;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` char(10) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/'
drop table t1;
deallocate prepare stmt;
End of 4.1 tests. End of 4.1 tests.
create table t1 (a varchar(20)); create table t1 (a varchar(20));
insert into t1 values ('foo'); insert into t1 values ('foo');
......
...@@ -1106,10 +1106,80 @@ EXECUTE stmt USING @a; ...@@ -1106,10 +1106,80 @@ EXECUTE stmt USING @a;
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
DROP TABLE t1; 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
--echo End of 4.1 tests. 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
--disable_query_log
eval prepare stmt from "create table t1 (c char(10)) data directory='$MYSQLTEST_VARDIR/tmp'";
--enable_query_log
execute stmt;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
show create table t1;
drop table t1;
execute stmt;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
show create table t1;
drop table t1;
deallocate prepare stmt;
--echo End of 4.1 tests.
############################# 5.0 tests start ################################ ############################# 5.0 tests start ################################
# #
......
...@@ -774,17 +774,15 @@ int prepare_create_field(create_field *sql_field, ...@@ -774,17 +774,15 @@ int prepare_create_field(create_field *sql_field,
uint table_flags); uint table_flags);
bool mysql_create_table(THD *thd,const char *db, const char *table_name, bool mysql_create_table(THD *thd,const char *db, const char *table_name,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
List<create_field> &fields, List<Key> &keys, Alter_info *alter_info,
bool tmp_table, uint select_field_count); bool tmp_table, uint select_field_count);
bool mysql_alter_table(THD *thd, char *new_db, char *new_name, bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
TABLE_LIST *table_list, TABLE_LIST *table_list,
List<create_field> &fields, Alter_info *alter_info,
List<Key> &keys, uint order_num, ORDER *order, bool ignore);
uint order_num, ORDER *order, bool ignore, bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list);
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, bool mysql_create_like_table(THD *thd, TABLE_LIST *table,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
Table_ident *src_table); Table_ident *src_table);
...@@ -793,9 +791,6 @@ bool mysql_rename_table(enum db_type base, ...@@ -793,9 +791,6 @@ bool mysql_rename_table(enum db_type base,
const char * old_name, const char * old_name,
const char *new_db, const char *new_db,
const char * new_name); const char * new_name);
bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &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, bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
Item **conds, uint order_num, ORDER *order); Item **conds, uint order_num, ORDER *order);
int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields, int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
...@@ -897,7 +892,8 @@ int get_quote_char_for_identifier(THD *thd, const char *name, uint length); ...@@ -897,7 +892,8 @@ int get_quote_char_for_identifier(THD *thd, const char *name, uint length);
void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild); void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd); int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd);
bool mysqld_show_create(THD *thd, TABLE_LIST *table_list); bool mysqld_show_create(THD *thd, TABLE_LIST *table_list);
bool mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create); bool mysqld_show_create_db(THD *thd, char *dbname,
const HA_CREATE_INFO *create);
void mysqld_list_processes(THD *thd,const char *user,bool verbose); void mysqld_list_processes(THD *thd,const char *user,bool verbose);
int mysqld_show_status(THD *thd); int mysqld_show_status(THD *thd);
......
...@@ -1840,21 +1840,22 @@ class select_insert :public select_result_interceptor { ...@@ -1840,21 +1840,22 @@ class select_insert :public select_result_interceptor {
class select_create: public select_insert { class select_create: public select_insert {
ORDER *group; ORDER *group;
TABLE_LIST *create_table; TABLE_LIST *create_table;
List<create_field> *extra_fields;
List<Key> *keys;
HA_CREATE_INFO *create_info; HA_CREATE_INFO *create_info;
Alter_info *alter_info;
MYSQL_LOCK *lock; MYSQL_LOCK *lock;
Field **field; Field **field;
public: public:
select_create (TABLE_LIST *table, select_create(TABLE_LIST *table,
HA_CREATE_INFO *create_info_par, HA_CREATE_INFO *create_info_arg,
List<create_field> &fields_par, Alter_info *alter_info_arg,
List<Key> &keys_par, List<Item> &select_fields,
List<Item> &select_fields,enum_duplicates duplic, bool ignore) enum_duplicates duplic, bool ignore)
:select_insert (NULL, NULL, &select_fields, 0, 0, duplic, ignore), create_table(table), :select_insert(NULL, NULL, &select_fields, 0, 0, duplic, ignore),
extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par), create_table(table),
create_info(create_info_arg),
alter_info(alter_info_arg),
lock(0) lock(0)
{} {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
void store_values(List<Item> &values); void store_values(List<Item> &values);
void send_error(uint errcode,const char *err); void send_error(uint errcode,const char *err);
......
...@@ -2764,7 +2764,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ...@@ -2764,7 +2764,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
unit= u; unit= u;
table= create_table_from_items(thd, create_info, create_table, table= create_table_from_items(thd, create_info, create_table,
extra_fields, keys, &values, &lock); alter_info, &values, &lock);
if (!table) if (!table)
DBUG_RETURN(-1); // abort() deletes table DBUG_RETURN(-1); // abort() deletes table
......
...@@ -1055,6 +1055,18 @@ int MYSQLlex(void *arg, void *yythd) ...@@ -1055,6 +1055,18 @@ 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),
is_simple(rhs.is_simple)
{}
/* /*
Skip comment in the end of statement. Skip comment in the end of statement.
......
...@@ -688,18 +688,58 @@ typedef class st_select_lex SELECT_LEX; ...@@ -688,18 +688,58 @@ typedef class st_select_lex SELECT_LEX;
#define ALTER_CONVERT 1024 #define ALTER_CONVERT 1024
#define ALTER_FORCE 2048 #define ALTER_FORCE 2048
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_drop> drop_list;
List<Alter_column> alter_list; List<Alter_column> alter_list;
List<Key> key_list;
List<create_field> create_list;
uint flags; uint flags;
enum enum_enable_or_disable keys_onoff; enum enum_enable_or_disable keys_onoff;
enum tablespace_op_type tablespace_op; enum tablespace_op_type tablespace_op;
st_alter_info(){clear();} Alter_info() :
void clear(){keys_onoff= LEAVE_AS_IS;tablespace_op= NO_TABLESPACE_OP;} flags(0),
void reset(){drop_list.empty();alter_list.empty();clear();} keys_onoff(LEAVE_AS_IS),
} ALTER_INFO; tablespace_op(NO_TABLESPACE_OP)
{}
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;
}
/**
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
};
struct st_sp_chistics struct st_sp_chistics
{ {
...@@ -885,8 +925,6 @@ typedef struct st_lex : public Query_tables_list ...@@ -885,8 +925,6 @@ typedef struct st_lex : public Query_tables_list
List<String> interval_list; List<String> interval_list;
List<LEX_USER> users_list; List<LEX_USER> users_list;
List<LEX_COLUMN> columns; List<LEX_COLUMN> columns;
List<Key> key_list;
List<create_field> create_list;
List<Item> *insert_list,field_list,value_list,update_list; List<Item> *insert_list,field_list,value_list,update_list;
List<List_item> many_values; List<List_item> many_values;
List<set_var_base> var_list; List<set_var_base> var_list;
...@@ -979,7 +1017,7 @@ typedef struct st_lex : public Query_tables_list ...@@ -979,7 +1017,7 @@ typedef struct st_lex : public Query_tables_list
bool safe_to_cache_query; bool safe_to_cache_query;
bool subqueries, ignore; bool subqueries, ignore;
st_parsing_options parsing_options; st_parsing_options parsing_options;
ALTER_INFO alter_info; Alter_info alter_info;
/* Prepared statements SQL syntax:*/ /* Prepared statements SQL syntax:*/
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */ LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
/* /*
......
...@@ -62,21 +62,24 @@ public: ...@@ -62,21 +62,24 @@ public:
pointer. 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; list_node *next;
void *info; void *info;
list_node(void *info_par,list_node *next_par) list_node(void *info_par,list_node *next_par)
:next(next_par),info(info_par) :next(next_par),info(info_par)
{} {}
list_node() /* For end_of_list */ list_node() /* For end_of_list */
{ {
info=0; info= 0;
next= this; next= this;
} }
friend class base_list;
friend class base_list_iterator;
}; };
...@@ -92,12 +95,57 @@ public: ...@@ -92,12 +95,57 @@ public:
inline void empty() { elements=0; first= &end_of_list; last=&first;} inline void empty() { elements=0; first= &end_of_list; last=&first;}
inline base_list() { empty(); } 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() inline base_list(const base_list &tmp) :Sql_alloc()
{ {
elements= tmp.elements; elements= tmp.elements;
first= tmp.first; first= tmp.first;
last= elements ? tmp.last : &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.
*/
inline 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;
}
inline base_list(bool error) { } inline base_list(bool error) { }
inline bool push_back(void *info) inline bool push_back(void *info)
{ {
...@@ -348,6 +396,8 @@ template <class T> class List :public base_list ...@@ -348,6 +396,8 @@ template <class T> class List :public base_list
public: public:
inline List() :base_list() {} inline List() :base_list() {}
inline List(const List<T> &tmp) :base_list(tmp) {} inline List(const List<T> &tmp) :base_list(tmp) {}
inline List(const List<T> &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) { return base_list::push_back(a); }
inline bool push_back(T *a, MEM_ROOT *mem_root) inline bool push_back(T *a, MEM_ROOT *mem_root)
{ return base_list::push_back(a, mem_root); } { return base_list::push_back(a, mem_root); }
......
This diff is collapsed.
...@@ -461,7 +461,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) ...@@ -461,7 +461,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
} }
bool mysqld_show_create_db(THD *thd, char *dbname, bool mysqld_show_create_db(THD *thd, char *dbname,
HA_CREATE_INFO *create_info) const HA_CREATE_INFO *create_info)
{ {
Security_context *sctx= thd->security_ctx; Security_context *sctx= thd->security_ctx;
int length; int length;
......
This diff is collapsed.
...@@ -1171,8 +1171,7 @@ create: ...@@ -1171,8 +1171,7 @@ create:
TL_READ_NO_INSERT: TL_READ_NO_INSERT:
TL_READ))) TL_READ)))
YYABORT; YYABORT;
lex->create_list.empty(); lex->alter_info.reset();
lex->key_list.empty();
lex->col_list.empty(); lex->col_list.empty();
lex->change=NullS; lex->change=NullS;
bzero((char*) &lex->create_info,sizeof(lex->create_info)); bzero((char*) &lex->create_info,sizeof(lex->create_info));
...@@ -1190,16 +1189,18 @@ create: ...@@ -1190,16 +1189,18 @@ create:
if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL, if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL,
TL_OPTION_UPDATING)) TL_OPTION_UPDATING))
YYABORT; YYABORT;
lex->create_list.empty(); lex->alter_info.reset();
lex->key_list.empty(); lex->alter_info.is_simple= 0;
lex->alter_info.flags= ALTER_ADD_INDEX;
lex->col_list.empty(); lex->col_list.empty();
lex->change=NullS; lex->change=NullS;
} }
'(' key_list ')' '(' key_list ')'
{ {
LEX *lex=Lex; LEX *lex=Lex;
Key *key= new Key($2, $4.str, $5, 0, lex->col_list);
lex->key_list.push_back(new Key($2,$4.str, $5, 0, lex->col_list)); lex->alter_info.key_list.push_back(key);
lex->col_list.empty(); lex->col_list.empty();
} }
| CREATE DATABASE opt_if_not_exists ident | CREATE DATABASE opt_if_not_exists ident
...@@ -2734,29 +2735,34 @@ key_def: ...@@ -2734,29 +2735,34 @@ key_def:
key_type opt_ident key_alg '(' key_list ')' key_type opt_ident key_alg '(' key_list ')'
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->key_list.push_back(new Key($1,$2, $3, 0, lex->col_list)); Key *key= new Key($1, $2, $3, 0, lex->col_list);
lex->alter_info.key_list.push_back(key);
lex->col_list.empty(); /* Alloced by sql_alloc */ lex->col_list.empty(); /* Alloced by sql_alloc */
} }
| opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')' | opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')'
{ {
LEX *lex=Lex; LEX *lex=Lex;
const char *key_name= $3 ? $3:$1; const char *key_name= $3 ? $3:$1;
lex->key_list.push_back(new Key($2, key_name, $4, 0, Key *key= new Key($2, key_name, $4, 0, lex->col_list);
lex->col_list)); lex->alter_info.key_list.push_back(key);
lex->col_list.empty(); /* Alloced by sql_alloc */ lex->col_list.empty(); /* Alloced by sql_alloc */
} }
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->key_list.push_back(new foreign_key($4 ? $4:$1, lex->col_list, const char *key_name= $4 ? $4 : $1;
$8, Key *key= new foreign_key(key_name, lex->col_list,
lex->ref_list, $8,
lex->fk_delete_opt, lex->ref_list,
lex->fk_update_opt, lex->fk_delete_opt,
lex->fk_match_option)); lex->fk_update_opt,
lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4 : $1, lex->fk_match_option);
HA_KEY_ALG_UNDEF, 1, lex->alter_info.key_list.push_back(key);
lex->col_list)); key= new Key(Key::MULTIPLE, key_name,
HA_KEY_ALG_UNDEF, 1,
lex->col_list);
lex->alter_info.key_list.push_back(key);
lex->col_list.empty(); /* Alloced by sql_alloc */ lex->col_list.empty(); /* Alloced by sql_alloc */
} }
| constraint opt_check_constraint | constraint opt_check_constraint
...@@ -3298,8 +3304,6 @@ alter: ...@@ -3298,8 +3304,6 @@ alter:
if (!lex->select_lex.add_table_to_list(thd, $4, NULL, if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
TL_OPTION_UPDATING)) TL_OPTION_UPDATING))
YYABORT; YYABORT;
lex->create_list.empty();
lex->key_list.empty();
lex->col_list.empty(); lex->col_list.empty();
lex->select_lex.init_order(); lex->select_lex.init_order();
lex->select_lex.db= lex->select_lex.db=
...@@ -3310,7 +3314,6 @@ alter: ...@@ -3310,7 +3314,6 @@ alter:
lex->create_info.default_table_charset= NULL; lex->create_info.default_table_charset= NULL;
lex->create_info.row_type= ROW_TYPE_NOT_USED; lex->create_info.row_type= ROW_TYPE_NOT_USED;
lex->alter_info.reset(); lex->alter_info.reset();
lex->alter_info.flags= 0;
} }
alter_list alter_list
{} {}
...@@ -6072,7 +6075,9 @@ drop: ...@@ -6072,7 +6075,9 @@ drop:
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->sql_command= SQLCOM_DROP_INDEX; lex->sql_command= SQLCOM_DROP_INDEX;
lex->alter_info.drop_list.empty(); lex->alter_info.reset();
lex->alter_info.is_simple= 0;
lex->alter_info.flags= ALTER_DROP_INDEX;
lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY,
$3.str)); $3.str));
if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL, if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment