Commit fb631aa4 authored by tomas@poseidon.ndb.mysql.com's avatar tomas@poseidon.ndb.mysql.com

Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.1-new

into  poseidon.ndb.mysql.com:/home/tomas/mysql-5.1-new
parents 139af836 34a74d65
......@@ -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_replace_into= 0,
opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
opt_events= 0,
opt_alltspcs=0;
static ulong opt_max_allowed_packet, opt_net_buffer_length;
static MYSQL mysql_connection,*sock=0;
......@@ -232,6 +233,9 @@ static struct my_option my_long_options[] =
{"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,
(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',
"Allows utilization of the new, much faster INSERT syntax.",
(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);
}
/*
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
-- 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).
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)
{
char query_buff[512];
char query_buff[QUERY_LENGTH];
const char *routine_type[]= {"FUNCTION", "PROCEDURE"};
char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
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)))
{
routine_name= quote_name(routine_list_row[1], name_buff, 0);
DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type[i],
name_buff));
routine_name= quote_name(routine_list_row[1], name_buff, 0);
my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s",
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;
const char *insert_option;
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;
int len;
MYSQL_RES *result;
......@@ -1886,7 +2017,7 @@ static void dump_triggers_for_table (char *table, char *db)
{
char *result_table;
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;
FILE *sql_file = md_result_file;
MYSQL_RES *result;
......@@ -2546,7 +2677,6 @@ static int dump_all_tablespaces()
{
MYSQL_ROW row;
MYSQL_RES *tableres;
int result=0;
char buf[FN_REFLEN];
int first;
......@@ -2844,6 +2974,12 @@ static int dump_all_tables_in_db(char *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 &&
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);
}
}
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) */
if (opt_routines && !opt_xml &&
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 t2;
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;
......@@ -1166,3 +1166,43 @@ drop table t1;
drop table t2;
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;
#####
......@@ -14,13 +14,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_LEX 1
#include "event_priv.h"
#include "event.h"
#include "sp.h"
extern int yyparse(void *thd);
extern int MYSQLparse(void *thd);
/*
Init all member variables
......@@ -1063,8 +1064,6 @@ Event_timed::get_create_event(THD *thd, String *buf)
DBUG_RETURN(EVEX_MICROSECOND_UNSUP);
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);
buf->append(STRING_WITH_LEN(" ON SCHEDULE "));
......@@ -1338,7 +1337,7 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root)
thd->lex= &lex;
lex_start(thd, (uchar*)thd->query, thd->query_length);
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",
thd->is_fatal_error));
......
......@@ -1223,7 +1223,7 @@ File open_binlog(IO_CACHE *log, const char *log_file_name,
const char **errmsg);
/* mysqld.cc */
extern void yyerror(const char*);
extern void MYSQLerror(const char*);
/* item_func.cc */
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);
/* sql_yacc.cc */
extern int yyparse(void *thd);
extern int MYSQLparse(void *thd);
/* frm_crypt.cc */
#ifdef HAVE_CRYPTED_FRM
......
......@@ -1620,7 +1620,7 @@ static void network_init(void)
#endif /*!EMBEDDED_LIBRARY*/
void yyerror(const char *s)
void MYSQLerror(const char *s)
{
THD *thd=current_thd;
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
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;
const char *params, *returns, *body;
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());
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;
......
......@@ -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_OPERATOR_OR_IDENT Last state was an ident, text or 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;
int tokval, result_state;
......
......@@ -757,7 +757,7 @@ typedef struct st_lex
const uchar *buf; /* The beginning of string, used by SPs */
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;
char *length,*dec,*change,*name;
......@@ -1119,7 +1119,7 @@ extern void lex_init(void);
extern void lex_free(void);
extern void lex_start(THD *thd, const uchar *buf, uint length);
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);
......
......@@ -4379,7 +4379,7 @@ end_with_restore_list:
/*
We must cleanup the unit and the lex here because
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.
*/
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_func_cache);
if (!yyparse((void *)thd) && ! thd->is_fatal_error)
if (!MYSQLparse((void *)thd) && ! thd->is_fatal_error)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
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");
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))
error= 1; /* Ignore question */
thd->end_statement();
......
......@@ -33,6 +33,7 @@
/* Some general useful functions */
#define MYSQL_LEX 1
#include "mysql_priv.h"
#include <errno.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.
*/
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)
{
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_len= part_state_len;
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);
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->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);
lex->safe_to_cache_query= FALSE;
/*
......
......@@ -15,6 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#define MYSQL_LEX 1
#include "mysql_priv.h"
#include "sp_head.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);
thd->spcont= 0;
if (yyparse((void *)thd) || thd->is_fatal_error)
if (MYSQLparse((void *)thd) || thd->is_fatal_error)
{
/*
Free lex associated resources.
......
......@@ -15,6 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define MYSQL_LEX 1
#include "mysql_priv.h"
#include "sql_select.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);
CHARSET_INFO *save_cs= thd->variables.character_set_client;
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.sql_mode= save_mode;
}
......
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