summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
authorunknown <Li-Bing.Song@sun.com>2010-08-18 12:56:06 +0800
committerunknown <Li-Bing.Song@sun.com>2010-08-18 12:56:06 +0800
commit9d6811502ed22f7b4aa99e2be1d5c8ac45792790 (patch)
tree16b28895d7863e7a43e3bb20dc77422d067a6626 /sql/sql_yacc.yy
parent790852c0c91df8bf104687753c019ceefaed6622 (diff)
downloadmariadb-git-9d6811502ed22f7b4aa99e2be1d5c8ac45792790.tar.gz
WL#5370 Keep forward-compatibility when changing
'CREATE TABLE IF NOT EXISTS ... SELECT' behaviour BUG#55474, BUG#55499, BUG#55598, BUG#55616 and BUG#55777 are fixed in this patch too. This is the 5.1 part. It implements: - if the table exists, binlog two events: CREATE TABLE IF NOT EXISTS and INSERT ... SELECT - Insert nothing and binlog nothing on master if the existing object is a view. It only generates a warning that table already exists. mysql-test/r/trigger.result: Ather this patch, 'CREATE TABLE IF NOT EXISTS ... SELECT' will not insert anything if the creating table already exists and is a view. sql/sql_class.h: Declare virtual function write_to_binlog() for select_insert. It's used to binlog 'create select' sql/sql_insert.cc: Implement write_to_binlog(); Use write_to_binlog() instead of binlog_query() to binlog the statement. if the table exists, binlog two events: CREATE TABLE IF NOT EXISTS and INSERT ... SELECT sql/sql_lex.h: Declare create_select_start_with_brace and create_select_pos. They are helpful for binlogging 'create select' sql/sql_parse.cc: Do nothing on master if the existing object is a view. sql/sql_yacc.yy: Record the relative postion of 'SELECT' in the 'CREATE ...SELECT' statement. Record whether there is a '(' before the 'SELECT' clause.
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy28
1 files changed, 25 insertions, 3 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 5a3ad0b3eba..ed367582ba5 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -3881,17 +3881,26 @@ create2a:
create3 {}
| opt_partitioning
create_select ')'
- { Select->set_braces(1);}
+ {
+ Select->set_braces(1);
+ Lex->create_select_start_with_brace= TRUE;
+ }
union_opt {}
;
create3:
/* empty */ {}
| opt_duplicate opt_as create_select
- { Select->set_braces(0);}
+ {
+ Select->set_braces(0);
+ Lex->create_select_start_with_brace= FALSE;
+ }
union_clause {}
| opt_duplicate opt_as '(' create_select ')'
- { Select->set_braces(1);}
+ {
+ Select->set_braces(1);
+ Lex->create_select_start_with_brace= TRUE;
+ }
union_opt {}
;
@@ -4516,6 +4525,19 @@ create_select:
lex->current_select->table_list.save_and_clear(&lex->save_list);
mysql_init_select(lex);
lex->current_select->parsing_place= SELECT_LIST;
+
+ if (lex->sql_command == SQLCOM_CREATE_TABLE &&
+ (lex->create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS))
+ {
+ Lex_input_stream *lip= YYLIP;
+
+ if (lex->spcont)
+ lex->create_select_pos= lip->get_tok_start() -
+ lex->sphead->m_tmp_query;
+ else
+ lex->create_select_pos= lip->get_tok_start() - lip->get_buf();
+ lex->create_select_in_comment= (lip->in_comment == DISCARD_COMMENT);
+ }
}
select_options select_item_list
{