summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2009-12-08 17:13:12 +0300
committerKonstantin Osipov <kostja@sun.com>2009-12-08 17:13:12 +0300
commit302352723e8fbf69b9d02604c84a79fa56e69b7b (patch)
treea89672143d8c1f4bec0ae0ba85c2a1f992845d5d /sql/sql_yacc.yy
parent97d2a9233bea5937f136ecc513fcbb28481b9289 (diff)
downloadmariadb-git-302352723e8fbf69b9d02604c84a79fa56e69b7b.tar.gz
Backport of:
---------------------------------------------------------- revno: 2617.69.24 committer: Konstantin Osipov <kostja@sun.com> branch nick: 5.4-42546 timestamp: Fri 2009-08-14 19:22:05 +0400 message: A pre-requisite for a fix for Bug#42546 "Backup: RESTORE fails, thinking it finds an existing table" Back-port from WL 148 "Foreign keys" feature tree a patch that introduced Prelocking_strategy class -- a way to parameterize open_tables() behaviour, implemented by Dmitry Lenev. (Part of WL#4284). sql/sql_base.cc: Implement different prelocking strategies. Use an instance of prelocking_strategy in open_tables(). sql/sql_class.h: Add declarations for class Prelocking_strategy. sql/sql_lex.h: Add a helper method to access last table of the global table list (lex->query_tables). sql/sql_parse.cc: Use a special prelocking strategy when locking tables for LOCK TABLES. sql/sql_table.cc: Use normal open_and_lock_tables_derived() in ALTER TABLE. sql/sql_yacc.yy: Modify the grammar to not pollute the global table list with tables that should not be opened.
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy66
1 files changed, 50 insertions, 16 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 24800f805d0..577c60b4c10 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1766,6 +1766,7 @@ create:
lex->create_info.default_table_charset= NULL;
lex->name.str= 0;
lex->name.length= 0;
+ lex->create_last_non_select_table= lex->last_table();
}
create2
{
@@ -1788,7 +1789,8 @@ create:
lex->sql_command= SQLCOM_CREATE_INDEX;
if (!lex->current_select->add_table_to_list(lex->thd, $7,
NULL,
- TL_OPTION_UPDATING))
+ TL_OPTION_UPDATING,
+ TL_WRITE_ALLOW_READ))
MYSQL_YYABORT;
lex->alter_info.reset();
lex->alter_info.flags= ALTER_ADD_INDEX;
@@ -3952,7 +3954,7 @@ create2:
;
create2a:
- field_list ')' opt_create_table_options
+ create_field_list ')' opt_create_table_options
opt_partitioning
create3 {}
| opt_partitioning
@@ -4802,19 +4804,30 @@ create_table_option:
Lex->create_info.row_type= $3;
Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT;
}
- | UNION_SYM opt_equal '(' opt_table_list ')'
+ | UNION_SYM opt_equal
+ {
+ Lex->select_lex.table_list.save_and_clear(&Lex->save_list);
+ }
+ '(' opt_table_list ')'
{
- /* Move the union list to the merge_list */
+ /*
+ Move the union list to the merge_list and exclude its tables
+ from the global list.
+ */
LEX *lex=Lex;
- TABLE_LIST *table_list= lex->select_lex.get_table_list();
lex->create_info.merge_list= lex->select_lex.table_list;
- lex->create_info.merge_list.elements--;
- lex->create_info.merge_list.first=
- (uchar*) (table_list->next_local);
- lex->select_lex.table_list.elements=1;
- lex->select_lex.table_list.next=
- (uchar**) &(table_list->next_local);
- table_list->next_local= 0;
+ lex->select_lex.table_list= lex->save_list;
+ /*
+ When excluding union list from the global list we assume that
+ elements of the former immediately follow elements which represent
+ table being created/altered and parent tables.
+ */
+ TABLE_LIST *last_non_sel_table= lex->create_last_non_select_table;
+ DBUG_ASSERT(last_non_sel_table->next_global ==
+ (TABLE_LIST *)lex->create_info.merge_list.first);
+ last_non_sel_table->next_global= 0;
+ Lex->query_tables_last= &last_non_sel_table->next_global;
+
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
}
| default_charset
@@ -4952,6 +4965,14 @@ udf_type:
| INT_SYM {$$ = (int) INT_RESULT; }
;
+
+create_field_list:
+ field_list
+ {
+ Lex->create_last_non_select_table= Lex->last_table();
+ }
+ ;
+
field_list:
field_list_item
| field_list ',' field_list_item
@@ -5743,7 +5764,8 @@ alter:
lex->sql_command= SQLCOM_ALTER_TABLE;
lex->duplicates= DUP_ERROR;
if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
- TL_OPTION_UPDATING))
+ TL_OPTION_UPDATING,
+ TL_WRITE_ALLOW_READ))
MYSQL_YYABORT;
lex->col_list.empty();
lex->select_lex.init_order();
@@ -5756,6 +5778,7 @@ alter:
lex->alter_info.reset();
lex->no_write_to_binlog= 0;
lex->create_info.storage_media= HA_SM_DEFAULT;
+ lex->create_last_non_select_table= lex->last_table();
}
alter_commands
{}
@@ -6139,12 +6162,16 @@ add_column:
;
alter_list_item:
- add_column column_def opt_place { }
+ add_column column_def opt_place
+ {
+ Lex->create_last_non_select_table= Lex->last_table();
+ }
| ADD key_def
{
+ Lex->create_last_non_select_table= Lex->last_table();
Lex->alter_info.flags|= ALTER_ADD_INDEX;
}
- | add_column '(' field_list ')'
+ | add_column '(' create_field_list ')'
{
Lex->alter_info.flags|= ALTER_ADD_COLUMN | ALTER_ADD_INDEX;
}
@@ -6155,6 +6182,9 @@ alter_list_item:
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
}
field_spec opt_place
+ {
+ Lex->create_last_non_select_table= Lex->last_table();
+ }
| MODIFY_SYM opt_column field_ident
{
LEX *lex=Lex;
@@ -6177,6 +6207,9 @@ alter_list_item:
MYSQL_YYABORT;
}
opt_place
+ {
+ Lex->create_last_non_select_table= Lex->last_table();
+ }
| DROP opt_column field_ident opt_restrict
{
LEX *lex=Lex;
@@ -9607,7 +9640,8 @@ drop:
lex->alter_info.flags= ALTER_DROP_INDEX;
lex->alter_info.drop_list.push_back(ad);
if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
- TL_OPTION_UPDATING))
+ TL_OPTION_UPDATING,
+ TL_WRITE_ALLOW_READ))
MYSQL_YYABORT;
}
| DROP DATABASE if_exists ident