summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-04-24 09:39:45 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-04-24 09:39:45 +0300
commit4cd7979c56130194cc3742e1037998d11f98c047 (patch)
tree70131981da1d874d68b9e8cc8e7bf293e405907e /sql
parent619dc2b24f26aea29345dc3f3289bed406738025 (diff)
parent9c34a4124d67d9e3f70837eaeb11290f35e8f8d0 (diff)
downloadmariadb-git-4cd7979c56130194cc3742e1037998d11f98c047.tar.gz
Merge 10.1 into 10.2
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.cc13
-rw-r--r--sql/handler.h2
-rw-r--r--sql/item_func.h1
-rw-r--r--sql/item_strfunc.h1
-rw-r--r--sql/log_event.cc119
-rw-r--r--sql/log_event_old.cc10
-rw-r--r--sql/opt_subselect.cc1
-rw-r--r--sql/sp.cc6
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_admin.cc4
-rw-r--r--sql/sql_base.cc26
-rw-r--r--sql/sql_base.h2
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_partition.cc6
-rw-r--r--sql/sql_partition_admin.cc2
-rw-r--r--sql/sql_plugin.cc14
-rw-r--r--sql/sql_priv.h4
-rw-r--r--sql/sql_statistics.cc2
-rw-r--r--sql/sql_table.cc10
-rw-r--r--sql/sql_trigger.cc3
-rw-r--r--sql/sql_truncate.cc5
-rw-r--r--sql/table.cc19
-rw-r--r--sql/table.h10
23 files changed, 206 insertions, 58 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 8093c17135b..cd2ad06bb70 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -4284,18 +4284,6 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table,
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
}
-
-/*
- Default implementation to support in-place alter table
- and old online add/drop index API
-*/
-
-void handler::notify_table_changed()
-{
- ha_create_partitioning_metadata(table->s->path.str, NULL, CHF_INDEX_FLAG);
-}
-
-
void Alter_inplace_info::report_unsupported_error(const char *not_supported,
const char *try_instead)
{
@@ -4394,7 +4382,6 @@ handler::ha_create_partitioning_metadata(const char *name,
*/
DBUG_ASSERT(m_lock_type == F_UNLCK ||
(!old_name && strcmp(name, table_share->path.str)));
- mark_trx_read_write();
return create_partitioning_metadata(name, old_name, action_flag);
}
diff --git a/sql/handler.h b/sql/handler.h
index b280f6d597d..a29026990de 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -3901,7 +3901,7 @@ protected:
@note No errors are allowed during notify_table_changed().
*/
- virtual void notify_table_changed();
+ virtual void notify_table_changed() { }
public:
/* End of On-line/in-place ALTER TABLE interface. */
diff --git a/sql/item_func.h b/sql/item_func.h
index 0fb365f8107..689bfb84034 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -2460,6 +2460,7 @@ public:
Item_func_uuid_short(THD *thd): Item_int_func(thd) {}
const char *func_name() const { return "uuid_short"; }
longlong val_int();
+ bool const_item() const { return false; }
void fix_length_and_dec()
{ max_length= 21; unsigned_flag=1; }
table_map used_tables() const { return RAND_TABLE_BIT; }
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 4372855ccf5..c9956ab364e 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -1384,6 +1384,7 @@ public:
DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
fix_char_length(MY_UUID_STRING_LENGTH);
}
+ bool const_item() const { return false; }
table_map used_tables() const { return RAND_TABLE_BIT; }
const char *func_name() const{ return "uuid"; }
String *val_str(String *);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 55e5e49f5bd..7de9df9ebe6 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+ Copyright (c) 2000, 2018, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2018, 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
@@ -4525,6 +4525,24 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
db= (char *)start;
query= (char *)(start + db_len + 1);
q_len= data_len - db_len -1;
+
+ if (data_len && (data_len < db_len ||
+ data_len < q_len ||
+ data_len != (db_len + q_len + 1)))
+ {
+ q_len= 0;
+ query= NULL;
+ DBUG_VOID_RETURN;
+ }
+
+ uint32 max_length= uint32(event_len - ((const char*)(end + db_len + 1) -
+ (buf - common_header_len)));
+ if (q_len != max_length)
+ {
+ q_len= 0;
+ query= NULL;
+ DBUG_VOID_RETURN;
+ }
/**
Append the db length at the end of the buffer. This will be used by
Query_cache::send_result_to_client() in case the query cache is On.
@@ -5043,6 +5061,19 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
you.
*/
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
+
+ size_t valid_len= Well_formed_prefix(system_charset_info,
+ db, db_len, NAME_LEN).length();
+
+ if (valid_len != db_len)
+ {
+ rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+ ER_THD(thd, ER_SLAVE_FATAL_ERROR),
+ "Invalid database name in Query event.");
+ thd->is_slave_error= true;
+ goto end;
+ }
+
new_db.length= db_len;
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */
@@ -5184,7 +5215,23 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
}
else
thd->variables.collation_database= thd->db_charset;
-
+
+ {
+ const CHARSET_INFO *cs= thd->charset();
+ /*
+ We cannot ask for parsing a statement using a character set
+ without state_maps (parser internal data).
+ */
+ if (!cs->state_map)
+ {
+ rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+ ER_THD(thd, ER_SLAVE_FATAL_ERROR),
+ "character_set cannot be parsed");
+ thd->is_slave_error= true;
+ goto end;
+ }
+ }
+
/*
Record any GTID in the same transaction, so slave state is
transactionally consistent.
@@ -5727,7 +5774,13 @@ int Start_log_event_v3::do_apply_event(rpl_group_info *rgi)
*/
break;
default:
- /* this case is impossible */
+ /*
+ This case is not expected. It can be either an event corruption or an
+ unsupported binary log version.
+ */
+ rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+ ER_THD(thd, ER_SLAVE_FATAL_ERROR),
+ "Binlog version not supported");
DBUG_RETURN(1);
}
DBUG_RETURN(error);
@@ -6643,6 +6696,9 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
fields = (char*)field_lens + num_fields;
table_name = fields + field_block_len;
+ if (strlen(table_name) > NAME_LEN)
+ goto err;
+
db = table_name + table_name_len + 1;
DBUG_EXECUTE_IF ("simulate_invalid_address",
db_len = data_len;);
@@ -8623,6 +8679,13 @@ User_var_log_event(const char* buf, uint event_len,
buf+= description_event->common_header_len +
description_event->post_header_len[USER_VAR_EVENT-1];
name_len= uint4korr(buf);
+ /* Avoid reading out of buffer */
+ if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len)
+ {
+ error= true;
+ goto err;
+ }
+
name= (char *) buf + UV_NAME_LEN_SIZE;
/*
@@ -8679,7 +8742,12 @@ User_var_log_event(const char* buf, uint event_len,
Old events will not have this extra byte, thence,
we keep the flags set to UNDEF_F.
*/
- size_t bytes_read= ((val + val_len) - buf_start);
+ size_t bytes_read= (val + val_len) - buf_start;
+ if (bytes_read > size_t(event_len))
+ {
+ error= true;
+ goto err;
+ }
if ((data_written - bytes_read) > 0)
{
flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
@@ -8894,7 +8962,12 @@ int User_var_log_event::do_apply_event(rpl_group_info *rgi)
}
if (!(charset= get_charset(charset_number, MYF(MY_WME))))
+ {
+ rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+ ER_THD(thd, ER_SLAVE_FATAL_ERROR),
+ "Invalid character set for User var event");
DBUG_RETURN(1);
+ }
LEX_STRING user_var_name;
user_var_name.str= name;
user_var_name.length= name_len;
@@ -8909,12 +8982,26 @@ int User_var_log_event::do_apply_event(rpl_group_info *rgi)
{
switch (type) {
case REAL_RESULT:
+ if (val_len != 8)
+ {
+ rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+ ER_THD(thd, ER_SLAVE_FATAL_ERROR),
+ "Invalid variable length at User var event");
+ return 1;
+ }
float8get(real_val, val);
it= new (thd->mem_root) Item_float(thd, real_val, 0);
val= (char*) &real_val; // Pointer to value in native format
val_len= 8;
break;
case INT_RESULT:
+ if (val_len != 8)
+ {
+ rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+ ER_THD(thd, ER_SLAVE_FATAL_ERROR),
+ "Invalid variable length at User var event");
+ return 1;
+ }
int_val= (longlong) uint8korr(val);
it= new (thd->mem_root) Item_int(thd, int_val);
val= (char*) &int_val; // Pointer to value in native format
@@ -8922,6 +9009,13 @@ int User_var_log_event::do_apply_event(rpl_group_info *rgi)
break;
case DECIMAL_RESULT:
{
+ if (val_len < 3)
+ {
+ rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+ ER_THD(thd, ER_SLAVE_FATAL_ERROR),
+ "Invalid variable length at User var event");
+ return 1;
+ }
Item_decimal *dec= new (thd->mem_root) Item_decimal(thd, (uchar*) val+2, val[0], val[1]);
it= dec;
val= (char *)dec->val_decimal(NULL);
@@ -10294,6 +10388,14 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
m_width = net_field_length(&ptr_after_width);
DBUG_PRINT("debug", ("m_width=%lu", m_width));
+
+ /* Avoid reading out of buffer */
+ if (ptr_after_width + (m_width + 7) / 8 > (uchar*)buf + event_len)
+ {
+ m_cols.bitmap= NULL;
+ DBUG_VOID_RETURN;
+ }
+
/* if my_bitmap_init fails, catched in is_valid() */
if (likely(!my_bitmap_init(&m_cols,
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
@@ -10342,7 +10444,12 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
- size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
+ size_t const read_size= ptr_rows_data - (const unsigned char *) buf;
+ if (read_size > event_len)
+ {
+ DBUG_VOID_RETURN;
+ }
+ size_t const data_size= event_len - read_size;
DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu",
m_table_id, m_flags, m_width, (ulong) data_size));
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 68ffa32fafe..ce9bca920fe 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2007, 2016, Oracle and/or its affiliates.
+/* Copyright (c) 2007, 2018, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2018, 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
@@ -1233,6 +1234,13 @@ Old_rows_log_event::Old_rows_log_event(const char *buf, uint event_len,
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
m_width = net_field_length(&ptr_after_width);
DBUG_PRINT("debug", ("m_width=%lu", m_width));
+ /* Avoid reading out of buffer */
+ if (ptr_after_width + m_width > (uchar *)buf + event_len)
+ {
+ m_cols.bitmap= NULL;
+ DBUG_VOID_RETURN;
+ }
+
/* if my_bitmap_init fails, catched in is_valid() */
if (likely(!my_bitmap_init(&m_cols,
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 9e456bd3969..b28adae0a44 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -5969,5 +5969,6 @@ bool JOIN::choose_tableless_subquery_plan()
tmp_having= having;
}
}
+ exec_const_cond= conds;
return FALSE;
}
diff --git a/sql/sp.cc b/sql/sp.cc
index 89797ff400a..207ece47356 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2002, 2016, Oracle and/or its affiliates.
- Copyright (c) 2009, 2017, MariaDB
+ Copyright (c) 2002, 2018, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2018, 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
@@ -347,7 +347,7 @@ private:
bool m_print_once;
public:
- Proc_table_intact() : m_print_once(TRUE) {}
+ Proc_table_intact() : m_print_once(TRUE) { has_keys= TRUE; }
protected:
void report_error(uint code, const char *fmt, ...);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index e5c3340aa09..b3059248ac0 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+ Copyright (c) 2009, 2018, 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
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 6474213cb9f..48d16da9d0a 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates.
- Copyright (c) 2011, 2016, MariaDB
+ Copyright (c) 2011, 2018, 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
@@ -238,7 +238,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
if (thd->locked_tables_list.locked_tables())
{
- if (thd->locked_tables_list.reopen_tables(thd))
+ if (thd->locked_tables_list.reopen_tables(thd, false))
goto end;
/* Restore the table in the table list with the new opened table */
table_list->table= pos_in_locked_tables->table;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index aa4a77554f8..cc34b103a15 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -481,7 +481,7 @@ err_with_reopen:
old locks. This should always succeed (unless some external process
has removed the tables)
*/
- if (thd->locked_tables_list.reopen_tables(thd))
+ if (thd->locked_tables_list.reopen_tables(thd, false))
result= true;
/*
Since downgrade_lock() won't do anything with shared
@@ -808,7 +808,10 @@ void close_thread_tables(THD *thd)
we will exit this function a few lines below.
*/
if (! thd->lex->requires_prelocking())
+ {
+ thd->locked_tables_list.reopen_tables(thd, true);
DBUG_VOID_RETURN;
+ }
/*
We are in the top-level statement of a prelocked statement,
@@ -2241,7 +2244,8 @@ void Locked_tables_list::unlink_from_list(THD *thd,
If mode is not LTM_LOCK_TABLES, we needn't do anything. Moreover,
outside this mode pos_in_locked_tables value is not trustworthy.
*/
- if (thd->locked_tables_mode != LTM_LOCK_TABLES)
+ if (thd->locked_tables_mode != LTM_LOCK_TABLES &&
+ thd->locked_tables_mode != LTM_PRELOCKED_UNDER_LOCK_TABLES)
return;
/*
@@ -2345,7 +2349,7 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count)
*/
bool
-Locked_tables_list::reopen_tables(THD *thd)
+Locked_tables_list::reopen_tables(THD *thd, bool need_reopen)
{
Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN);
size_t reopen_count= 0;
@@ -2356,8 +2360,20 @@ Locked_tables_list::reopen_tables(THD *thd)
for (TABLE_LIST *table_list= m_locked_tables;
table_list; table_list= table_list->next_global)
{
- if (table_list->table) /* The table was not closed */
- continue;
+ if (need_reopen)
+ {
+ if (!table_list->table || !table_list->table->needs_reopen())
+ continue;
+ /* no need to remove the table from the TDC here, thus (TABLE*)1 */
+ close_all_tables_for_name(thd, table_list->table->s,
+ HA_EXTRA_NOT_USED, (TABLE*)1);
+ DBUG_ASSERT(table_list->table == NULL);
+ }
+ else
+ {
+ if (table_list->table) /* The table was not closed */
+ continue;
+ }
/* Links into thd->open_tables upon success */
if (open_table(thd, table_list, &ot_ctx))
diff --git a/sql/sql_base.h b/sql/sql_base.h
index 9fb94e92d09..d6063f1b771 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -1,4 +1,6 @@
/* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2011, 2018, 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
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 89cdb5af251..cd31e0356e8 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1854,7 +1854,7 @@ public:
void unlink_all_closed_tables(THD *thd,
MYSQL_LOCK *lock,
size_t reopen_count);
- bool reopen_tables(THD *thd);
+ bool reopen_tables(THD *thd, bool need_reopen);
bool restore_lock(THD *thd, TABLE_LIST *dst_table_list, TABLE *table,
MYSQL_LOCK *lock);
void add_back_last_deleted_lock(TABLE_LIST *dst_table_list);
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 1376115e77c..536c436475f 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2005, 2017, Oracle and/or its affiliates.
- Copyright (c) 2009, 2017, SkySQL Ab.
+ Copyright (c) 2009, 2018, 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
@@ -6283,7 +6283,7 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
thd->set_stmt_da(&tmp_stmt_da);
}
- if (thd->locked_tables_list.reopen_tables(thd))
+ if (thd->locked_tables_list.reopen_tables(thd, false))
sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE");
if (stmt_da)
@@ -6489,7 +6489,7 @@ err_exclusive_lock:
thd->set_stmt_da(&tmp_stmt_da);
}
- if (thd->locked_tables_list.reopen_tables(thd))
+ if (thd->locked_tables_list.reopen_tables(thd, false))
sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE");
if (stmt_da)
diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc
index 1f9ee32ba73..cb5b3c8a044 100644
--- a/sql/sql_partition_admin.cc
+++ b/sql/sql_partition_admin.cc
@@ -629,7 +629,7 @@ bool Sql_cmd_alter_table_exchange_partition::
better to keep master/slave in consistent state. Alternative would be to
try to revert the exchange operation and issue error.
*/
- (void) thd->locked_tables_list.reopen_tables(thd);
+ (void) thd->locked_tables_list.reopen_tables(thd, false);
if ((error= write_bin_log(thd, TRUE, thd->query(), thd->query_length())))
{
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index adf6fa4f936..4c258acd487 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1,6 +1,6 @@
/*
- Copyright (c) 2005, 2013, Oracle and/or its affiliates.
- Copyright (c) 2010, 2017, MariaDB Corporation.
+ Copyright (c) 2005, 2018, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2018, MariaDB Corporation
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
@@ -2283,6 +2283,16 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name,
if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
DBUG_RETURN(TRUE);
+ if (!table->key_info)
+ {
+ my_printf_error(ER_UNKNOWN_ERROR,
+ "The table %s.%s has no primary key. "
+ "Please check the table definition and "
+ "create the primary key accordingly.", MYF(0),
+ table->s->db.str, table->s->table_name.str);
+ DBUG_RETURN(TRUE);
+ }
+
/*
Pre-acquire audit plugins for events that may potentially occur
during [UN]INSTALL PLUGIN.
diff --git a/sql/sql_priv.h b/sql/sql_priv.h
index 6c9df6a9606..f34148d4fe6 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
- Copyright (c) 2010, 2014, Monty Program Ab.
+/* Copyright (c) 2000, 2018, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2018, Monty Program Ab.
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
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 5badcad3492..e40e817ec8a 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -2619,7 +2619,7 @@ int collect_statistics_for_index(THD *thd, TABLE *table, uint index)
DBUG_ENTER("collect_statistics_for_index");
/* No statistics for FULLTEXT indexes. */
- if (key_info->flags & HA_FULLTEXT)
+ if (key_info->flags & (HA_FULLTEXT|HA_SPATIAL))
DBUG_RETURN(rc);
Index_prefix_calc index_prefix_calc(thd, table, key_info);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 78e91d64689..9e7973b745c 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2017, MariaDB Corporation.
+ Copyright (c) 2010, 2018, 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
@@ -5090,7 +5090,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
This should always work as we have a meta lock on the table.
*/
thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables);
- if (thd->locked_tables_list.reopen_tables(thd))
+ if (thd->locked_tables_list.reopen_tables(thd, false))
{
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
result= 1;
@@ -5480,7 +5480,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
This should always work as we have a meta lock on the table.
*/
thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables);
- if (thd->locked_tables_list.reopen_tables(thd))
+ if (thd->locked_tables_list.reopen_tables(thd, false))
{
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
res= 1; // We got an error
@@ -7455,7 +7455,7 @@ static bool mysql_inplace_alter_table(THD *thd,
HA_EXTRA_PREPARE_FOR_RENAME :
HA_EXTRA_NOT_USED,
NULL);
- if (thd->locked_tables_list.reopen_tables(thd))
+ if (thd->locked_tables_list.reopen_tables(thd, false))
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
/* QQ; do something about metadata locks ? */
}
@@ -9642,7 +9642,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
end_inplace:
- if (thd->locked_tables_list.reopen_tables(thd))
+ if (thd->locked_tables_list.reopen_tables(thd, false))
goto err_with_mdl_after_alter;
THD_STAGE_INFO(thd, stage_end);
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 303c5d75e18..0fefe7d2c52 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1,5 +1,6 @@
/*
Copyright (c) 2004, 2012, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2018, 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
@@ -587,7 +588,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
Ignore the return value for now. It's better to
keep master/slave in consistent state.
*/
- if (thd->locked_tables_list.reopen_tables(thd))
+ if (thd->locked_tables_list.reopen_tables(thd, false))
thd->clear_error();
/*
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index c08c75f771a..8a70e6f6bdb 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates.
- Copyright (c) 2013, 2015, MariaDB
+ Copyright (c) 2012, 2018, 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
@@ -426,7 +426,7 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
*/
error= dd_recreate_table(thd, table_ref->db, table_ref->table_name);
- if (thd->locked_tables_mode && thd->locked_tables_list.reopen_tables(thd))
+ if (thd->locked_tables_mode && thd->locked_tables_list.reopen_tables(thd, false))
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
/* No need to binlog a failed truncate-by-recreate. */
@@ -500,4 +500,3 @@ bool Sql_cmd_truncate_table::execute(THD *thd)
DBUG_RETURN(res);
}
-
diff --git a/sql/table.cc b/sql/table.cc
index b36feadeac2..18bc4bf17bc 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2016, MariaDB
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2008, 2018, 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
@@ -4088,7 +4088,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
/* Whether the table definition has already been validated. */
if (table->s->table_field_def_cache == table_def)
- DBUG_RETURN(FALSE);
+ goto end;
if (table->s->fields != table_def->count)
{
@@ -4121,6 +4121,8 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
is backward compatible.
*/
}
+ else
+ {
StringBuffer<1024> sql_type(system_charset_info);
sql_type.extra_allocation(256); // Allocate min 256 characters at once
for (i=0 ; i < table_def->count; i++, field_def++)
@@ -4206,6 +4208,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
error= TRUE;
}
}
+ }
if (table_def->primary_key_parts)
{
@@ -4250,6 +4253,16 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def)
if (! error)
table->s->table_field_def_cache= table_def;
+end:
+
+ if (has_keys && !error && !table->key_info)
+ {
+ report_error(0, "Incorrect definition of table %s.%s: "
+ "indexes are missing",
+ table->s->db.str, table->alias.c_ptr());
+ error= TRUE;
+ }
+
DBUG_RETURN(error);
}
diff --git a/sql/table.h b/sql/table.h
index 7af45b9f169..61ac6c06e38 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1,8 +1,7 @@
#ifndef TABLE_INCLUDED
#define TABLE_INCLUDED
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2009, 2014, SkySQL Ab.
- Copyright (c) 2016, 2017, MariaDB Corporation.
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2018, 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
@@ -473,10 +472,11 @@ typedef struct st_table_field_def
class Table_check_intact
{
protected:
+ bool has_keys;
virtual void report_error(uint code, const char *fmt, ...)= 0;
public:
- Table_check_intact() {}
+ Table_check_intact(bool keys= false) : has_keys(keys) {}
virtual ~Table_check_intact() {}
/** Checks whether a table is intact. */
@@ -491,6 +491,8 @@ class Table_check_intact_log_error : public Table_check_intact
{
protected:
void report_error(uint, const char *fmt, ...);
+public:
+ Table_check_intact_log_error() : Table_check_intact(true) {}
};