summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field.h20
-rw-r--r--sql/item_cmpfunc.cc2
-rw-r--r--sql/item_cmpfunc.h4
-rw-r--r--sql/item_func.cc8
-rw-r--r--sql/item_subselect.cc28
-rw-r--r--sql/mysqld.h4
-rw-r--r--sql/sql_acl.cc4
-rw-r--r--sql/sql_insert.cc16
-rw-r--r--sql/sql_prepare.cc6
-rw-r--r--sql/sql_reload.cc5
-rw-r--r--sql/sql_select.cc32
-rw-r--r--sql/table.cc17
12 files changed, 94 insertions, 52 deletions
diff --git a/sql/field.h b/sql/field.h
index b20bedbecc9..4c79847228e 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -349,7 +349,7 @@ public:
DBUG_ENTER("Field::pack_length_from_metadata");
DBUG_RETURN(field_metadata);
}
- virtual uint row_pack_length() { return 0; }
+ virtual uint row_pack_length() const { return 0; }
virtual int save_field_metadata(uchar *first_byte)
{ return do_save_field_metadata(first_byte); }
@@ -757,7 +757,7 @@ public:
int store_decimal(const my_decimal *);
my_decimal *val_decimal(my_decimal *);
uint is_equal(Create_field *new_field);
- uint row_pack_length() { return pack_length(); }
+ uint row_pack_length() const { return pack_length(); }
uint32 pack_length_from_metadata(uint field_metadata) {
uint32 length= pack_length();
DBUG_PRINT("result", ("pack_length_from_metadata(%d): %u",
@@ -940,7 +940,7 @@ public:
uint size_of() const { return sizeof(*this); }
uint32 pack_length() const { return (uint32) bin_size; }
uint pack_length_from_metadata(uint field_metadata);
- uint row_pack_length() { return pack_length(); }
+ uint row_pack_length() const { return pack_length(); }
bool compatible_field_size(uint field_metadata, Relay_log_info *rli,
uint16 mflags, int *order_var);
uint is_equal(Create_field *new_field);
@@ -1189,7 +1189,7 @@ public:
int cmp(const uchar *,const uchar *);
void sort_string(uchar *buff,uint length);
uint32 pack_length() const { return sizeof(float); }
- uint row_pack_length() { return pack_length(); }
+ uint row_pack_length() const { return pack_length(); }
void sql_type(String &str) const;
private:
int do_save_field_metadata(uchar *first_byte);
@@ -1229,7 +1229,7 @@ public:
int cmp(const uchar *,const uchar *);
void sort_string(uchar *buff,uint length);
uint32 pack_length() const { return sizeof(double); }
- uint row_pack_length() { return pack_length(); }
+ uint row_pack_length() const { return pack_length(); }
void sql_type(String &str) const;
private:
int do_save_field_metadata(uchar *first_byte);
@@ -1718,7 +1718,7 @@ public:
}
bool compatible_field_size(uint field_metadata, Relay_log_info *rli,
uint16 mflags, int *order_var);
- uint row_pack_length() { return field_length; }
+ uint row_pack_length() const { return field_length; }
int pack_cmp(const uchar *a,const uchar *b,uint key_length,
bool insert_or_update);
int pack_cmp(const uchar *b,uint key_length,bool insert_or_update);
@@ -1768,7 +1768,7 @@ public:
enum_field_types type() const { return MYSQL_TYPE_VARCHAR; }
bool match_collation_to_optimize_range() const { return TRUE; }
enum ha_base_keytype key_type() const;
- uint row_pack_length() { return field_length; }
+ uint row_pack_length() const { return field_length; }
bool zero_pack() const { return 0; }
int reset(void) { bzero(ptr,field_length+length_bytes); return 0; }
uint32 pack_length() const { return (uint32) field_length+length_bytes; }
@@ -1893,7 +1893,7 @@ public:
*/
uint32 pack_length_no_ptr() const
{ return (uint32) (packlength); }
- uint row_pack_length() { return pack_length_no_ptr(); }
+ uint row_pack_length() const { return pack_length_no_ptr(); }
uint32 sort_length() const;
virtual uint32 max_data_length() const
{
@@ -2055,7 +2055,7 @@ public:
enum_field_types real_type() const { return MYSQL_TYPE_ENUM; }
uint pack_length_from_metadata(uint field_metadata)
{ return (field_metadata & 0x00ff); }
- uint row_pack_length() { return pack_length(); }
+ uint row_pack_length() const { return pack_length(); }
virtual bool zero_pack() const { return 0; }
bool optimize_range(uint idx, uint part) { return 0; }
bool eq_def(Field *field);
@@ -2176,7 +2176,7 @@ public:
uint32 pack_length() const { return (uint32) (field_length + 7) / 8; }
uint32 pack_length_in_rec() const { return bytes_in_rec; }
uint pack_length_from_metadata(uint field_metadata);
- uint row_pack_length()
+ uint row_pack_length() const
{ return (bytes_in_rec + ((bit_len > 0) ? 1 : 0)); }
bool compatible_field_size(uint metadata, Relay_log_info *rli,
uint16 mflags, int *order_var);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 0c48592eb9f..d5f50871ddf 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2009, 2013, Monty Program Ab.
+ Copyright (c) 2009, 2015, 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/item_cmpfunc.h b/sql/item_cmpfunc.h
index 9504be57a90..babe1d76ea4 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1,7 +1,7 @@
#ifndef ITEM_CMPFUNC_INCLUDED
#define ITEM_CMPFUNC_INCLUDED
-/* Copyright (c) 2000, 2012, Oracle and/or its affiliates.
- Copyright (c) 2009, 2011, Monty Program Ab.
+/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2015, 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/item_func.cc b/sql/item_func.cc
index 9a38fc60b0d..252ca9e504b 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
Copyright (c) 2009, 2015, MariaDB
This program is free software; you can redistribute it and/or modify
@@ -6280,9 +6280,7 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref)
table= 0;
for (uint i=1 ; i < arg_count ; i++)
{
- item=args[i];
- if (item->type() == Item::REF_ITEM)
- args[i]= item= *((Item_ref *)item)->ref;
+ item= args[i]= args[i]->real_item();
/*
When running in PS mode, some Item_field's can already be replaced
to Item_func_conv_charset during PREPARE time. This is possible
@@ -6295,7 +6293,7 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref)
if (!thd->stmt_arena->is_stmt_execute() &&
item->type() != Item::FIELD_ITEM)
{
- my_error(ER_WRONG_ARGUMENTS, MYF(0), "AGAINST");
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "MATCH");
return TRUE;
}
/*
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 1107945ae99..3020faf29d3 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2002, 2012, Oracle and/or its affiliates.
- Copyright (c) 2010, 2012, Monty Program Ab
+/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2015, 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
@@ -1748,6 +1748,27 @@ Item_in_subselect::single_value_transformer(JOIN *join)
runtime created Ref item which is deleted at the end
of the statement. Thus one of 'substitution' arguments
can be broken in case of PS.
+
+ @todo
+ Why do we use real_item()/substitutional_item() instead of the plain
+ left_expr?
+ Because left_expr might be a rollbackable item, and we fail to properly
+ rollback all copies of left_expr at end of execution, so we want to
+ avoid creating copies of left_expr as much as possible, so we use
+ real_item() instead.
+ Doing a proper rollback is difficult: the change was registered for the
+ original item which was the left argument of IN. Then this item was
+ copied to left_expr, which is copied below to substitution->args[0]. To
+ do a proper rollback, we would have to restore the content
+ of both copies as well as the original item. There might be more copies,
+ if AND items have been constructed.
+ The same applies to the right expression.
+ However, using real_item()/substitutional_item() brings its own
+ problems: for example, we lose information that the item is an outer
+ reference; the item can thus wrongly be considered for a Keyuse (causing
+ bug#17766653).
+ When WL#6570 removes the "rolling back" system, all
+ real_item()/substitutional_item() in this file should be removed.
*/
substitution= func->create(left_expr, where_item);
have_to_be_excluded= 1;
@@ -2034,6 +2055,9 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
}
else
{
+ /*
+ Grep for "WL#6570" to see the relevant comment about real_item.
+ */
Item *item= (Item*) select_lex->item_list.head()->real_item();
if (select_lex->table_list.elements)
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 3480d02365b..24ae9ec7a61 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2015, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2015, 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
@@ -336,6 +337,7 @@ extern mysql_mutex_t
LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count;
extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thread_count;
#ifdef HAVE_OPENSSL
+extern char* des_key_file;
extern mysql_mutex_t LOCK_des_key_file;
#endif
extern mysql_mutex_t LOCK_server_started;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 4588c741cb4..da7c3f17c63 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -7326,6 +7326,8 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user,
DBUG_RETURN(FALSE);
}
+ mysql_mutex_lock(&acl_cache->lock);
+
/* check for matching WITH PROXY rights */
for (uint i=0; i < acl_proxy_users.elements; i++)
{
@@ -7338,10 +7340,12 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user,
proxy->get_with_grant())
{
DBUG_PRINT("info", ("found"));
+ mysql_mutex_unlock(&acl_cache->lock);
DBUG_RETURN(FALSE);
}
}
+ mysql_mutex_unlock(&acl_cache->lock);
my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0),
thd->security_ctx->user,
thd->security_ctx->host_or_ip);
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 640ee5d1ec9..52e059b5ef8 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1999,7 +1999,7 @@ public:
*/
MDL_request grl_protection;
- Delayed_insert()
+ Delayed_insert(SELECT_LEX *current_select)
:locks_in_memory(0), table(0),tables_in_use(0),stacked_inserts(0),
status(0), handler_thread_initialized(FALSE), group_count(0)
{
@@ -2009,7 +2009,7 @@ public:
strmake_buf(thd.security_ctx->priv_user, thd.security_ctx->user);
thd.current_tablenr=0;
thd.command=COM_DELAYED_INSERT;
- thd.lex->current_select= 0; // for my_message_sql
+ thd.lex->current_select= current_select;
thd.lex->sql_command= SQLCOM_INSERT; // For innodb::store_lock()
/*
Prevent changes to global.lock_wait_timeout from affecting
@@ -2186,7 +2186,7 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request,
*/
if (! (di= find_handler(thd, table_list)))
{
- if (!(di= new Delayed_insert()))
+ if (!(di= new Delayed_insert(thd->lex->current_select)))
goto end_create;
mysql_mutex_lock(&LOCK_thread_count);
thread_count++;
@@ -2817,6 +2817,16 @@ pthread_handler_t handle_delayed_insert(void *arg)
if (di->open_and_lock_table())
goto err;
+ /*
+ INSERT DELAYED generally expects thd->lex->current_select to be NULL,
+ since this is not an attribute of the current thread. This can lead to
+ problems if the thread that spawned the current one disconnects.
+ current_select will then point to freed memory. But current_select is
+ required to resolve the partition function. So, after fulfilling that
+ requirement, we set the current_select to 0.
+ */
+ thd->lex->current_select= NULL;
+
/* Tell client that the thread is initialized */
mysql_cond_signal(&di->cond_client);
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index c61c9101a36..6727b2a0182 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2002, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2013, Monty Program Ab
+/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
+ Copyright (c) 2008, 2015, 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
@@ -3781,8 +3781,8 @@ Prepared_statement::swap_prepared_statement(Prepared_statement *copy)
swap_variables(LEX_STRING, name, copy->name);
/* Ditto */
swap_variables(char *, db, copy->db);
+ swap_variables(size_t, db_length, copy->db_length);
- DBUG_ASSERT(db_length == copy->db_length);
DBUG_ASSERT(param_count == copy->param_count);
DBUG_ASSERT(thd == copy->thd);
last_error[0]= '\0';
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index 914b9026014..b9328addc6a 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
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
@@ -26,6 +26,7 @@
#include "sql_repl.h" // reset_master, reset_slave
#include "rpl_mi.h" // Master_info::data_lock
#include "debug_sync.h"
+#include "des_key_file.h"
static void disable_checkpoints(THD *thd);
@@ -301,7 +302,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long options,
}
}
#endif
-#ifdef OPENSSL
+#ifdef HAVE_OPENSSL
if (options & REFRESH_DES_KEY_FILE)
{
if (des_key_file && load_des_key_file(des_key_file))
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ef1b5b0014e..1b1464049df 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -4114,6 +4114,17 @@ add_key_field(JOIN *join,
Field *field, bool eq_func, Item **value, uint num_values,
table_map usable_tables, SARGABLE_PARAM **sargables)
{
+ if (field->table->reginfo.join_tab == NULL)
+ {
+ /*
+ Due to a bug in IN-to-EXISTS (grep for real_item() in item_subselect.cc
+ for more info), an index over a field from an outer query might be
+ considered here, which is incorrect. Their query has been fully
+ optimized already so their reginfo.join_tab is NULL and we reject them.
+ */
+ return;
+ }
+
uint optimize= 0;
if (eq_func &&
((join->is_allowed_hash_join_access() &&
@@ -14904,8 +14915,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
uint temp_pool_slot=MY_BIT_NONE;
uint fieldnr= 0;
ulong reclength, string_total_length;
- bool using_unique_constraint= 0;
- bool use_packed_rows= 0;
+ bool using_unique_constraint= false;
+ bool use_packed_rows= false;
bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
char *tmpname,path[FN_REFLEN];
uchar *pos, *group_buff, *bitmaps;
@@ -14979,10 +14990,10 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
*/
(*tmp->item)->marker=4; // Store null in key
if ((*tmp->item)->too_big_for_varchar())
- using_unique_constraint=1;
+ using_unique_constraint= true;
}
if (param->group_length >= MAX_BLOB_WIDTH)
- using_unique_constraint=1;
+ using_unique_constraint= true;
if (group)
distinct=0; // Can't use distinct
}
@@ -15236,12 +15247,14 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
*blob_field++= fieldnr;
blob_count++;
}
+
if (new_field->real_type() == MYSQL_TYPE_STRING ||
new_field->real_type() == MYSQL_TYPE_VARCHAR)
{
string_count++;
string_total_length+= new_field->pack_length();
}
+
if (item->marker == 4 && item->maybe_null)
{
group_null_items++;
@@ -15294,7 +15307,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
if (group &&
(param->group_parts > table->file->max_key_parts() ||
param->group_length > table->file->max_key_length()))
- using_unique_constraint=1;
+ using_unique_constraint= true;
}
else
{
@@ -15431,7 +15444,9 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
field->real_type() == MYSQL_TYPE_STRING &&
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
recinfo->type= FIELD_SKIP_ENDSPACE;
- else if (field->real_type() == MYSQL_TYPE_VARCHAR)
+ else if (use_packed_rows &&
+ field->real_type() == MYSQL_TYPE_VARCHAR &&
+ length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
recinfo->type= FIELD_VARCHAR;
else
recinfo->type= FIELD_NORMAL;
@@ -16202,7 +16217,10 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
start_recinfo,
share->uniques, &uniquedef,
&create_info,
- HA_CREATE_TMP_TABLE)))
+ HA_CREATE_TMP_TABLE |
+ ((share->db_create_options & HA_OPTION_PACK_RECORD) ?
+ HA_PACK_RECORD : 0)
+ )))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
table->db_stat=0;
diff --git a/sql/table.cc b/sql/table.cc
index f521056aaee..db18214165e 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
Copyright (c) 2008, 2015, MariaDB
This program is free software; you can redistribute it and/or modify
@@ -2445,21 +2445,6 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
outparam->record[1]= outparam->record[0]; // Safety
}
-#ifdef HAVE_valgrind
- /*
- We need this because when we read var-length rows, we are not updating
- bytes after end of varchar
- */
- if (records > 1)
- {
- memcpy(outparam->record[0], share->default_values, share->rec_buff_length);
- memcpy(outparam->record[1], share->default_values, share->null_bytes);
- if (records > 2)
- memcpy(outparam->record[1], share->default_values,
- share->rec_buff_length);
- }
-#endif
-
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
(uint) ((share->fields+1)*
sizeof(Field*)))))