summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-01-20 15:49:48 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-01-20 15:49:48 +0200
commit87a61355e8e499baf7908862711c26aa0225bf32 (patch)
tree7122052c801b5f1ee4a93af2348fad916aa2f86b /sql
parent7ea413ac2d80c7f03d1dbad90ac30ecddd8b2835 (diff)
parentbc43bf3e430c20bc2178e584215bd443054709d6 (diff)
downloadmariadb-git-87a61355e8e499baf7908862711c26aa0225bf32.tar.gz
Merge 10.3 into 10.4
The MDEV-17062 fix in commit c4195305b2a8431f39a4c75cc1c66ba43685f7a0 was omitted.
Diffstat (limited to 'sql')
-rw-r--r--sql/item_func.cc3
-rw-r--r--sql/log.cc3
-rw-r--r--sql/sp.cc2
-rw-r--r--sql/sp_cache.cc2
-rw-r--r--sql/sp_head.cc89
-rw-r--r--sql/sp_head.h33
-rw-r--r--sql/sql_lex.cc10
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_select.cc21
-rw-r--r--sql/sql_show.cc6
-rw-r--r--sql/sql_trigger.cc2
12 files changed, 106 insertions, 69 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc
index e66fe12c57f..f3d7528b68f 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -123,7 +123,8 @@ Item_args::Item_args(THD *thd, const Item_args *other)
arg_count= 0;
return;
}
- memcpy(args, other->args, sizeof(Item*) * arg_count);
+ if (arg_count)
+ memcpy(args, other->args, sizeof(Item*) * arg_count);
}
diff --git a/sql/log.cc b/sql/log.cc
index d7878db6901..af22c4993bb 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -488,6 +488,7 @@ private:
void truncate(my_off_t pos, bool reset_cache=0)
{
DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos));
+ cache_log.error=0;
if (pending())
{
delete pending();
@@ -496,7 +497,7 @@ private:
reinit_io_cache(&cache_log, WRITE_CACHE, pos, 0, reset_cache);
cache_log.end_of_file= saved_max_binlog_cache_size;
}
-
+
binlog_cache_data& operator=(const binlog_cache_data& info);
binlog_cache_data(const binlog_cache_data& info);
};
diff --git a/sql/sp.cc b/sql/sp.cc
index 751e4644da0..e8611159df0 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -855,7 +855,7 @@ static sp_head *sp_compile(THD *thd, String *defstr, sql_mode_t sql_mode,
if (parse_sql(thd, & parser_state, creation_ctx) || thd->lex == NULL)
{
sp= thd->lex->sphead;
- delete sp;
+ sp_head::destroy(sp);
sp= 0;
}
else
diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc
index 99e68cd2595..e4ffbdcb155 100644
--- a/sql/sp_cache.cc
+++ b/sql/sp_cache.cc
@@ -283,7 +283,7 @@ uchar *hash_get_key_for_sp_head(const uchar *ptr, size_t *plen,
void hash_free_sp_head(void *p)
{
sp_head *sp= (sp_head *)p;
- delete sp;
+ sp_head::destroy(sp);
}
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index eb3c35a4492..6f1b720806c 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2002, 2016, Oracle and/or its affiliates.
- Copyright (c) 2011, 2017, MariaDB
+ Copyright (c) 2011, 2020, 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
@@ -451,49 +451,47 @@ check_routine_name(const LEX_CSTRING *ident)
* sp_head
*
*/
-
-void *
-sp_head::operator new(size_t size) throw()
+
+sp_head *sp_head::create(sp_package *parent, const Sp_handler *handler,
+ enum_sp_aggregate_type agg_type)
{
- DBUG_ENTER("sp_head::operator new");
MEM_ROOT own_root;
+ init_sql_alloc(&own_root, "sp_head", MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC,
+ MYF(0));
sp_head *sp;
+ if (!(sp= new (&own_root) sp_head(&own_root, parent, handler, agg_type)))
+ free_root(&own_root, MYF(0));
- init_sql_alloc(&own_root, "sp_head",
- MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC, MYF(0));
- sp= (sp_head *) alloc_root(&own_root, size);
- if (sp == NULL)
- DBUG_RETURN(NULL);
- sp->main_mem_root= own_root;
- DBUG_PRINT("info", ("mem_root %p", &sp->mem_root));
- DBUG_RETURN(sp);
+ return sp;
}
-void
-sp_head::operator delete(void *ptr, size_t size) throw()
-{
- DBUG_ENTER("sp_head::operator delete");
- MEM_ROOT own_root;
- if (ptr == NULL)
- DBUG_VOID_RETURN;
-
- sp_head *sp= (sp_head *) ptr;
-
- /* Make a copy of main_mem_root as free_root will free the sp */
- own_root= sp->main_mem_root;
- DBUG_PRINT("info", ("mem_root %p moved to %p",
- &sp->mem_root, &own_root));
- free_root(&own_root, MYF(0));
-
- DBUG_VOID_RETURN;
+void sp_head::destroy(sp_head *sp)
+{
+ if (sp)
+ {
+ /* Make a copy of main_mem_root as free_root will free the sp */
+ MEM_ROOT own_root= sp->main_mem_root;
+ DBUG_PRINT("info", ("mem_root %p moved to %p",
+ &sp->mem_root, &own_root));
+ delete sp;
+
+
+ free_root(&own_root, MYF(0));
+ }
}
+/*
+ *
+ * sp_head
+ *
+ */
-sp_head::sp_head(sp_package *parent, const Sp_handler *sph,
- enum_sp_aggregate_type agg_type)
- :Query_arena(&main_mem_root, STMT_INITIALIZED_FOR_SP),
+sp_head::sp_head(MEM_ROOT *mem_root_arg, sp_package *parent,
+ const Sp_handler *sph, enum_sp_aggregate_type agg_type)
+ :Query_arena(NULL, STMT_INITIALIZED_FOR_SP),
Database_qualified_name(&null_clex_str, &null_clex_str),
+ main_mem_root(*mem_root_arg),
m_parent(parent),
m_handler(sph),
m_flags(0),
@@ -524,6 +522,8 @@ sp_head::sp_head(sp_package *parent, const Sp_handler *sph,
m_pcont(new (&main_mem_root) sp_pcontext()),
m_cont_level(0)
{
+ mem_root= &main_mem_root;
+
set_chistics_agg_type(agg_type);
m_first_instance= this;
m_first_free_instance= this;
@@ -548,10 +548,25 @@ sp_head::sp_head(sp_package *parent, const Sp_handler *sph,
}
-sp_package::sp_package(LEX *top_level_lex,
+sp_package *sp_package::create(LEX *top_level_lex, const sp_name *name,
+ const Sp_handler *sph)
+{
+ MEM_ROOT own_root;
+ init_sql_alloc(&own_root, "sp_package", MEM_ROOT_BLOCK_SIZE,
+ MEM_ROOT_PREALLOC, MYF(0));
+ sp_package *sp;
+ if (!(sp= new (&own_root) sp_package(&own_root, top_level_lex, name, sph)))
+ free_root(&own_root, MYF(0));
+
+ return sp;
+}
+
+
+sp_package::sp_package(MEM_ROOT *mem_root_arg,
+ LEX *top_level_lex,
const sp_name *name,
const Sp_handler *sph)
- :sp_head(NULL, sph, DEFAULT_AGGREGATE),
+ :sp_head(mem_root_arg, NULL, sph, DEFAULT_AGGREGATE),
m_current_routine(NULL),
m_top_level_lex(top_level_lex),
m_rcontext(NULL),
@@ -569,7 +584,7 @@ sp_package::~sp_package()
m_routine_declarations.cleanup();
m_body= null_clex_str;
if (m_current_routine)
- delete m_current_routine->sphead;
+ sp_head::destroy(m_current_routine->sphead);
delete m_rcontext;
}
@@ -826,7 +841,7 @@ sp_head::~sp_head()
my_hash_free(&m_sptabs);
my_hash_free(&m_sroutines);
- delete m_next_cached_sp;
+ sp_head::destroy(m_next_cached_sp);
DBUG_VOID_RETURN;
}
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 3085c248924..6cf4610c466 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -1,6 +1,7 @@
/* -*- C++ -*- */
/*
Copyright (c) 2002, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2020, 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
@@ -124,10 +125,11 @@ bool
check_routine_name(const LEX_CSTRING *ident);
class sp_head :private Query_arena,
- public Database_qualified_name
+ public Database_qualified_name,
+ public Sql_alloc
{
- sp_head(const sp_head &); /**< Prevent use of these */
- void operator=(sp_head &);
+ sp_head(const sp_head &)= delete;
+ void operator=(sp_head &)= delete;
protected:
MEM_ROOT main_mem_root;
@@ -318,14 +320,14 @@ public:
*/
SQL_I_List<Item_trigger_field> m_trg_table_fields;
- static void *
- operator new(size_t size) throw ();
-
- static void
- operator delete(void *ptr, size_t size) throw ();
-
- sp_head(sp_package *parent, const Sp_handler *handler,
- enum_sp_aggregate_type);
+protected:
+ sp_head(MEM_ROOT *mem_root, sp_package *parent, const Sp_handler *handler,
+ enum_sp_aggregate_type agg_type);
+ virtual ~sp_head();
+public:
+ static void destroy(sp_head *sp);
+ static sp_head *create(sp_package *parent, const Sp_handler *handler,
+ enum_sp_aggregate_type agg_type);
/// Initialize after we have reset mem_root
void
@@ -343,7 +345,6 @@ public:
void
set_stmt_end(THD *thd);
- virtual ~sp_head();
bool
execute_trigger(THD *thd,
@@ -968,10 +969,16 @@ public:
bool m_is_instantiated;
bool m_is_cloning_routine;
- sp_package(LEX *top_level_lex,
+private:
+ sp_package(MEM_ROOT *mem_root,
+ LEX *top_level_lex,
const sp_name *name,
const Sp_handler *sph);
~sp_package();
+public:
+ static sp_package *create(LEX *top_level_lex, const sp_name *name,
+ const Sp_handler *sph);
+
bool add_routine_declaration(LEX *lex)
{
return m_routine_declarations.check_dup_qualified(lex->sphead) ||
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 6539b1e471f..33bc8eef651 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -815,7 +815,7 @@ void lex_end_stage1(LEX *lex)
}
else
{
- delete lex->sphead;
+ sp_head::destroy(lex->sphead);
lex->sphead= NULL;
}
@@ -3130,13 +3130,13 @@ void LEX::cleanup_lex_after_parse_error(THD *thd)
DBUG_ASSERT(pkg == pkg->m_top_level_lex->sphead);
pkg->restore_thd_mem_root(thd);
LEX *top= pkg->m_top_level_lex;
- delete pkg;
+ sp_package::destroy(pkg);
thd->lex= top;
thd->lex->sphead= NULL;
}
else
{
- delete thd->lex->sphead;
+ sp_head::destroy(thd->lex->sphead);
thd->lex->sphead= NULL;
}
}
@@ -6515,7 +6515,7 @@ sp_head *LEX::make_sp_head(THD *thd, const sp_name *name,
sp_head *sp;
/* Order is important here: new - reset - init */
- if (likely((sp= new sp_head(package, sph, agg_type))))
+ if (likely((sp= sp_head::create(package, sph, agg_type))))
{
sp->reset_thd_mem_root(thd);
sp->init(this);
@@ -8411,7 +8411,7 @@ sp_package *LEX::create_package_start(THD *thd,
return 0;
}
}
- if (unlikely(!(pkg= new sp_package(this, name_arg, sph))))
+ if (unlikely(!(pkg= sp_package::create(this, name_arg, sph))))
return NULL;
pkg->reset_thd_mem_root(thd);
pkg->init(this);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d89cae39330..2c74f15aa17 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5176,7 +5176,7 @@ mysql_execute_command(THD *thd)
/* Don't do it, if we are inside a SP */
if (!thd->spcont)
{
- delete lex->sphead;
+ sp_head::destroy(lex->sphead);
lex->sphead= NULL;
}
/* lex->unit.cleanup() is called outside, no need to call it here */
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 5bf4e0a9c2f..3f8a9df1efe 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -3868,7 +3868,7 @@ Prepared_statement::~Prepared_statement()
free_items();
if (lex)
{
- delete lex->sphead;
+ sp_head::destroy(lex->sphead);
delete lex->result;
delete (st_lex_local *) lex;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 0e0c5c94387..7914a7165a2 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -11596,6 +11596,13 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
if (i != join->const_tables && tab->use_quick != 2 &&
!tab->first_inner)
{ /* Read with cache */
+ /*
+ TODO: the execution also gets here when we will not be using
+ join buffer. Review these cases and perhaps, remove this call.
+ (The final decision whether to use join buffer is made in
+ check_join_cache_usage, so we should only call make_scan_filter()
+ there, too).
+ */
if (tab->make_scan_filter())
DBUG_RETURN(1);
}
@@ -12572,6 +12579,9 @@ uint check_join_cache_usage(JOIN_TAB *tab,
if ((tab->cache= new (root) JOIN_CACHE_BNL(join, tab, prev_cache)))
{
tab->icp_other_tables_ok= FALSE;
+ /* If make_join_select() hasn't called make_scan_filter(), do it now */
+ if (!tab->cache_select && tab->make_scan_filter())
+ goto no_join_cache;
return (2 - MY_TEST(!prev_cache));
}
goto no_join_cache;
@@ -15245,12 +15255,15 @@ static int compare_fields_by_table_order(Item *field1,
{
int cmp= 0;
bool outer_ref= 0;
- Item_field *f1= (Item_field *) (field1->real_item());
- Item_field *f2= (Item_field *) (field2->real_item());
- if (field1->const_item() || f1->const_item())
+ Item *field1_real= field1->real_item();
+ Item *field2_real= field2->real_item();
+
+ if (field1->const_item() || field1_real->const_item())
return -1;
- if (field2->const_item() || f2->const_item())
+ if (field2->const_item() || field2_real->const_item())
return 1;
+ Item_field *f1= (Item_field *) field1_real;
+ Item_field *f2= (Item_field *) field2_real;
if (f1->used_tables() & OUTER_REF_TABLE_BIT)
{
outer_ref= 1;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 03de557b400..0f9537ff704 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -6367,7 +6367,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
{
free_table_share(&share);
if (free_sp_head)
- delete sp;
+ sp_head::destroy(sp);
DBUG_RETURN(1);
}
}
@@ -6414,7 +6414,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
}
}
if (free_sp_head)
- delete sp;
+ sp_head::destroy(sp);
}
free_table_share(&share);
DBUG_RETURN(error);
@@ -6492,7 +6492,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
store_column_type(table, field, cs, 5);
free_table_share(&share);
if (free_sp_head)
- delete sp;
+ sp_head::destroy(sp);
}
}
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index f9b9e4dd4f1..5802d2c811e 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -329,7 +329,7 @@ public:
Trigger::~Trigger()
{
- delete body;
+ sp_head::destroy(body);
}