diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/lock.cc | 6 | ||||
-rw-r--r-- | sql/sql_class.cc | 4 | ||||
-rw-r--r-- | sql/sql_class.h | 11 | ||||
-rw-r--r-- | sql/sql_lex.cc | 35 | ||||
-rw-r--r-- | sql/sql_lex.h | 7 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 7 |
6 files changed, 59 insertions, 11 deletions
diff --git a/sql/lock.cc b/sql/lock.cc index ebe6f325e65..3df1eb0f516 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -148,11 +148,11 @@ lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags) } } + if (t->s->table_category == TABLE_CATEGORY_SYSTEM) + system_count++; + if (t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE) { - if (t->s->table_category == TABLE_CATEGORY_SYSTEM) - system_count++; - if (t->db_stat & HA_READ_ONLY) { my_error(ER_OPEN_AS_READONLY, MYF(0), t->alias.c_ptr_safe()); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 3ff2e2c10ca..f3f6d10b706 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -195,18 +195,20 @@ Foreign_key::Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root) constraint_name(rhs.constraint_name), ref_db(rhs.ref_db), ref_table(rhs.ref_table), + ref_table_list(rhs.ref_table_list), ref_columns(rhs.ref_columns,mem_root), fk_options(rhs.fk_options) { list_copy_and_replace_each_value(ref_columns, mem_root); } - void Foreign_key::init(const LEX_CSTRING& _ref_db, const LEX_CSTRING& _ref_table, + TABLE_LIST *_ref_table_list, st_fk_options _fk_options) { ref_db= _ref_db; ref_table= _ref_table; + ref_table_list= _ref_table_list; if (ref_columns.is_empty()) { ref_columns= columns; diff --git a/sql/sql_class.h b/sql/sql_class.h index 1979e85c31c..57e464c4d67 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -705,6 +705,7 @@ public: LEX_CSTRING constraint_name; LEX_CSTRING ref_db; LEX_CSTRING ref_table; + TABLE_LIST *ref_table_list; List<Key_part_spec> ref_columns; st_fk_options fk_options; Foreign_key(const LEX_CSTRING *name_arg, @@ -744,7 +745,7 @@ public: return !foreign; } void init(const LEX_CSTRING& _ref_db, const LEX_CSTRING& _ref_table, - st_fk_options _fk_options); + TABLE_LIST *_ref_table_list, st_fk_options _fk_options); Foreign_key(const Foreign_key &rhs, MEM_ROOT *mem_root); /** Used to make a clone of this object for ALTER/CREATE TABLE @@ -1658,8 +1659,8 @@ public: class Server_side_cursor; /* - Struct to catch changes in column metadata that is sent to client. - in the "result set metadata". Used to support + Struct to catch changes in column metadata that is sent to client. + in the "result set metadata". Used to support MARIADB_CLIENT_CACHE_METADATA. */ struct send_column_info_state @@ -1672,7 +1673,7 @@ struct send_column_info_state /* Column info can only be changed by PreparedStatement::reprepare() - + There is a class of "weird" prepared statements like SELECT ? or SELECT @a that are not immutable, and depend on input parameters or user variables */ @@ -1779,7 +1780,7 @@ public: LEX_CSTRING db; send_column_info_state column_info_state; - + /* This is set to 1 of last call to send_result_to_client() was ok */ my_bool query_cache_is_applicable; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 4081a4e0c3c..2415e0287e5 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -11447,6 +11447,41 @@ bool LEX::add_column_foreign_key(const LEX_CSTRING &field_name, return false; } +bool LEX::init_last_foreign_key(Table_ident *ref_table_name) +{ + if (ref_table_name->db.str == NULL) + ref_table_name->db= query_tables->db; + + Table_ident lookup_ref_name(ref_table_name->db, ref_table_name->table); + if (lower_case_table_names) + lookup_ref_name.lowercase(thd->mem_root); + + if (ref_table_name->db.str == NULL) + copy_db_to(&ref_table_name->db); + TABLE_LIST *ref_table= find_table_in_list(query_tables, + &TABLE_LIST::next_global, + &lookup_ref_name.db, + &lookup_ref_name.table); + + if (ref_table == NULL && + !(thd->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)) + { + ref_table= (TABLE_LIST *) thd->alloc(sizeof(TABLE_LIST)); + if (unlikely(ref_table == NULL)) + return true; + ref_table->init_one_table_for_prelocking(&lookup_ref_name.db, + &lookup_ref_name.table, + NULL, TL_READ, + TABLE_LIST::PRELOCK_NONE, + 0, 0, + &query_tables_last, + false); + } + last_foreign_key->init(ref_table_name->db, ref_table_name->table, ref_table, + fk_options); + return false; +} + bool LEX::stmt_grant_table(THD *thd, Grant_privilege *grant, diff --git a/sql/sql_lex.h b/sql/sql_lex.h index d16af3fb51a..aedc7c5a66a 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -4709,6 +4709,7 @@ public: bool add_column_foreign_key(const LEX_CSTRING &name, const LEX_CSTRING &constraint_name, DDL_options ddl_options); + bool init_last_foreign_key(Table_ident *ref_table_name); }; @@ -5046,6 +5047,12 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead, bool need_set_keyword= true); void mark_or_conds_to_avoid_pushdown(Item *cond); +TABLE_LIST *find_table_in_list(TABLE_LIST *table, + TABLE_LIST *TABLE_LIST::*link, + const LEX_CSTRING *db_name, + const LEX_CSTRING *table_name); +int add_foreign_key_to_list(LEX *lex, LEX_CSTRING *name, Table_ident *table_name, + DDL_options ddl_options); #endif /* MYSQL_SERVER */ #endif /* SQL_LEX_INCLUDED */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 06875a38dc5..b6e34234217 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5858,7 +5858,9 @@ column_def: } references { - Lex->last_foreign_key->init($4->db, $4->table, Lex->fk_options); + + if (unlikely(Lex->init_last_foreign_key($4))) + MYSQL_YYABORT; $$= $1; } ; @@ -5921,7 +5923,8 @@ key_def: } '(' key_list ')' references { - Lex->last_foreign_key->init($10->db, $10->table, Lex->fk_options); + if (unlikely(Lex->init_last_foreign_key($10))) + MYSQL_YYABORT; } ; |