summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/lock.cc6
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_class.h11
-rw-r--r--sql/sql_lex.cc35
-rw-r--r--sql/sql_lex.h7
-rw-r--r--sql/sql_yacc.yy7
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;
}
;