mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 14:54:20 +01:00
Merge bk-internal:/home/bk/mysql-5.1-new
into neptunus.(none):/home/msvensson/mysql/mysql-5.1
This commit is contained in:
commit
888f96769e
26 changed files with 464 additions and 78 deletions
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
#####
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
|
||||||
|
list may be in 2 versions
|
||||||
|
|
||||||
|
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_count;
|
||||||
Uint32 m_gci_op_alloc;
|
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()
|
||||||
{
|
{
|
||||||
|
if (m_is_not_multi_list)
|
||||||
delete [] m_gci_op_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.
|
||||||
|
|
|
@ -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" },
|
||||||
|
|
Loading…
Add table
Reference in a new issue