Merge bk-internal:/home/bk/mysql-5.1-new

into  neptunus.(none):/home/msvensson/mysql/mysql-5.1
This commit is contained in:
unknown 2006-03-10 12:14:18 +01:00
commit 888f96769e
26 changed files with 464 additions and 78 deletions

View file

@ -96,6 +96,7 @@ static my_bool verbose=0,tFlag=0,dFlag=0,quick= 1, extended_insert= 1,
opt_complete_insert= 0, opt_drop_database= 0, opt_complete_insert= 0, opt_drop_database= 0,
opt_replace_into= 0, opt_replace_into= 0,
opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1, opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
opt_events= 0,
opt_alltspcs=0; opt_alltspcs=0;
static ulong opt_max_allowed_packet, opt_net_buffer_length; static ulong opt_max_allowed_packet, opt_net_buffer_length;
static MYSQL mysql_connection,*sock=0; static MYSQL mysql_connection,*sock=0;
@ -232,6 +233,9 @@ static struct my_option my_long_options[] =
{"disable-keys", 'K', {"disable-keys", 'K',
"'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys, "'/*!40000 ALTER TABLE tb_name DISABLE KEYS */; and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */; will be put in the output.", (gptr*) &opt_disable_keys,
(gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, (gptr*) &opt_disable_keys, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"events", 'E', "Dump events.",
(gptr*) &opt_events, (gptr*) &opt_events, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"extended-insert", 'e', {"extended-insert", 'e',
"Allows utilization of the new, much faster INSERT syntax.", "Allows utilization of the new, much faster INSERT syntax.",
(gptr*) &extended_insert, (gptr*) &extended_insert, 0, GET_BOOL, NO_ARG, (gptr*) &extended_insert, (gptr*) &extended_insert, 0, GET_BOOL, NO_ARG,
@ -1239,9 +1243,136 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
check_io(xml_file); check_io(xml_file);
} }
/*
create_delimiter
Generate a new (null-terminated) string that does not exist in query
and is therefore suitable for use as a query delimiter. Store this
delimiter in delimiter_buff .
This is quite simple in that it doesn't even try to parse statements as an
interpreter would. It merely returns a string that is not in the query, which
is much more than adequate for constructing a delimiter.
RETURN
ptr to the delimiter on Success
NULL on Failure
*/
static char *create_delimiter(char *query, char *delimiter_buff,
int delimiter_max_size)
{
int proposed_length;
char *presence;
delimiter_buff[0]= ';'; /* start with one semicolon, and */
for (proposed_length= 2; proposed_length < delimiter_max_size;
delimiter_max_size++) {
delimiter_buff[proposed_length-1]= ';'; /* add semicolons, until */
delimiter_buff[proposed_length]= '\0';
presence = strstr(query, delimiter_buff);
if (presence == NULL) { /* the proposed delimiter is not in the query. */
return delimiter_buff;
}
}
return NULL; /* but if we run out of space, return nothing at all. */
}
/*
dump_events_for_db
-- retrieves list of events for a given db, and prints out
the CREATE EVENT statement into the output (the dump).
RETURN
0 Success
1 Error
*/
static uint dump_events_for_db(char *db)
{
char query_buff[QUERY_LENGTH];
char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
char *event_name;
char delimiter[QUERY_LENGTH], *delimit_test;
FILE *sql_file= md_result_file;
MYSQL_RES *event_res, *event_list_res;
MYSQL_ROW row, event_list_row;
DBUG_ENTER("dump_events_for_db");
DBUG_PRINT("enter", ("db: '%s'", db));
mysql_real_escape_string(sock, db_name_buff, db, strlen(db));
/* nice comments */
if (opt_comments)
fprintf(sql_file, "\n--\n-- Dumping events for database '%s'\n--\n", db);
/*
not using "mysql_query_with_error_report" because we may have not
enough privileges to lock mysql.events.
*/
if (lock_tables)
mysql_query(sock, "LOCK TABLES mysql.event READ");
if (mysql_query_with_error_report(sock, &event_list_res, "show events"))
{
safe_exit(EX_MYSQLERR);
DBUG_RETURN(0);
}
strcpy(delimiter, ";");
if (mysql_num_rows(event_list_res) > 0)
{
while ((event_list_row= mysql_fetch_row(event_list_res)) != NULL)
{
event_name= quote_name(event_list_row[1], name_buff, 0);
DBUG_PRINT("info", ("retrieving CREATE EVENT for %s", name_buff));
my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE EVENT %s",
event_name);
if (mysql_query_with_error_report(sock, &event_res, query_buff))
DBUG_RETURN(1);
while ((row= mysql_fetch_row(event_res)) != NULL)
{
/*
if the user has EXECUTE privilege he can see event names, but not the
event body!
*/
if (strlen(row[2]) != 0)
{
if (opt_drop)
fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n",
event_name, delimiter);
delimit_test= create_delimiter(row[2], delimiter, sizeof(delimiter));
if (delimit_test == NULL) {
fprintf(stderr, "%s: Warning: Can't dump event '%s'\n",
event_name, my_progname);
DBUG_RETURN(1);
}
fprintf(sql_file, "DELIMITER %s\n", delimiter);
fprintf(sql_file, "/*!50106 %s */ %s\n", row[2], delimiter);
}
} /* end of event printing */
} /* end of list of events */
fprintf(sql_file, "DELIMITER ;\n");
mysql_free_result(event_res);
}
mysql_free_result(event_list_res);
if (lock_tables)
VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"));
DBUG_RETURN(0);
}
/* /*
dump_routines_for_db dump_routines_for_db
-- retrievs list of routines for a given db, and prints out -- retrieves list of routines for a given db, and prints out
the CREATE PROCEDURE definition into the output (the dump). the CREATE PROCEDURE definition into the output (the dump).
This function has logic to print the appropriate syntax depending on whether This function has logic to print the appropriate syntax depending on whether
@ -1254,7 +1385,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
static uint dump_routines_for_db(char *db) static uint dump_routines_for_db(char *db)
{ {
char query_buff[512]; char query_buff[QUERY_LENGTH];
const char *routine_type[]= {"FUNCTION", "PROCEDURE"}; const char *routine_type[]= {"FUNCTION", "PROCEDURE"};
char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3]; char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
char *routine_name; char *routine_name;
@ -1295,9 +1426,9 @@ static uint dump_routines_for_db(char *db)
while ((routine_list_row= mysql_fetch_row(routine_list_res))) while ((routine_list_row= mysql_fetch_row(routine_list_res)))
{ {
routine_name= quote_name(routine_list_row[1], name_buff, 0);
DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type[i], DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type[i],
name_buff)); name_buff));
routine_name= quote_name(routine_list_row[1], name_buff, 0);
my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s", my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s",
routine_type[i], routine_name); routine_type[i], routine_name);
@ -1410,7 +1541,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
char *result_table, *opt_quoted_table; char *result_table, *opt_quoted_table;
const char *insert_option; const char *insert_option;
char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3]; char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
char table_buff2[NAME_LEN*2+3], query_buff[512]; char table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
FILE *sql_file = md_result_file; FILE *sql_file = md_result_file;
int len; int len;
MYSQL_RES *result; MYSQL_RES *result;
@ -1886,7 +2017,7 @@ static void dump_triggers_for_table (char *table, char *db)
{ {
char *result_table; char *result_table;
char name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3]; char name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3];
char query_buff[512]; char query_buff[QUERY_LENGTH];
uint old_opt_compatible_mode=opt_compatible_mode; uint old_opt_compatible_mode=opt_compatible_mode;
FILE *sql_file = md_result_file; FILE *sql_file = md_result_file;
MYSQL_RES *result; MYSQL_RES *result;
@ -2546,7 +2677,6 @@ static int dump_all_tablespaces()
{ {
MYSQL_ROW row; MYSQL_ROW row;
MYSQL_RES *tableres; MYSQL_RES *tableres;
int result=0;
char buf[FN_REFLEN]; char buf[FN_REFLEN];
int first; int first;
@ -2844,6 +2974,12 @@ static int dump_all_tables_in_db(char *database)
dump_triggers_for_table(table, database); dump_triggers_for_table(table, database);
} }
} }
if (opt_events && !opt_xml &&
mysql_get_server_version(sock) >= 50106)
{
DBUG_PRINT("info", ("Dumping events for database %s", database));
dump_events_for_db(database);
}
if (opt_routines && !opt_xml && if (opt_routines && !opt_xml &&
mysql_get_server_version(sock) >= 50009) mysql_get_server_version(sock) >= 50009)
{ {
@ -3054,6 +3190,12 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
get_view_structure(table_name, db); get_view_structure(table_name, db);
} }
} }
if (opt_events && !opt_xml &&
mysql_get_server_version(sock) >= 50106)
{
DBUG_PRINT("info", ("Dumping events for database %s", db));
dump_events_for_db(db);
}
/* obtain dump of routines (procs/functions) */ /* obtain dump of routines (procs/functions) */
if (opt_routines && !opt_xml && if (opt_routines && !opt_xml &&
mysql_get_server_version(sock) >= 50009) mysql_get_server_version(sock) >= 50009)

View file

@ -2907,3 +2907,40 @@ mysql-import: Error: 1146, Table 'test.words' doesn't exist, when using table: w
drop table t1; drop table t1;
drop table t2; drop table t2;
drop table words2; drop table words2;
create database first;
use first;
set time_zone = 'UTC';
create event ee1 on schedule at '2035-12-31 20:01:23' do set @a=5;
show events;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
first ee1 root@localhost ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED
show create event ee1;
Event sql_mode Create Event
ee1 CREATE EVENT `ee1` ON SCHEDULE AT '2035-12-31 20:01:23' ON COMPLETION NOT PRESERVE ENABLE DO set @a=5
drop database first;
create database second;
use second;
show events;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
second ee1 root@localhost ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED
show create event ee1;
Event sql_mode Create Event
ee1 NO_AUTO_VALUE_ON_ZERO CREATE EVENT `ee1` ON SCHEDULE AT '2035-12-31 20:01:23' ON COMPLETION NOT PRESERVE ENABLE DO set @a=5
create event ee2 on schedule at '2018-12-31 21:01:23' do set @a=5;
create event ee3 on schedule at '2030-12-31 22:01:23' do set @a=5;
show events;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
second ee1 root@localhost ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED
second ee2 root@localhost ONE TIME 2018-12-31 21:01:23 NULL NULL NULL NULL ENABLED
second ee3 root@localhost ONE TIME 2030-12-31 22:01:23 NULL NULL NULL NULL ENABLED
drop database second;
create database third;
use third;
show events;
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
third ee1 root@localhost ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED
third ee2 root@localhost ONE TIME 2018-12-31 21:01:23 NULL NULL NULL NULL ENABLED
third ee3 root@localhost ONE TIME 2030-12-31 22:01:23 NULL NULL NULL NULL ENABLED
drop database third;
set time_zone = 'SYSTEM';
use test;

View file

@ -1,9 +1,9 @@
drop table if exists t1, t2, t3, t4, t5, t6, t7, t8; drop table if exists t1, t2, t3, t4, t5, t6, t7, t8;
CREATE TABLE t1 ( CREATE TABLE t1 (
a int unsigned NOT NULL PRIMARY KEY, a int NOT NULL PRIMARY KEY,
b int unsigned not null, b int not null,
c int unsigned, c int,
UNIQUE(b) UNIQUE ib(b)
) engine=ndbcluster; ) engine=ndbcluster;
insert t1 values(1, 2, 3), (2, 3, 5), (3, 4, 6), (4, 5, 8), (5,6, 2), (6,7, 2); insert t1 values(1, 2, 3), (2, 3, 5), (3, 4, 6), (4, 5, 8), (5,6, 2), (6,7, 2);
select * from t1 order by b; select * from t1 order by b;
@ -43,6 +43,8 @@ a b c
6 7 2 6 7 2
7 8 3 7 8 3
8 2 3 8 2 3
alter table t1 drop index ib;
insert into t1 values(1, 2, 3);
drop table t1; drop table t1;
CREATE TABLE t1 ( CREATE TABLE t1 (
a int unsigned NOT NULL PRIMARY KEY, a int unsigned NOT NULL PRIMARY KEY,

View file

@ -422,4 +422,10 @@ partition_name partition_description table_rows
x123 11,12 1 x123 11,12 1
x234 NULL,1 1 x234 NULL,1 1
drop table t1; drop table t1;
create table t1 (a int)
partition by list (a)
(partition p0 values in (1));
alter table t1 rebuild partition;
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 '' at line 1
drop table t1;
End of 5.1 tests End of 5.1 tests

View file

@ -1166,3 +1166,43 @@ drop table t1;
drop table t2; drop table t2;
drop table words2; drop table words2;
#
# BUG# 16853: mysqldump doesn't show events
#
create database first;
use first;
set time_zone = 'UTC';
## prove one works
create event ee1 on schedule at '2035-12-31 20:01:23' do set @a=5;
show events;
show create event ee1;
--exec $MYSQL_DUMP --events first > $MYSQLTEST_VARDIR/tmp/bug16853-1.sql
drop database first;
create database second;
use second;
--exec $MYSQL second < $MYSQLTEST_VARDIR/tmp/bug16853-1.sql
show events;
show create event ee1;
## prove three works
# start with one from the previous restore
create event ee2 on schedule at '2018-12-31 21:01:23' do set @a=5;
create event ee3 on schedule at '2030-12-31 22:01:23' do set @a=5;
show events;
--exec $MYSQL_DUMP --events second > $MYSQLTEST_VARDIR/tmp/bug16853-2.sql
drop database second;
create database third;
use third;
--exec $MYSQL third < $MYSQLTEST_VARDIR/tmp/bug16853-2.sql
show events;
drop database third;
# revert back to normal settings
set time_zone = 'SYSTEM';
use test;
#####

View file

@ -10,10 +10,10 @@ drop table if exists t1, t2, t3, t4, t5, t6, t7, t8;
# #
CREATE TABLE t1 ( CREATE TABLE t1 (
a int unsigned NOT NULL PRIMARY KEY, a int NOT NULL PRIMARY KEY,
b int unsigned not null, b int not null,
c int unsigned, c int,
UNIQUE(b) UNIQUE ib(b)
) engine=ndbcluster; ) engine=ndbcluster;
insert t1 values(1, 2, 3), (2, 3, 5), (3, 4, 6), (4, 5, 8), (5,6, 2), (6,7, 2); insert t1 values(1, 2, 3), (2, 3, 5), (3, 4, 6), (4, 5, 8), (5,6, 2), (6,7, 2);
@ -29,6 +29,12 @@ delete from t1 where a = 1;
insert into t1 values(8, 2, 3); insert into t1 values(8, 2, 3);
select * from t1 order by a; select * from t1 order by a;
alter table t1 drop index ib;
insert into t1 values(1, 2, 3);
# Bug# #18129
#--error 1169
#create unique index ib on t1(b);
drop table t1; drop table t1;
# #

View file

@ -540,4 +540,16 @@ select partition_name, partition_description, table_rows
from information_schema.partitions where table_schema ='test'; from information_schema.partitions where table_schema ='test';
drop table t1; drop table t1;
#
# BUG 17947 Crash with REBUILD PARTITION
#
create table t1 (a int)
partition by list (a)
(partition p0 values in (1));
--error 1064
alter table t1 rebuild partition;
drop table t1;
--echo End of 5.1 tests --echo End of 5.1 tests

View file

@ -14,13 +14,14 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_LEX 1
#include "event_priv.h" #include "event_priv.h"
#include "event.h" #include "event.h"
#include "sp.h" #include "sp.h"
extern int yyparse(void *thd); extern int MYSQLparse(void *thd);
/* /*
Init all member variables Init all member variables
@ -1063,8 +1064,6 @@ Event_timed::get_create_event(THD *thd, String *buf)
DBUG_RETURN(EVEX_MICROSECOND_UNSUP); DBUG_RETURN(EVEX_MICROSECOND_UNSUP);
buf->append(STRING_WITH_LEN("CREATE EVENT ")); buf->append(STRING_WITH_LEN("CREATE EVENT "));
append_identifier(thd, buf, dbname.str, dbname.length);
buf->append(STRING_WITH_LEN("."));
append_identifier(thd, buf, name.str, name.length); append_identifier(thd, buf, name.str, name.length);
buf->append(STRING_WITH_LEN(" ON SCHEDULE ")); buf->append(STRING_WITH_LEN(" ON SCHEDULE "));
@ -1338,7 +1337,7 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root)
thd->lex= &lex; thd->lex= &lex;
lex_start(thd, (uchar*)thd->query, thd->query_length); lex_start(thd, (uchar*)thd->query, thd->query_length);
lex.et_compile_phase= TRUE; lex.et_compile_phase= TRUE;
if (yyparse((void *)thd) || thd->is_fatal_error) if (MYSQLparse((void *)thd) || thd->is_fatal_error)
{ {
DBUG_PRINT("error", ("error during compile or thd->is_fatal_error=%d", DBUG_PRINT("error", ("error during compile or thd->is_fatal_error=%d",
thd->is_fatal_error)); thd->is_fatal_error));

View file

@ -1319,13 +1319,11 @@ int ha_ndbcluster::drop_indexes(Ndb *ndb, TABLE *tab)
int error= 0; int error= 0;
const char *index_name; const char *index_name;
KEY* key_info= tab->key_info; KEY* key_info= tab->key_info;
const char **key_name= tab->s->keynames.type_names;
NDBDICT *dict= ndb->getDictionary(); NDBDICT *dict= ndb->getDictionary();
DBUG_ENTER("ha_ndbcluster::drop_indexes"); DBUG_ENTER("ha_ndbcluster::drop_indexes");
for (i= 0; i < tab->s->keys; i++, key_info++, key_name++) for (i= 0; i < tab->s->keys; i++, key_info++)
{ {
index_name= *key_name;
NDB_INDEX_TYPE idx_type= get_index_type_from_table(i); NDB_INDEX_TYPE idx_type= get_index_type_from_table(i);
m_index[i].type= idx_type; m_index[i].type= idx_type;
if (m_index[i].status == TO_BE_DROPPED) if (m_index[i].status == TO_BE_DROPPED)
@ -1346,8 +1344,8 @@ int ha_ndbcluster::drop_indexes(Ndb *ndb, TABLE *tab)
m_index[i].index= NULL; m_index[i].index= NULL;
if (!error && unique_index) if (!error && unique_index)
{ {
index_name= index->getName(); index_name= unique_index->getName();
DBUG_PRINT("info", ("Dropping index %u: %s", i, index_name)); DBUG_PRINT("info", ("Dropping unique index %u: %s", i, index_name));
// Drop unique index from ndb // Drop unique index from ndb
error= drop_ndb_index(index_name); error= drop_ndb_index(index_name);
} }

View file

@ -1477,7 +1477,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp,
if (do_close_cached_tables) if (do_close_cached_tables)
close_cached_tables((THD*) 0, 0, (TABLE_LIST*) 0); close_cached_tables((THD*) 0, 0, (TABLE_LIST*) 0);
return 0; DBUG_RETURN(0);
} }
static int static int

View file

@ -1223,7 +1223,7 @@ File open_binlog(IO_CACHE *log, const char *log_file_name,
const char **errmsg); const char **errmsg);
/* mysqld.cc */ /* mysqld.cc */
extern void yyerror(const char*); extern void MYSQLerror(const char*);
/* item_func.cc */ /* item_func.cc */
extern bool check_reserved_words(LEX_STRING *name); extern bool check_reserved_words(LEX_STRING *name);
@ -1634,7 +1634,7 @@ void free_list(I_List <i_string_pair> *list);
void free_list(I_List <i_string> *list); void free_list(I_List <i_string> *list);
/* sql_yacc.cc */ /* sql_yacc.cc */
extern int yyparse(void *thd); extern int MYSQLparse(void *thd);
/* frm_crypt.cc */ /* frm_crypt.cc */
#ifdef HAVE_CRYPTED_FRM #ifdef HAVE_CRYPTED_FRM

View file

@ -1620,7 +1620,7 @@ static void network_init(void)
#endif /*!EMBEDDED_LIBRARY*/ #endif /*!EMBEDDED_LIBRARY*/
void yyerror(const char *s) void MYSQLerror(const char *s)
{ {
THD *thd=current_thd; THD *thd=current_thd;
char *yytext= (char*) thd->lex->tok_start; char *yytext= (char*) thd->lex->tok_start;

View file

@ -268,7 +268,7 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table)
static int static int
db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
{ {
extern int yyparse(void *thd); extern int MYSQLparse(void *thd);
TABLE *table; TABLE *table;
const char *params, *returns, *body; const char *params, *returns, *body;
int ret; int ret;
@ -458,7 +458,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
lex_start(thd, (uchar*)defstr.c_ptr(), defstr.length()); lex_start(thd, (uchar*)defstr.c_ptr(), defstr.length());
thd->spcont= 0; thd->spcont= 0;
if (yyparse(thd) || thd->is_fatal_error || newlex.sphead == NULL) if (MYSQLparse(thd) || thd->is_fatal_error || newlex.sphead == NULL)
{ {
sp_head *sp= newlex.sphead; sp_head *sp= newlex.sphead;

View file

@ -513,14 +513,14 @@ static inline uint int_token(const char *str,uint length)
} }
/* /*
yylex remember the following states from the following yylex() MYSQLlex remember the following states from the following MYSQLlex()
- MY_LEX_EOQ Found end of query - MY_LEX_EOQ Found end of query
- MY_LEX_OPERATOR_OR_IDENT Last state was an ident, text or number - MY_LEX_OPERATOR_OR_IDENT Last state was an ident, text or number
(which can't be followed by a signed number) (which can't be followed by a signed number)
*/ */
int yylex(void *arg, void *yythd) int MYSQLlex(void *arg, void *yythd)
{ {
reg1 uchar c; reg1 uchar c;
int tokval, result_state; int tokval, result_state;

View file

@ -757,7 +757,7 @@ typedef struct st_lex
const uchar *buf; /* The beginning of string, used by SPs */ const uchar *buf; /* The beginning of string, used by SPs */
const uchar *ptr,*tok_start,*tok_end,*end_of_query; const uchar *ptr,*tok_start,*tok_end,*end_of_query;
/* The values of tok_start/tok_end as they were one call of yylex before */ /* The values of tok_start/tok_end as they were one call of MYSQLlex before */
const uchar *tok_start_prev, *tok_end_prev; const uchar *tok_start_prev, *tok_end_prev;
char *length,*dec,*change,*name; char *length,*dec,*change,*name;
@ -1119,7 +1119,7 @@ extern void lex_init(void);
extern void lex_free(void); extern void lex_free(void);
extern void lex_start(THD *thd, const uchar *buf, uint length); extern void lex_start(THD *thd, const uchar *buf, uint length);
extern void lex_end(LEX *lex); extern void lex_end(LEX *lex);
extern int yylex(void *arg, void *yythd); extern int MYSQLlex(void *arg, void *yythd);
extern pthread_key(LEX*,THR_LEX); extern pthread_key(LEX*,THR_LEX);

View file

@ -4379,7 +4379,7 @@ end_with_restore_list:
/* /*
We must cleanup the unit and the lex here because We must cleanup the unit and the lex here because
sp_grant_privileges calls (indirectly) db_find_routine, sp_grant_privileges calls (indirectly) db_find_routine,
which in turn may call yyparse with THD::lex. which in turn may call MYSQLparse with THD::lex.
TODO: fix db_find_routine to use a temporary lex. TODO: fix db_find_routine to use a temporary lex.
*/ */
lex->unit.cleanup(); lex->unit.cleanup();
@ -5818,7 +5818,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
sp_cache_flush_obsolete(&thd->sp_proc_cache); sp_cache_flush_obsolete(&thd->sp_proc_cache);
sp_cache_flush_obsolete(&thd->sp_func_cache); sp_cache_flush_obsolete(&thd->sp_func_cache);
if (!yyparse((void *)thd) && ! thd->is_fatal_error) if (!MYSQLparse((void *)thd) && ! thd->is_fatal_error)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (mqh_used && thd->user_connect && if (mqh_used && thd->user_connect &&
@ -5910,7 +5910,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
DBUG_ENTER("mysql_test_parse_for_slave"); DBUG_ENTER("mysql_test_parse_for_slave");
mysql_init_query(thd, (uchar*) inBuf, length); mysql_init_query(thd, (uchar*) inBuf, length);
if (!yyparse((void*) thd) && ! thd->is_fatal_error && if (!MYSQLparse((void*) thd) && ! thd->is_fatal_error &&
all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first)) all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
error= 1; /* Ignore question */ error= 1; /* Ignore question */
thd->end_statement(); thd->end_statement();

View file

@ -33,6 +33,7 @@
/* Some general useful functions */ /* Some general useful functions */
#define MYSQL_LEX 1
#include "mysql_priv.h" #include "mysql_priv.h"
#include <errno.h> #include <errno.h>
#include <m_ctype.h> #include <m_ctype.h>
@ -3697,7 +3698,7 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf,
we then save in the partition info structure. we then save in the partition info structure.
*/ */
thd->free_list= NULL; thd->free_list= NULL;
lex.part_info= new partition_info();/* Indicates yyparse from this place */ lex.part_info= new partition_info();/* Indicates MYSQLparse from this place */
if (!lex.part_info) if (!lex.part_info)
{ {
mem_alloc_error(sizeof(partition_info)); mem_alloc_error(sizeof(partition_info));
@ -3706,7 +3707,7 @@ bool mysql_unpack_partition(THD *thd, const uchar *part_buf,
lex.part_info->part_state= part_state; lex.part_info->part_state= part_state;
lex.part_info->part_state_len= part_state_len; lex.part_info->part_state_len= part_state_len;
DBUG_PRINT("info", ("Parse: %s", part_buf)); DBUG_PRINT("info", ("Parse: %s", part_buf));
if (yyparse((void*)thd) || thd->is_fatal_error) if (MYSQLparse((void*)thd) || thd->is_fatal_error)
{ {
free_items(thd->free_list); free_items(thd->free_list);
goto end; goto end;

View file

@ -2758,7 +2758,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
lex_start(thd, (uchar*) thd->query, thd->query_length); lex_start(thd, (uchar*) thd->query, thd->query_length);
lex->stmt_prepare_mode= TRUE; lex->stmt_prepare_mode= TRUE;
error= yyparse((void *)thd) || thd->is_fatal_error || error= MYSQLparse((void *)thd) || thd->is_fatal_error ||
thd->net.report_error || init_param_array(this); thd->net.report_error || init_param_array(this);
lex->safe_to_cache_query= FALSE; lex->safe_to_cache_query= FALSE;
/* /*

View file

@ -15,6 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_LEX 1
#include "mysql_priv.h" #include "mysql_priv.h"
#include "sp_head.h" #include "sp_head.h"
#include "sql_trigger.h" #include "sql_trigger.h"
@ -928,7 +929,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
lex_start(thd, (uchar*)trg_create_str->str, trg_create_str->length); lex_start(thd, (uchar*)trg_create_str->str, trg_create_str->length);
thd->spcont= 0; thd->spcont= 0;
if (yyparse((void *)thd) || thd->is_fatal_error) if (MYSQLparse((void *)thd) || thd->is_fatal_error)
{ {
/* /*
Free lex associated resources. Free lex associated resources.

View file

@ -15,6 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#define MYSQL_LEX 1
#include "mysql_priv.h" #include "mysql_priv.h"
#include "sql_select.h" #include "sql_select.h"
#include "parse_file.h" #include "parse_file.h"
@ -891,7 +892,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES); MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES);
CHARSET_INFO *save_cs= thd->variables.character_set_client; CHARSET_INFO *save_cs= thd->variables.character_set_client;
thd->variables.character_set_client= system_charset_info; thd->variables.character_set_client= system_charset_info;
res= yyparse((void *)thd); res= MYSQLparse((void *)thd);
thd->variables.character_set_client= save_cs; thd->variables.character_set_client= save_cs;
thd->variables.sql_mode= save_mode; thd->variables.sql_mode= save_mode;
} }

View file

@ -4953,7 +4953,7 @@ alter_commands:
; ;
all_or_alt_part_name_list: all_or_alt_part_name_list:
| ALL ALL
{ {
Lex->alter_info.flags|= ALTER_ALL_PARTITION; Lex->alter_info.flags|= ALTER_ALL_PARTITION;
} }

View file

@ -1092,6 +1092,7 @@ Suma::execSUB_CREATE_REQ(Signal* signal)
subPtr.p->m_table_ptrI = RNIL; subPtr.p->m_table_ptrI = RNIL;
subPtr.p->m_state = Subscription::DEFINED; subPtr.p->m_state = Subscription::DEFINED;
subPtr.p->n_subscribers = 0; subPtr.p->n_subscribers = 0;
subPtr.p->m_current_sync_ptrI = RNIL;
fprintf(stderr, "table %d options %x\n", subPtr.p->m_tableId, subPtr.p->m_options); fprintf(stderr, "table %d options %x\n", subPtr.p->m_tableId, subPtr.p->m_options);
DBUG_PRINT("info",("Added: key.m_subscriptionId: %u, key.m_subscriptionKey: %u", DBUG_PRINT("info",("Added: key.m_subscriptionId: %u, key.m_subscriptionKey: %u",
@ -1163,13 +1164,15 @@ Suma::execSUB_SYNC_REQ(Signal* signal)
DBUG_PRINT("info",("c_syncPool size: %d free: %d", DBUG_PRINT("info",("c_syncPool size: %d free: %d",
c_syncPool.getSize(), c_syncPool.getSize(),
c_syncPool.getNoOfFree())); c_syncPool.getNoOfFree()));
new (syncPtr.p) Ptr<SyncRecord>;
syncPtr.p->m_senderRef = req->senderRef; syncPtr.p->m_senderRef = req->senderRef;
syncPtr.p->m_senderData = req->senderData; syncPtr.p->m_senderData = req->senderData;
syncPtr.p->m_subscriptionPtrI = subPtr.i; syncPtr.p->m_subscriptionPtrI = subPtr.i;
syncPtr.p->ptrI = syncPtr.i; syncPtr.p->ptrI = syncPtr.i;
syncPtr.p->m_error = 0; syncPtr.p->m_error = 0;
subPtr.p->m_current_sync_ptrI = syncPtr.i;
{ {
jam(); jam();
syncPtr.p->m_tableList.append(&subPtr.p->m_tableId, 1); syncPtr.p->m_tableList.append(&subPtr.p->m_tableId, 1);
@ -2059,7 +2062,7 @@ Suma::execSUB_SYNC_CONTINUE_CONF(Signal* signal){
ndbrequire(c_subscriptions.find(subPtr, key)); ndbrequire(c_subscriptions.find(subPtr, key));
ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend(); ScanFragNextReq * req = (ScanFragNextReq *)signal->getDataPtrSend();
req->senderData = subPtr.i; req->senderData = subPtr.p->m_current_sync_ptrI;
req->closeFlag = 0; req->closeFlag = 0;
req->transId1 = 0; req->transId1 = 0;
req->transId2 = (SUMA << 20) + (getOwnNodeId() << 8); req->transId2 = (SUMA << 20) + (getOwnNodeId() << 8);
@ -2098,6 +2101,12 @@ Suma::SyncRecord::completeScan(Signal* signal, int error)
#endif #endif
release(); release();
Ptr<Subscription> subPtr;
suma.c_subscriptions.getPtr(subPtr, m_subscriptionPtrI);
ndbrequire(subPtr.p->m_current_sync_ptrI == ptrI);
subPtr.p->m_current_sync_ptrI = RNIL;
suma.c_syncPool.release(ptrI); suma.c_syncPool.release(ptrI);
DBUG_PRINT("info",("c_syncPool size: %d free: %d", DBUG_PRINT("info",("c_syncPool size: %d free: %d",
suma.c_syncPool.getSize(), suma.c_syncPool.getSize(),

View file

@ -189,6 +189,7 @@ public:
*/ */
Uint32 m_tableId; Uint32 m_tableId;
Uint32 m_table_ptrI; Uint32 m_table_ptrI;
Uint32 m_current_sync_ptrI;
}; };
typedef Ptr<Subscription> SubscriptionPtr; typedef Ptr<Subscription> SubscriptionPtr;
@ -239,7 +240,8 @@ public:
suma.progError(line, cause, extra); suma.progError(line, cause, extra);
} }
union { Uint32 nextPool; Uint32 nextList; Uint32 prevList; Uint32 ptrI; }; Uint32 prevList; Uint32 ptrI;
union { Uint32 nextPool; Uint32 nextList; };
}; };
friend struct SyncRecord; friend struct SyncRecord;

View file

@ -1117,7 +1117,7 @@ NdbEventBuffer::nextEvent()
m_available_data.remove_first(); m_available_data.remove_first();
// add it to used list // add it to used list
m_used_data.append(data); m_used_data.append_used_data(data);
#ifdef VM_TRACE #ifdef VM_TRACE
op->m_data_done_count++; op->m_data_done_count++;
@ -1144,6 +1144,10 @@ NdbEventBuffer::nextEvent()
(void)tBlob->atNextEvent(); (void)tBlob->atNextEvent();
tBlob = tBlob->theNext; tBlob = tBlob->theNext;
} }
EventBufData_list::Gci_ops *gci_ops = m_available_data.first_gci_ops();
while (gci_ops && op->getGCI() > gci_ops->m_gci)
gci_ops = m_available_data.next_gci_ops();
assert(gci_ops && (op->getGCI() == gci_ops->m_gci));
DBUG_RETURN_EVENT(op->m_facade); DBUG_RETURN_EVENT(op->m_facade);
} }
// the next event belonged to an event op that is no // the next event belonged to an event op that is no
@ -1158,15 +1162,21 @@ NdbEventBuffer::nextEvent()
#ifdef VM_TRACE #ifdef VM_TRACE
m_latest_command= m_latest_command_save; m_latest_command= m_latest_command_save;
#endif #endif
// free all "per gci unique" collected operations
EventBufData_list::Gci_ops *gci_ops = m_available_data.first_gci_ops();
while (gci_ops)
gci_ops = m_available_data.next_gci_ops();
DBUG_RETURN_EVENT(0); DBUG_RETURN_EVENT(0);
} }
NdbEventOperationImpl* NdbEventOperationImpl*
NdbEventBuffer::getGCIEventOperations(Uint32* iter, Uint32* event_types) NdbEventBuffer::getGCIEventOperations(Uint32* iter, Uint32* event_types)
{ {
if (*iter < m_available_data.m_gci_op_count) EventBufData_list::Gci_ops *gci_ops = m_available_data.first_gci_ops();
if (*iter < gci_ops->m_gci_op_count)
{ {
EventBufData_list::Gci_op g = m_available_data.m_gci_op_list[(*iter)++]; EventBufData_list::Gci_op g = gci_ops->m_gci_op_list[(*iter)++];
if (event_types != NULL) if (event_types != NULL)
*event_types = g.event_types; *event_types = g.event_types;
return g.op; return g.op;
@ -1318,7 +1328,7 @@ NdbEventBuffer::execSUB_GCP_COMPLETE_REP(const SubGcpCompleteRep * const rep)
#ifdef VM_TRACE #ifdef VM_TRACE
assert(bucket->m_data.m_count); assert(bucket->m_data.m_count);
#endif #endif
m_complete_data.m_data.append(bucket->m_data); m_complete_data.m_data.append_list(&bucket->m_data, gci);
} }
reportStatus(); reportStatus();
bzero(bucket, sizeof(Gci_container)); bzero(bucket, sizeof(Gci_container));
@ -1389,7 +1399,7 @@ NdbEventBuffer::complete_outof_order_gcis()
#ifdef VM_TRACE #ifdef VM_TRACE
assert(bucket->m_data.m_count); assert(bucket->m_data.m_count);
#endif #endif
m_complete_data.m_data.append(bucket->m_data); m_complete_data.m_data.append_list(&bucket->m_data, start_gci);
#ifdef VM_TRACE #ifdef VM_TRACE
ndbout_c(" moved %lld rows -> %lld", bucket->m_data.m_count, ndbout_c(" moved %lld rows -> %lld", bucket->m_data.m_count,
m_complete_data.m_data.m_count); m_complete_data.m_data.m_count);
@ -1599,7 +1609,7 @@ NdbEventBuffer::insertDataL(NdbEventOperationImpl *op,
data->m_event_op = op; data->m_event_op = op;
if (! is_blob_event || ! is_data_event) if (! is_blob_event || ! is_data_event)
{ {
bucket->m_data.append(data); bucket->m_data.append_data(data);
} }
else else
{ {
@ -1615,7 +1625,7 @@ NdbEventBuffer::insertDataL(NdbEventOperationImpl *op,
if (ret != 0) // main event was created if (ret != 0) // main event was created
{ {
main_data->m_event_op = op->theMainOp; main_data->m_event_op = op->theMainOp;
bucket->m_data.append(main_data); bucket->m_data.append_data(main_data);
if (use_hash) if (use_hash)
{ {
main_data->m_pkhash = main_hpos.pkhash; main_data->m_pkhash = main_hpos.pkhash;
@ -2097,7 +2107,7 @@ NdbEventBuffer::move_data()
if (!m_complete_data.m_data.is_empty()) if (!m_complete_data.m_data.is_empty())
{ {
// move this list to last in m_available_data // move this list to last in m_available_data
m_available_data.append(m_complete_data.m_data); m_available_data.append_list(&m_complete_data.m_data, 0);
bzero(&m_complete_data, sizeof(m_complete_data)); bzero(&m_complete_data, sizeof(m_complete_data));
} }
@ -2160,6 +2170,19 @@ NdbEventBuffer::free_list(EventBufData_list &list)
list.m_count = list.m_sz = 0; list.m_count = list.m_sz = 0;
} }
void EventBufData_list::append_list(EventBufData_list *list, Uint64 gci)
{
move_gci_ops(list, gci);
if (m_tail)
m_tail->m_next= list->m_head;
else
m_head= list->m_head;
m_tail= list->m_tail;
m_count+= list->m_count;
m_sz+= list->m_sz;
}
void void
EventBufData_list::add_gci_op(Gci_op g) EventBufData_list::add_gci_op(Gci_op g)
{ {
@ -2188,6 +2211,44 @@ EventBufData_list::add_gci_op(Gci_op g)
} }
} }
void
EventBufData_list::move_gci_ops(EventBufData_list *list, Uint64 gci)
{
assert(!m_is_not_multi_list);
if (!list->m_is_not_multi_list)
{
assert(gci == 0);
if (m_gci_ops_list_tail)
m_gci_ops_list_tail->m_next = list->m_gci_ops_list;
else
{
m_gci_ops_list = list->m_gci_ops_list;
}
m_gci_ops_list_tail = list->m_gci_ops_list_tail;
goto end;
}
{
Gci_ops *new_gci_ops = new Gci_ops;
if (m_gci_ops_list_tail)
m_gci_ops_list_tail->m_next = new_gci_ops;
else
{
assert(m_gci_ops_list == 0);
m_gci_ops_list = new_gci_ops;
}
m_gci_ops_list_tail = new_gci_ops;
new_gci_ops->m_gci_op_list = list->m_gci_op_list;
new_gci_ops->m_gci_op_count = list->m_gci_op_count;
new_gci_ops->m_gci = gci;
new_gci_ops->m_next = 0;
}
end:
list->m_gci_op_list = 0;
list->m_gci_ops_list_tail = 0;
list->m_gci_op_alloc = 0;
}
NdbEventOperation* NdbEventOperation*
NdbEventBuffer::createEventOperation(const char* eventName, NdbEventBuffer::createEventOperation(const char* eventName,
NdbError &theError) NdbError &theError)

View file

@ -68,8 +68,12 @@ public:
~EventBufData_list(); ~EventBufData_list();
void remove_first(); void remove_first();
void append(EventBufData *data); // append data and insert data into Gci_op list with add_gci_op
void append(const EventBufData_list &list); void append_data(EventBufData *data);
// append data and insert data but ignore Gci_op list
void append_used_data(EventBufData *data);
// append list to another, will call move_gci_ops
void append_list(EventBufData_list *list, Uint64 gci);
int is_empty(); int is_empty();
@ -77,13 +81,60 @@ public:
unsigned m_count; unsigned m_count;
unsigned m_sz; unsigned m_sz;
// distinct ops per gci (assume no hash needed) /*
struct Gci_op { NdbEventOperationImpl* op; Uint32 event_types; }; distinct ops per gci (assume no hash needed)
Gci_op* m_gci_op_list;
Uint32 m_gci_op_count; list may be in 2 versions
Uint32 m_gci_op_alloc;
1. single list with on gci only
- one linear array
Gci_op *m_gci_op_list;
Uint32 m_gci_op_count;
Uint32 m_gci_op_alloc != 0;
2. multi list with several gcis
- linked list of gci's
- one linear array per gci
Gci_ops *m_gci_ops_list;
Gci_ops *m_gci_ops_list_tail;
Uint32 m_is_not_multi_list == 0;
*/
struct Gci_op // 1 + 2
{
NdbEventOperationImpl* op;
Uint32 event_types;
};
struct Gci_ops // 2
{
Uint64 m_gci;
Gci_op *m_gci_op_list;
Gci_ops *m_next;
Uint32 m_gci_op_count;
};
union
{
Gci_op *m_gci_op_list; // 1
Gci_ops *m_gci_ops_list; // 2
};
union
{
Uint32 m_gci_op_count; // 1
Gci_ops *m_gci_ops_list_tail;// 2
};
union
{
Uint32 m_gci_op_alloc; // 1
Uint32 m_is_not_multi_list; // 2
};
Gci_ops *first_gci_ops();
Gci_ops *next_gci_ops();
private: private:
// case 1 above; add Gci_op to single list
void add_gci_op(Gci_op g); void add_gci_op(Gci_op g);
// case 2 above; move single list or multi list from
// one list to another
void move_gci_ops(EventBufData_list *list, Uint64 gci);
}; };
inline inline
@ -92,7 +143,7 @@ EventBufData_list::EventBufData_list()
m_count(0), m_count(0),
m_sz(0), m_sz(0),
m_gci_op_list(NULL), m_gci_op_list(NULL),
m_gci_op_count(0), m_gci_ops_list_tail(0),
m_gci_op_alloc(0) m_gci_op_alloc(0)
{ {
} }
@ -100,7 +151,14 @@ EventBufData_list::EventBufData_list()
inline inline
EventBufData_list::~EventBufData_list() EventBufData_list::~EventBufData_list()
{ {
delete [] m_gci_op_list; if (m_is_not_multi_list)
delete [] m_gci_op_list;
else
{
Gci_ops *op = first_gci_ops();
while (op)
op = next_gci_ops();
}
} }
inline inline
@ -120,11 +178,8 @@ void EventBufData_list::remove_first()
} }
inline inline
void EventBufData_list::append(EventBufData *data) void EventBufData_list::append_used_data(EventBufData *data)
{ {
Gci_op g = { data->m_event_op, 1 << (Uint32)data->sdata->operation };
add_gci_op(g);
data->m_next= 0; data->m_next= 0;
if (m_tail) if (m_tail)
m_tail->m_next= data; m_tail->m_next= data;
@ -143,19 +198,33 @@ void EventBufData_list::append(EventBufData *data)
} }
inline inline
void EventBufData_list::append(const EventBufData_list &list) void EventBufData_list::append_data(EventBufData *data)
{ {
Uint32 i; Gci_op g = { data->m_event_op, 1 << (Uint32)data->sdata->operation };
for (i = 0; i < list.m_gci_op_count; i++) add_gci_op(g);
add_gci_op(list.m_gci_op_list[i]);
if (m_tail) append_used_data(data);
m_tail->m_next= list.m_head; }
else
m_head= list.m_head; inline EventBufData_list::Gci_ops *
m_tail= list.m_tail; EventBufData_list::first_gci_ops()
m_count+= list.m_count; {
m_sz+= list.m_sz; assert(!m_is_not_multi_list);
return m_gci_ops_list;
}
inline EventBufData_list::Gci_ops *
EventBufData_list::next_gci_ops()
{
assert(!m_is_not_multi_list);
Gci_ops *first = m_gci_ops_list;
m_gci_ops_list = first->m_next;
if (first->m_gci_op_list)
delete [] first->m_gci_op_list;
delete first;
if (m_gci_ops_list == 0)
m_gci_ops_list_tail = 0;
return m_gci_ops_list;
} }
// GCI bucket has also a hash over data, with key event op, table PK. // GCI bucket has also a hash over data, with key event op, table PK.

View file

@ -577,7 +577,7 @@ ErrorBundle ErrorCodes[] = {
{ 4248, DMEC, AE, "Trigger/index name invalid" }, { 4248, DMEC, AE, "Trigger/index name invalid" },
{ 4249, DMEC, AE, "Invalid table" }, { 4249, DMEC, AE, "Invalid table" },
{ 4250, DMEC, AE, "Invalid index type or index logging option" }, { 4250, DMEC, AE, "Invalid index type or index logging option" },
{ 4251, DMEC, AE, "Cannot create unique index, duplicate keys found" }, { 4251, HA_ERR_FOUND_DUPP_UNIQUE, AE, "Cannot create unique index, duplicate keys found" },
{ 4252, DMEC, AE, "Failed to allocate space for index" }, { 4252, DMEC, AE, "Failed to allocate space for index" },
{ 4253, DMEC, AE, "Failed to create index table" }, { 4253, DMEC, AE, "Failed to create index table" },
{ 4254, DMEC, AE, "Table not an index table" }, { 4254, DMEC, AE, "Table not an index table" },