mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
Merge branch '10.1' into 10.2
This commit is contained in:
168
sql/sql_base.cc
168
sql/sql_base.cc
@ -1,5 +1,5 @@
|
||||
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
|
||||
Copyright (c) 2010, 2015, MariaDB
|
||||
Copyright (c) 2010, 2016, MariaDB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -168,11 +168,6 @@ static bool check_and_update_table_version(THD *thd, TABLE_LIST *tables,
|
||||
TABLE_SHARE *table_share);
|
||||
static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share, TABLE *entry);
|
||||
static bool auto_repair_table(THD *thd, TABLE_LIST *table_list);
|
||||
static bool
|
||||
has_write_table_with_auto_increment(TABLE_LIST *tables);
|
||||
static bool
|
||||
has_write_table_with_auto_increment_and_select(TABLE_LIST *tables);
|
||||
static bool has_write_table_auto_increment_not_first_in_pk(TABLE_LIST *tables);
|
||||
|
||||
|
||||
/**
|
||||
@ -2295,6 +2290,16 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
|
||||
*/
|
||||
if (dd_frm_is_view(thd, path))
|
||||
{
|
||||
/*
|
||||
If parent_l of the table_list is non null then a merge table
|
||||
has this view as child table, which is not supported.
|
||||
*/
|
||||
if (table_list->parent_l)
|
||||
{
|
||||
my_error(ER_WRONG_MRG_TABLE, MYF(0));
|
||||
DBUG_RETURN(true);
|
||||
}
|
||||
|
||||
if (!tdc_open_view(thd, table_list, alias, key, key_length,
|
||||
CHECK_METADATA_VERSION))
|
||||
{
|
||||
@ -5417,65 +5422,6 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint count,
|
||||
*(ptr++)= table->table;
|
||||
}
|
||||
|
||||
/*
|
||||
DML statements that modify a table with an auto_increment column based on
|
||||
rows selected from a table are unsafe as the order in which the rows are
|
||||
fetched fron the select tables cannot be determined and may differ on
|
||||
master and slave.
|
||||
*/
|
||||
if (thd->variables.binlog_format != BINLOG_FORMAT_ROW && tables &&
|
||||
has_write_table_with_auto_increment_and_select(tables))
|
||||
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT);
|
||||
/* Todo: merge all has_write_table_auto_inc with decide_logging_format */
|
||||
if (thd->variables.binlog_format != BINLOG_FORMAT_ROW && tables)
|
||||
{
|
||||
if (has_write_table_auto_increment_not_first_in_pk(tables))
|
||||
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST);
|
||||
}
|
||||
|
||||
#ifdef NOT_USED_IN_MARIADB
|
||||
/*
|
||||
INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys
|
||||
can be unsafe.
|
||||
*/
|
||||
uint unique_keys= 0;
|
||||
for (TABLE_LIST *query_table= tables; query_table && unique_keys <= 1;
|
||||
query_table= query_table->next_global)
|
||||
if(query_table->table)
|
||||
{
|
||||
uint keys= query_table->table->s->keys, i= 0;
|
||||
unique_keys= 0;
|
||||
for (KEY* keyinfo= query_table->table->s->key_info;
|
||||
i < keys && unique_keys <= 1; i++, keyinfo++)
|
||||
{
|
||||
if (keyinfo->flags & HA_NOSAME)
|
||||
unique_keys++;
|
||||
}
|
||||
if (!query_table->placeholder() &&
|
||||
query_table->lock_type >= TL_WRITE_ALLOW_WRITE &&
|
||||
unique_keys > 1 && thd->lex->sql_command == SQLCOM_INSERT &&
|
||||
/* Duplicate key update is not supported by INSERT DELAYED */
|
||||
thd->get_command() != COM_DELAYED_INSERT &&
|
||||
thd->lex->duplicates == DUP_UPDATE)
|
||||
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We have to emulate LOCK TABLES if we are statement needs prelocking. */
|
||||
if (thd->lex->requires_prelocking())
|
||||
{
|
||||
|
||||
/*
|
||||
A query that modifies autoinc column in sub-statement can make the
|
||||
master and slave inconsistent.
|
||||
We can solve these problems in mixed mode by switching to binlogging
|
||||
if at least one updated table is used by sub-statement
|
||||
*/
|
||||
if (thd->wsrep_binlog_format() != BINLOG_FORMAT_ROW && tables &&
|
||||
has_write_table_with_auto_increment(thd->lex->first_not_own_table()))
|
||||
thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS);
|
||||
}
|
||||
|
||||
DEBUG_SYNC(thd, "before_lock_tables_takes_lock");
|
||||
|
||||
if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start),
|
||||
@ -9270,98 +9216,6 @@ bool is_equal(const LEX_STRING *a, const LEX_STRING *b)
|
||||
return a->length == b->length && !strncmp(a->str, b->str, a->length);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Tells if two (or more) tables have auto_increment columns and we want to
|
||||
lock those tables with a write lock.
|
||||
|
||||
SYNOPSIS
|
||||
has_two_write_locked_tables_with_auto_increment
|
||||
tables Table list
|
||||
|
||||
NOTES:
|
||||
Call this function only when you have established the list of all tables
|
||||
which you'll want to update (including stored functions, triggers, views
|
||||
inside your statement).
|
||||
*/
|
||||
|
||||
static bool
|
||||
has_write_table_with_auto_increment(TABLE_LIST *tables)
|
||||
{
|
||||
for (TABLE_LIST *table= tables; table; table= table->next_global)
|
||||
{
|
||||
/* we must do preliminary checks as table->table may be NULL */
|
||||
if (!table->placeholder() &&
|
||||
table->table->found_next_number_field &&
|
||||
(table->lock_type >= TL_WRITE_ALLOW_WRITE))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
checks if we have select tables in the table list and write tables
|
||||
with auto-increment column.
|
||||
|
||||
SYNOPSIS
|
||||
has_two_write_locked_tables_with_auto_increment_and_select
|
||||
tables Table list
|
||||
|
||||
RETURN VALUES
|
||||
|
||||
-true if the table list has atleast one table with auto-increment column
|
||||
|
||||
|
||||
and atleast one table to select from.
|
||||
-false otherwise
|
||||
*/
|
||||
|
||||
static bool
|
||||
has_write_table_with_auto_increment_and_select(TABLE_LIST *tables)
|
||||
{
|
||||
bool has_select= false;
|
||||
bool has_auto_increment_tables = has_write_table_with_auto_increment(tables);
|
||||
for(TABLE_LIST *table= tables; table; table= table->next_global)
|
||||
{
|
||||
if (!table->placeholder() &&
|
||||
(table->lock_type <= TL_READ_NO_INSERT))
|
||||
{
|
||||
has_select= true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(has_select && has_auto_increment_tables);
|
||||
}
|
||||
|
||||
/*
|
||||
Tells if there is a table whose auto_increment column is a part
|
||||
of a compound primary key while is not the first column in
|
||||
the table definition.
|
||||
|
||||
@param tables Table list
|
||||
|
||||
@return true if the table exists, fais if does not.
|
||||
*/
|
||||
|
||||
static bool
|
||||
has_write_table_auto_increment_not_first_in_pk(TABLE_LIST *tables)
|
||||
{
|
||||
for (TABLE_LIST *table= tables; table; table= table->next_global)
|
||||
{
|
||||
/* we must do preliminary checks as table->table may be NULL */
|
||||
if (!table->placeholder() &&
|
||||
table->table->found_next_number_field &&
|
||||
(table->lock_type >= TL_WRITE_ALLOW_WRITE)
|
||||
&& table->table->s->next_number_keypart != 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Open and lock system tables for read.
|
||||
|
||||
|
Reference in New Issue
Block a user