summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_sequence.cc2
-rw-r--r--sql/handler.h12
-rw-r--r--sql/item.cc4
-rw-r--r--sql/item_func.cc12
-rw-r--r--sql/partition_info.cc4
-rw-r--r--sql/sql_acl.cc6
-rw-r--r--sql/sql_const.h12
-rw-r--r--sql/sql_db.cc9
-rw-r--r--sql/sql_db.h3
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_select.cc4
-rw-r--r--sql/sql_signal.cc10
-rw-r--r--sql/sql_table.cc16
-rw-r--r--sql/table.cc10
-rw-r--r--sql/temporary_tables.cc50
-rw-r--r--sql/wsrep_sst.cc21
-rw-r--r--sql/wsrep_sst.h3
17 files changed, 104 insertions, 78 deletions
diff --git a/sql/ha_sequence.cc b/sql/ha_sequence.cc
index d5064af16c3..a199892f971 100644
--- a/sql/ha_sequence.cc
+++ b/sql/ha_sequence.cc
@@ -114,7 +114,7 @@ int ha_sequence::open(const char *name, int mode, uint flags)
if (unlikely((error= table->s->sequence->read_initial_values(table))))
file->ha_close();
}
- else
+ else if (!table->s->tmp_table)
table->m_needs_reopen= true;
/*
diff --git a/sql/handler.h b/sql/handler.h
index a0739d75aaf..fc6246c38a1 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -430,6 +430,12 @@ enum enum_alter_inplace_result {
#define HA_KEY_NULL_LENGTH 1
#define HA_KEY_BLOB_LENGTH 2
+/* Maximum length of any index lookup key, in bytes */
+
+#define MAX_KEY_LENGTH (MAX_DATA_LENGTH_FOR_KEY \
+ +(MAX_REF_PARTS \
+ *(HA_KEY_NULL_LENGTH + HA_KEY_BLOB_LENGTH)))
+
#define HA_LEX_CREATE_TMP_TABLE 1U
#define HA_CREATE_TMP_ALTER 8U
#define HA_LEX_CREATE_SEQUENCE 16U
@@ -3801,14 +3807,14 @@ public:
uint max_key_parts() const
{ return MY_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
uint max_key_length() const
- { return MY_MIN(MAX_KEY_LENGTH, max_supported_key_length()); }
+ { return MY_MIN(MAX_DATA_LENGTH_FOR_KEY, max_supported_key_length()); }
uint max_key_part_length() const
- { return MY_MIN(MAX_KEY_LENGTH, max_supported_key_part_length()); }
+ { return MY_MIN(MAX_DATA_LENGTH_FOR_KEY, max_supported_key_part_length()); }
virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
virtual uint max_supported_keys() const { return 0; }
virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
- virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
+ virtual uint max_supported_key_length() const { return MAX_DATA_LENGTH_FOR_KEY; }
virtual uint max_supported_key_part_length() const { return 255; }
virtual uint min_record_length(uint options) const { return 1; }
diff --git a/sql/item.cc b/sql/item.cc
index ed9c78e5525..4387d67e615 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -8071,7 +8071,9 @@ void Item_ref::print(String *str, enum_query_type query_type)
{
if (ref)
{
- if ((*ref)->type() != Item::CACHE_ITEM && ref_type() != VIEW_REF &&
+ if ((*ref)->type() != Item::CACHE_ITEM &&
+ (*ref)->type() != Item::WINDOW_FUNC_ITEM &&
+ ref_type() != VIEW_REF &&
!table_name && name.str && alias_name_used)
{
THD *thd= current_thd;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 1f949a4445b..60216684c53 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1615,13 +1615,9 @@ longlong Item_func_int_div::val_int()
bool Item_func_int_div::fix_length_and_dec()
{
- Item_result argtype= args[0]->result_type();
- /* use precision ony for the data type it is applicable for and valid */
- uint32 char_length= args[0]->max_char_length() -
- (argtype == DECIMAL_RESULT || argtype == INT_RESULT ?
- args[0]->decimals : 0);
- fix_char_length(char_length > MY_INT64_NUM_DECIMAL_DIGITS ?
- MY_INT64_NUM_DECIMAL_DIGITS : char_length);
+ uint32 prec= args[0]->decimal_int_part();
+ set_if_smaller(prec, MY_INT64_NUM_DECIMAL_DIGITS);
+ fix_char_length(prec);
maybe_null=1;
unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag;
return false;
@@ -3169,6 +3165,8 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
func->maybe_null=1;
if (with_sum_func_cache)
with_sum_func_cache->join_with_sum_func(item);
+ func->with_window_func= func->with_window_func ||
+ item->with_window_func;
func->with_field= func->with_field || item->with_field;
func->with_param= func->with_param || item->with_param;
func->With_subquery_cache::join(item);
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index e24038f96ab..0ac4014a669 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -1516,12 +1516,12 @@ bool partition_info::check_partition_field_length()
for (i= 0; i < num_part_fields; i++)
store_length+= get_partition_field_store_length(part_field_array[i]);
- if (store_length > MAX_KEY_LENGTH)
+ if (store_length > MAX_DATA_LENGTH_FOR_KEY)
DBUG_RETURN(TRUE);
store_length= 0;
for (i= 0; i < num_subpart_fields; i++)
store_length+= get_partition_field_store_length(subpart_field_array[i]);
- if (store_length > MAX_KEY_LENGTH)
+ if (store_length > MAX_DATA_LENGTH_FOR_KEY)
DBUG_RETURN(TRUE);
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 85b54009219..3c31be5bd36 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -6614,7 +6614,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list,
{
List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str, *tmp_Str;
- bool create_new_users= 0, result;
+ bool create_new_users= 0;
+ int result;
const char *db_name, *table_name;
DBUG_ENTER("mysql_routine_grant");
@@ -7047,7 +7048,8 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
List_iterator <LEX_USER> str_list (list);
LEX_USER *Str, *tmp_Str, *proxied_user= NULL;
char tmp_db[SAFE_NAME_LEN+1];
- bool create_new_users=0, result;
+ bool create_new_users=0;
+ int result;
DBUG_ENTER("mysql_grant");
if (lower_case_table_names && db)
diff --git a/sql/sql_const.h b/sql/sql_const.h
index be26de872df..82f3b9c21f2 100644
--- a/sql/sql_const.h
+++ b/sql/sql_const.h
@@ -33,7 +33,17 @@
#define MAX_SYS_VAR_LENGTH 32
#define MAX_KEY MAX_INDEXES /* Max used keys */
#define MAX_REF_PARTS 32 /* Max parts used as ref */
-#define MAX_KEY_LENGTH 3072 /* max possible key */
+
+/*
+ Maximum length of the data part of an index lookup key.
+
+ The "data part" is defined as the value itself, not including the
+ NULL-indicator bytes or varchar length bytes ("the Extras"). We need this
+ value because there was a bug where length of the Extras were not counted.
+
+ You probably need MAX_KEY_LENGTH, not this constant.
+*/
+#define MAX_DATA_LENGTH_FOR_KEY 3072
#if SIZEOF_OFF_T > 4
#define MAX_REFLENGTH 8 /* Max length for record ref */
#else
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 5f826e37a76..55c51dbe151 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -764,8 +764,7 @@ exit:
}
-int mysql_create_db(THD *thd, const LEX_CSTRING *db,
- const DDL_options_st &options,
+int mysql_create_db(THD *thd, const LEX_CSTRING *db, DDL_options_st options,
const Schema_specification_st *create_info)
{
/*
@@ -773,6 +772,9 @@ int mysql_create_db(THD *thd, const LEX_CSTRING *db,
to it, we need to use a copy to make execution prepared statement- safe.
*/
Schema_specification_st tmp(*create_info);
+ if (thd->slave_thread &&
+ slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT)
+ options.add(DDL_options::OPT_IF_NOT_EXISTS);
return mysql_create_db_internal(thd, db, options, &tmp, false);
}
@@ -1047,6 +1049,9 @@ exit:
bool mysql_rm_db(THD *thd, const LEX_CSTRING *db, bool if_exists)
{
+ if (thd->slave_thread &&
+ slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT)
+ if_exists= true;
return mysql_rm_db_internal(thd, db, if_exists, false);
}
diff --git a/sql/sql_db.h b/sql/sql_db.h
index 7de6c2a9c99..c0646bd65f0 100644
--- a/sql/sql_db.h
+++ b/sql/sql_db.h
@@ -20,8 +20,7 @@
class THD;
-int mysql_create_db(THD *thd, const LEX_CSTRING *db,
- const DDL_options_st &options,
+int mysql_create_db(THD *thd, const LEX_CSTRING *db, DDL_options_st options,
const Schema_specification_st *create);
bool mysql_alter_db(THD *thd, const LEX_CSTRING *db,
const Schema_specification_st *create);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 312608e1395..7d6f71cda21 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -566,7 +566,7 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_CREATE_PACKAGE_BODY]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_DROP_PACKAGE_BODY]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS;
- sql_command_flags[SQLCOM_ALTER_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
+ sql_command_flags[SQLCOM_ALTER_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_DB_CHANGE;
sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS;
sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
@@ -1486,7 +1486,7 @@ static bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables)
if (lex->sql_command == SQLCOM_DROP_TABLE && lex->tmp_table())
DBUG_RETURN(FALSE);
- /* Check if we created or dropped databases */
+ /* Check if we created, dropped, or renamed a database */
if ((sql_command_flags[lex->sql_command] & CF_DB_CHANGE))
DBUG_RETURN(TRUE);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 04baf5737c6..978f0785887 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -20275,6 +20275,10 @@ test_if_quick_select(JOIN_TAB *tab)
delete tab->select->quick;
tab->select->quick=0;
+
+ if (tab->table->file->inited != handler::NONE)
+ tab->table->file->ha_index_or_rnd_end();
+
int res= tab->select->test_quick_select(tab->join->thd, tab->keys,
(table_map) 0, HA_POS_ERROR, 0,
FALSE, /*remove where parts*/FALSE);
diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc
index 83abaebd4fd..359b5e45f01 100644
--- a/sql/sql_signal.cc
+++ b/sql/sql_signal.cc
@@ -343,13 +343,15 @@ bool Sql_cmd_common_signal::raise_condition(THD *thd, Sql_condition *cond)
if (eval_signal_informations(thd, cond))
DBUG_RETURN(result);
- /* SIGNAL should not signal WARN_LEVEL_NOTE */
- DBUG_ASSERT((cond->m_level == Sql_condition::WARN_LEVEL_WARN) ||
- (cond->m_level == Sql_condition::WARN_LEVEL_ERROR));
+ /* SIGNAL should not signal WARN_LEVEL_NOTE, but RESIGNAL can */
+ DBUG_ASSERT(cond->m_level == Sql_condition::WARN_LEVEL_ERROR ||
+ cond->m_level != Sql_condition::WARN_LEVEL_NOTE ||
+ sql_command_code() == SQLCOM_RESIGNAL);
(void) thd->raise_condition(cond);
- if (cond->m_level == Sql_condition::WARN_LEVEL_WARN)
+ if (cond->m_level == Sql_condition::WARN_LEVEL_WARN ||
+ cond->m_level == Sql_condition::WARN_LEVEL_NOTE)
{
my_ok(thd);
result= FALSE;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 666c6fb325a..f200f6f8c6d 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -10398,14 +10398,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
error= 1;
break;
}
- if (to->next_number_field)
- {
- if (auto_increment_field_copied)
- to->auto_increment_field_not_null= TRUE;
- else
- to->next_number_field->reset();
- }
-
+
for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
{
copy_ptr->do_copy(copy_ptr);
@@ -10443,6 +10436,13 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
if (keep_versioned && to->versioned(VERS_TRX_ID))
to->vers_write= false;
+ if (to->next_number_field)
+ {
+ if (auto_increment_field_copied)
+ to->auto_increment_field_not_null= TRUE;
+ else
+ to->next_number_field->reset();
+ }
error= to->file->ha_write_row(to->record[0]);
to->auto_increment_field_not_null= FALSE;
if (unlikely(error))
diff --git a/sql/table.cc b/sql/table.cc
index 0a40c5fb341..488d05b1a22 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1075,7 +1075,7 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
while (pos < end)
{
uint type, expr_length;
- if (table->s->mysql_version >= 100202)
+ if (table->s->frm_version >= FRM_VER_EXPRESSSIONS)
{
uint field_nr, name_length;
/* see pack_expression() for how data is stored */
@@ -2308,7 +2308,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
uint pk_part_length= key_first_info->key_part[i].store_length;
if (keyinfo->ext_key_part_map & 1<<i)
{
- if (ext_key_length + pk_part_length > MAX_KEY_LENGTH)
+ if (ext_key_length + pk_part_length > MAX_DATA_LENGTH_FOR_KEY)
{
add_keyparts_for_this_key= i;
break;
@@ -2318,9 +2318,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
}
- if (add_keyparts_for_this_key < (keyinfo->ext_key_parts -
- keyinfo->user_defined_key_parts))
- {
+ if (add_keyparts_for_this_key < keyinfo->ext_key_parts -
+ keyinfo->user_defined_key_parts)
+ {
share->ext_key_parts-= keyinfo->ext_key_parts;
key_part_map ext_key_part_map= keyinfo->ext_key_part_map;
keyinfo->ext_key_parts= keyinfo->user_defined_key_parts;
diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc
index 1c8af5eaf66..917a85e6c3b 100644
--- a/sql/temporary_tables.cc
+++ b/sql/temporary_tables.cc
@@ -1041,39 +1041,28 @@ TABLE *THD::find_temporary_table(const char *key, uint key_length,
/* A matching TMP_TABLE_SHARE is found. */
All_share_tables_list::Iterator tables_it(share->all_tmp_tables);
- while ((table= tables_it++))
+ bool found= false;
+ while (!found && (table= tables_it++))
{
switch (state)
{
- case TMP_TABLE_IN_USE:
- if (table->query_id > 0)
- {
- result= table;
- goto done;
- }
- break;
- case TMP_TABLE_NOT_IN_USE:
- if (table->query_id == 0)
- {
- result= table;
- goto done;
- }
- break;
- case TMP_TABLE_ANY:
- {
- result= table;
- goto done;
- }
- break;
- default: /* Invalid */
- DBUG_ASSERT(0);
- goto done;
+ case TMP_TABLE_IN_USE: found= table->query_id > 0; break;
+ case TMP_TABLE_NOT_IN_USE: found= table->query_id == 0; break;
+ case TMP_TABLE_ANY: found= true; break;
}
}
+ if (table && unlikely(table->m_needs_reopen))
+ {
+ share->all_tmp_tables.remove(table);
+ free_temporary_table(table);
+ it.rewind();
+ continue;
+ }
+ result= table;
+ break;
}
}
-done:
if (locked)
{
DBUG_ASSERT(m_tmp_tables_locked);
@@ -1154,8 +1143,7 @@ TABLE *THD::open_temporary_table(TMP_TABLE_SHARE *share,
@return Success false
Failure true
*/
-bool THD::find_and_use_tmp_table(const TABLE_LIST *tl,
- TABLE **out_table)
+bool THD::find_and_use_tmp_table(const TABLE_LIST *tl, TABLE **out_table)
{
DBUG_ENTER("THD::find_and_use_tmp_table");
@@ -1165,11 +1153,9 @@ bool THD::find_and_use_tmp_table(const TABLE_LIST *tl,
key_length= create_tmp_table_def_key(key, tl->get_db_name(),
tl->get_table_name());
- result=
- use_temporary_table(find_temporary_table(key, key_length,
- TMP_TABLE_NOT_IN_USE),
- out_table);
-
+ result= use_temporary_table(find_temporary_table(key, key_length,
+ TMP_TABLE_NOT_IN_USE),
+ out_table);
DBUG_RETURN(result);
}
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 24306e37ca3..0a2424fa069 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -803,6 +803,7 @@ ssize_t wsrep_sst_prepare (void** msg)
{
const char* addr_in= NULL;
const char* addr_out= NULL;
+ const char* method;
if (!strcmp(wsrep_sst_method, WSREP_SST_SKIP))
{
@@ -861,7 +862,8 @@ ssize_t wsrep_sst_prepare (void** msg)
}
ssize_t addr_len= -ENOSYS;
- if (!strcmp(wsrep_sst_method, WSREP_SST_MYSQLDUMP))
+ method = wsrep_sst_method;
+ if (!strcmp(method, WSREP_SST_MYSQLDUMP))
{
addr_len= sst_prepare_mysqldump (addr_in, &addr_out);
if (addr_len < 0) unireg_abort(1);
@@ -871,6 +873,13 @@ ssize_t wsrep_sst_prepare (void** msg)
/*! A heuristic workaround until we learn how to stop and start engines */
if (SE_initialized)
{
+ if (!strcmp(method, WSREP_SST_XTRABACKUP) ||
+ !strcmp(method, WSREP_SST_XTRABACKUPV2))
+ {
+ WSREP_WARN("The %s SST method is deprecated, so it is automatically "
+ "replaced by %s", method, WSREP_SST_MARIABACKUP);
+ method = WSREP_SST_MARIABACKUP;
+ }
// we already did SST at initializaiton, now engines are running
// sql_print_information() is here because the message is too long
// for WSREP_INFO.
@@ -880,28 +889,28 @@ ssize_t wsrep_sst_prepare (void** msg)
"Wsrep provider won't be able to fall back to it "
"if other means of state transfer are unavailable. "
"In that case you will need to restart the server.",
- wsrep_sst_method);
+ method);
*msg = 0;
return 0;
}
- addr_len = sst_prepare_other (wsrep_sst_method, sst_auth_real,
+ addr_len = sst_prepare_other (method, sst_auth_real,
addr_in, &addr_out);
if (addr_len < 0)
{
WSREP_ERROR("Failed to prepare for '%s' SST. Unrecoverable.",
- wsrep_sst_method);
+ method);
unireg_abort(1);
}
}
- size_t const method_len(strlen(wsrep_sst_method));
+ size_t const method_len(strlen(method));
size_t const msg_len (method_len + addr_len + 2 /* + auth_len + 1*/);
*msg = malloc (msg_len);
if (NULL != *msg) {
char* const method_ptr(reinterpret_cast<char*>(*msg));
- strcpy (method_ptr, wsrep_sst_method);
+ strcpy (method_ptr, method);
char* const addr_ptr(method_ptr + method_len + 1);
strcpy (addr_ptr, addr_out);
diff --git a/sql/wsrep_sst.h b/sql/wsrep_sst.h
index cc0f1f5389d..29724a00797 100644
--- a/sql/wsrep_sst.h
+++ b/sql/wsrep_sst.h
@@ -49,6 +49,9 @@
#define WSREP_SST_MYSQLDUMP "mysqldump"
#define WSREP_SST_RSYNC "rsync"
#define WSREP_SST_SKIP "skip"
+#define WSREP_SST_MARIABACKUP "mariabackup"
+#define WSREP_SST_XTRABACKUP "xtrabackup"
+#define WSREP_SST_XTRABACKUPV2 "xtrabackupv2"
#define WSREP_SST_DEFAULT WSREP_SST_RSYNC
#define WSREP_SST_ADDRESS_AUTO "AUTO"
#define WSREP_SST_AUTH_MASK "********"