summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2018-05-05 14:01:59 +0200
committerSergei Golubchik <serg@mariadb.org>2018-05-05 14:01:59 +0200
commit9989c26bc99c90d3047a7b3e20e0800b62f62300 (patch)
tree0a2b04288168bf08530568c94c326f2e9a98a397 /sql
parent39d248fa555350756a569d766f11eec4c65c5b16 (diff)
parent3c07ed141c2ed885dea13fbce8603afce6250590 (diff)
downloadmariadb-git-9989c26bc99c90d3047a7b3e20e0800b62f62300.tar.gz
Merge branch '10.0' into 10.1
Diffstat (limited to 'sql')
-rw-r--r--sql/item.cc10
-rw-r--r--sql/item.h1
-rw-r--r--sql/item_cmpfunc.cc42
-rw-r--r--sql/item_func.cc3
-rw-r--r--sql/item_func.h8
-rw-r--r--sql/item_row.cc1
-rw-r--r--sql/item_sum.cc3
-rw-r--r--sql/opt_subselect.cc26
-rw-r--r--sql/sql_acl.cc1
-rw-r--r--sql/sql_base.cc3
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_select.cc6
12 files changed, 80 insertions, 28 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 1d0ed6a6ea5..00d812cb3d7 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -472,7 +472,9 @@ Item::Item(THD *thd):
maybe_null=null_value=with_sum_func=with_field=0;
in_rollup= 0;
with_subselect= 0;
- /* Initially this item is not attached to any JOIN_TAB. */
+ with_param= 0;
+
+ /* Initially this item is not attached to any JOIN_TAB. */
join_tab_idx= MAX_TABLES;
/* Put item in free list so that we can free all items at end */
@@ -514,6 +516,7 @@ Item::Item(THD *thd, Item *item):
in_rollup(item->in_rollup),
null_value(item->null_value),
with_sum_func(item->with_sum_func),
+ with_param(item->with_param),
with_field(item->with_field),
fixed(item->fixed),
is_autogenerated_name(item->is_autogenerated_name),
@@ -1423,6 +1426,9 @@ bool Item_sp_variable::fix_fields(THD *thd, Item **)
max_length= it->max_length;
decimals= it->decimals;
unsigned_flag= it->unsigned_flag;
+ with_param= 1;
+ if (thd->lex->current_select->master_unit()->item)
+ thd->lex->current_select->master_unit()->item->with_param= 1;
fixed= 1;
collation.set(it->collation.collation, it->collation.derivation);
@@ -7178,6 +7184,7 @@ void Item_ref::set_properties()
split_sum_func() doesn't try to change the reference.
*/
with_sum_func= (*ref)->with_sum_func;
+ with_param= (*ref)->with_param;
with_field= (*ref)->with_field;
fixed= 1;
if (alias_name_used)
@@ -7603,6 +7610,7 @@ Item_cache_wrapper::Item_cache_wrapper(THD *thd, Item *item_arg):
Type_std_attributes::set(orig_item);
maybe_null= orig_item->maybe_null;
with_sum_func= orig_item->with_sum_func;
+ with_param= orig_item->with_param;
with_field= orig_item->with_field;
name= item_arg->name;
name_length= item_arg->name_length;
diff --git a/sql/item.h b/sql/item.h
index a9b8006cdf3..60073f054c9 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -694,6 +694,7 @@ public:
of a query with ROLLUP */
bool null_value; /* if item is null */
bool with_sum_func; /* True if item contains a sum func */
+ bool with_param; /* True if contains an SP parameter */
/**
True if any item except Item_sum contains a field. Set during parsing.
*/
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 4e2e5bd4cac..6ffd582c133 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1358,6 +1358,7 @@ bool Item_in_optimizer::fix_left(THD *thd)
}
eval_not_null_tables(NULL);
with_sum_func= args[0]->with_sum_func;
+ with_param= args[0]->with_param || args[1]->with_param;
with_field= args[0]->with_field;
if ((const_item_cache= args[0]->const_item()))
{
@@ -1406,6 +1407,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
with_subselect= 1;
with_sum_func= with_sum_func || args[1]->with_sum_func;
with_field= with_field || args[1]->with_field;
+ with_param= args[0]->with_param || args[1]->with_param;
used_tables_and_const_cache_join(args[1]);
fixed= 1;
return FALSE;
@@ -1955,6 +1957,7 @@ void Item_func_interval::fix_length_and_dec()
used_tables_and_const_cache_join(row);
not_null_tables_cache= row->not_null_tables();
with_sum_func= with_sum_func || row->with_sum_func;
+ with_param= with_param || row->with_param;
with_field= with_field || row->with_field;
}
@@ -4573,6 +4576,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
List_iterator<Item> li(list);
Item *item;
uchar buff[sizeof(char*)]; // Max local vars in function
+ bool is_and_cond= functype() == Item_func::COND_AND_FUNC;
not_null_tables_cache= 0;
used_tables_and_const_cache_init();
@@ -4635,26 +4639,33 @@ Item_cond::fix_fields(THD *thd, Item **ref)
(item= *li.ref())->check_cols(1))
return TRUE; /* purecov: inspected */
used_tables_cache|= item->used_tables();
- if (item->const_item())
+ if (item->const_item() && !item->with_param &&
+ !item->is_expensive() && !cond_has_datetime_is_null(item))
{
- if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
- item->val_int() == 0)
+ if (item->val_int() == is_and_cond && top_level())
{
/*
- This is "... OR false_cond OR ..."
+ a. This is "... AND true_cond AND ..."
+ In this case, true_cond has no effect on cond_and->not_null_tables()
+ b. This is "... OR false_cond/null cond OR ..."
In this case, false_cond has no effect on cond_or->not_null_tables()
*/
}
else
{
/*
- This is "... OR const_cond OR ..."
+ a. This is "... AND false_cond/null_cond AND ..."
+ The whole condition is FALSE/UNKNOWN.
+ b. This is "... OR const_cond OR ..."
In this case, cond_or->not_null_tables()=0, because the condition
const_cond might evaluate to true (regardless of whether some tables
were NULL-complemented).
*/
+ not_null_tables_cache= (table_map) 0;
and_tables_cache= (table_map) 0;
}
+ if (thd->is_error())
+ return TRUE;
}
else
{
@@ -4666,6 +4677,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
}
with_sum_func= with_sum_func || item->with_sum_func;
+ with_param= with_param || item->with_param;
with_field= with_field || item->with_field;
with_subselect|= item->has_subquery();
if (item->maybe_null)
@@ -4681,30 +4693,36 @@ bool
Item_cond::eval_not_null_tables(uchar *opt_arg)
{
Item *item;
+ bool is_and_cond= functype() == Item_func::COND_AND_FUNC;
List_iterator<Item> li(list);
not_null_tables_cache= (table_map) 0;
and_tables_cache= ~(table_map) 0;
while ((item=li++))
{
table_map tmp_table_map;
- if (item->const_item())
+ if (item->const_item() && !item->with_param &&
+ !item->is_expensive() && !cond_has_datetime_is_null(item))
{
- if (!item->is_expensive() && !cond_has_datetime_is_null(item) &&
- item->val_int() == 0)
+ if (item->val_int() == is_and_cond && top_level())
{
/*
- This is "... OR false_cond OR ..."
+ a. This is "... AND true_cond AND ..."
+ In this case, true_cond has no effect on cond_and->not_null_tables()
+ b. This is "... OR false_cond/null cond OR ..."
In this case, false_cond has no effect on cond_or->not_null_tables()
*/
}
else
{
/*
- This is "... OR const_cond OR ..."
+ a. This is "... AND false_cond/null_cond AND ..."
+ The whole condition is FALSE/UNKNOWN.
+ b. This is "... OR const_cond OR ..."
In this case, cond_or->not_null_tables()=0, because the condition
- some_cond_or might be true regardless of what tables are
- NULL-complemented.
+ const_cond might evaluate to true (regardless of whether some tables
+ were NULL-complemented).
*/
+ not_null_tables_cache= (table_map) 0;
and_tables_cache= (table_map) 0;
}
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 0700d71a396..05a34a9a24a 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -133,6 +133,7 @@ void Item_func::sync_with_sum_func_and_with_field(List<Item> &list)
{
with_sum_func|= item->with_sum_func;
with_field|= item->with_field;
+ with_param|= item->with_param;
}
}
@@ -226,6 +227,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
maybe_null=1;
with_sum_func= with_sum_func || item->with_sum_func;
+ with_param= with_param || item->with_param;
with_field= with_field || item->with_field;
used_tables_and_const_cache_join(item);
with_subselect|= item->has_subquery();
@@ -3506,6 +3508,7 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
func->maybe_null=1;
func->with_sum_func= func->with_sum_func || item->with_sum_func;
func->with_field= func->with_field || item->with_field;
+ func->with_param= func->with_param || item->with_param;
func->with_subselect|= item->with_subselect;
func->used_tables_and_const_cache_join(item);
f_args.arg_type[i]=item->result_type();
diff --git a/sql/item_func.h b/sql/item_func.h
index 25f96be7962..3219c813821 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -74,16 +74,19 @@ public:
{
with_sum_func= 0;
with_field= 0;
+ with_param= 0;
}
Item_func(THD *thd, Item *a): Item_func_or_sum(thd, a), allowed_arg_cols(1)
{
with_sum_func= a->with_sum_func;
+ with_param= a->with_param;
with_field= a->with_field;
}
Item_func(THD *thd, Item *a, Item *b):
Item_func_or_sum(thd, a, b), allowed_arg_cols(1)
{
with_sum_func= a->with_sum_func || b->with_sum_func;
+ with_param= a->with_param || b->with_param;
with_field= a->with_field || b->with_field;
}
Item_func(THD *thd, Item *a, Item *b, Item *c):
@@ -91,6 +94,7 @@ public:
{
with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func;
with_field= a->with_field || b->with_field || c->with_field;
+ with_param= a->with_param || b->with_param || c->with_param;
}
Item_func(THD *thd, Item *a, Item *b, Item *c, Item *d):
Item_func_or_sum(thd, a, b, c, d), allowed_arg_cols(1)
@@ -99,6 +103,8 @@ public:
c->with_sum_func || d->with_sum_func;
with_field= a->with_field || b->with_field ||
c->with_field || d->with_field;
+ with_param= a->with_param || b->with_param ||
+ c->with_param || d->with_param;
}
Item_func(THD *thd, Item *a, Item *b, Item *c, Item *d, Item* e):
Item_func_or_sum(thd, a, b, c, d, e), allowed_arg_cols(1)
@@ -107,6 +113,8 @@ public:
c->with_sum_func || d->with_sum_func || e->with_sum_func;
with_field= a->with_field || b->with_field ||
c->with_field || d->with_field || e->with_field;
+ with_param= a->with_param || b->with_param ||
+ c->with_param || d->with_param || e->with_param;
}
Item_func(THD *thd, List<Item> &list):
Item_func_or_sum(thd, list), allowed_arg_cols(1)
diff --git a/sql/item_row.cc b/sql/item_row.cc
index 97f75c4b4cf..8c6edacad7f 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -64,6 +64,7 @@ bool Item_row::fix_fields(THD *thd, Item **ref)
with_sum_func= with_sum_func || item->with_sum_func;
with_field= with_field || item->with_field;
with_subselect|= item->with_subselect;
+ with_param|= item->with_param;
}
fixed= 1;
return FALSE;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 0e2e9f0795d..b4e31ba012f 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1159,6 +1159,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
return TRUE;
set_if_bigger(decimals, args[i]->decimals);
with_subselect|= args[i]->with_subselect;
+ with_param|= args[i]->with_param;
}
result_field=0;
max_length=float_length(decimals);
@@ -1190,6 +1191,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
return TRUE;
Type_std_attributes::set(args[0]);
with_subselect= args[0]->with_subselect;
+ with_param= args[0]->with_param;
Item *item2= item->real_item();
if (item2->type() == Item::FIELD_ITEM)
@@ -3361,6 +3363,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref)
args[i]->check_cols(1))
return TRUE;
with_subselect|= args[i]->with_subselect;
+ with_param|= args[i]->with_param;
}
/* skip charset aggregation for order columns */
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 05cc8db057a..89338928cb5 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -3744,22 +3744,30 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
sjm= emb_sj_nest->sj_mat_info;
thd= tab->join->thd;
/* First the calls come to the materialization function */
- //List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
-
+
DBUG_ASSERT(sjm->is_used);
/*
Set up the table to write to, do as select_union::create_result_table does
*/
sjm->sjm_table_param.init();
sjm->sjm_table_param.bit_fields_as_long= TRUE;
- //List_iterator<Item> it(item_list);
SELECT_LEX *subq_select= emb_sj_nest->sj_subq_pred->unit->first_select();
- Item **p_item= subq_select->ref_pointer_array;
- Item **p_end= p_item + subq_select->item_list.elements;
- //while((right_expr= it++))
- for(;p_item != p_end; p_item++)
- sjm->sjm_table_cols.push_back(*p_item, thd->mem_root);
-
+ List_iterator<Item> it(subq_select->item_list);
+ Item *item;
+ while((item= it++))
+ {
+ /*
+ This semi-join replaced the subquery (subq_select) and so on
+ re-executing it will not be prepared. To use the Items from its
+ select list we have to prepare (fix_fields) them
+ */
+ if (!item->fixed && item->fix_fields(thd, it.ref()))
+ DBUG_RETURN(TRUE);
+ item= *(it.ref()); // it can be changed by fix_fields
+ DBUG_ASSERT(!item->name_length || item->name_length == strlen(item->name));
+ sjm->sjm_table_cols.push_back(item, thd->mem_root);
+ }
+
sjm->sjm_table_param.field_count= subq_select->item_list.elements;
sjm->sjm_table_param.force_not_null_cols= TRUE;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index ce139280c5d..a5c91b49951 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -11475,6 +11475,7 @@ static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
const char *client_auth_plugin=
((st_mysql_auth *) (plugin_decl(mpvio->plugin)->info))->client_auth_plugin;
+ DBUG_EXECUTE_IF("auth_disconnect", { vio_close(net->vio); DBUG_RETURN(1); });
DBUG_ASSERT(client_auth_plugin);
/*
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index a5208ef29a5..8472117510b 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -995,10 +995,7 @@ 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,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 5c03999c9ac..3d40f8e4245 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5722,6 +5722,10 @@ finish:
lex->unit.cleanup();
+ /* close/reopen tables that were marked to need reopen under LOCK TABLES */
+ if (! thd->lex->requires_prelocking())
+ thd->locked_tables_list.reopen_tables(thd, true);
+
if (! thd->in_sub_stmt)
{
if (thd->killed != NOT_KILLED)
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 067c71205d0..e56f301af86 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1148,9 +1148,6 @@ JOIN::optimize_inner()
eval_select_list_used_tables();
- if (optimize_constant_subqueries())
- DBUG_RETURN(1);
-
table_count= select_lex->leaf_tables.elements;
if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
@@ -1212,6 +1209,9 @@ JOIN::optimize_inner()
thd->restore_active_arena(arena, &backup);
}
+ if (optimize_constant_subqueries())
+ DBUG_RETURN(1);
+
if (setup_jtbm_semi_joins(this, join_list, &conds))
DBUG_RETURN(1);