MDEV-33971 NAME_CONST in WHERE clause replaced by inner item
Improve performance of queries like SELECT * FROM t1 WHERE field = NAME_CONST('a', 4); by, in this example, replacing the WHERE clause with field = 4 in the case of ref access. The rewrite is done during fix_fields and we disambiguate this case from other cases of NAME_CONST by inspecting where we are in parsing. We rely on THD::where to accomplish this. To improve performance there, we change the type of THD::where to be an enumeration, so we can avoid string comparisons during Item_name_const::fix_fields. Consequently, this patch also changes all usages of THD::where to conform likewise.
This commit is contained in:
parent
a0a7b1c128
commit
02e38e2ece
@ -126,7 +126,7 @@ group by
|
|||||||
a.text, b.id, b.betreff
|
a.text, b.id, b.betreff
|
||||||
order by
|
order by
|
||||||
match(b.betreff) against ('+abc' in boolean mode) desc;
|
match(b.betreff) against ('+abc' in boolean mode) desc;
|
||||||
ERROR 42000: Table 'b' from one of the SELECTs cannot be used in ORDER clause
|
ERROR 42000: Table 'b' from one of the SELECTs cannot be used in order clause
|
||||||
select a.text, b.id, b.betreff
|
select a.text, b.id, b.betreff
|
||||||
from
|
from
|
||||||
t2 a inner join t3 b on a.id = b.forum inner join
|
t2 a inner join t3 b on a.id = b.forum inner join
|
||||||
@ -142,7 +142,7 @@ where
|
|||||||
match(c.beitrag) against ('+abc' in boolean mode)
|
match(c.beitrag) against ('+abc' in boolean mode)
|
||||||
order by
|
order by
|
||||||
match(b.betreff) against ('+abc' in boolean mode) desc;
|
match(b.betreff) against ('+abc' in boolean mode) desc;
|
||||||
ERROR 42000: Table 'b' from one of the SELECTs cannot be used in ORDER clause
|
ERROR 42000: Table 'b' from one of the SELECTs cannot be used in order clause
|
||||||
select a.text, b.id, b.betreff
|
select a.text, b.id, b.betreff
|
||||||
from
|
from
|
||||||
t2 a inner join t3 b on a.id = b.forum inner join
|
t2 a inner join t3 b on a.id = b.forum inner join
|
||||||
|
87
mysql-test/main/name_const_replacement.result
Normal file
87
mysql-test/main/name_const_replacement.result
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
create table t1 (a int, b int);
|
||||||
|
insert into t1 values (1,1),(2,2);
|
||||||
|
explain format=json
|
||||||
|
select * from t1 where a=name_const('varname',1);
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "ALL",
|
||||||
|
"rows": 2,
|
||||||
|
"filtered": 100,
|
||||||
|
"attached_condition": "t1.a = 1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
explain format=json
|
||||||
|
select * from t1 left join t1 as t2 on t1.a=name_const('varname',1) and t1.b=t2.b;
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"const_condition": "1",
|
||||||
|
"table": {
|
||||||
|
"table_name": "t1",
|
||||||
|
"access_type": "ALL",
|
||||||
|
"rows": 2,
|
||||||
|
"filtered": 100
|
||||||
|
},
|
||||||
|
"block-nl-join": {
|
||||||
|
"table": {
|
||||||
|
"table_name": "t2",
|
||||||
|
"access_type": "ALL",
|
||||||
|
"rows": 2,
|
||||||
|
"filtered": 100
|
||||||
|
},
|
||||||
|
"buffer_type": "flat",
|
||||||
|
"buffer_size": "141",
|
||||||
|
"join_type": "BNL",
|
||||||
|
"attached_condition": "trigcond(t2.b = t1.b and trigcond(t1.a = 1))"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
create table t2 (
|
||||||
|
a varchar(100) collate utf8_unicode_ci,
|
||||||
|
b int
|
||||||
|
);
|
||||||
|
insert into t2 values ('foo', 1),('bar', 1);
|
||||||
|
create procedure p1(var1 varchar(10))
|
||||||
|
update t2 set b=b+1 where a=var1;
|
||||||
|
call p1('foo');
|
||||||
|
call p1('foo');
|
||||||
|
call p1('foo');
|
||||||
|
select * from t2;
|
||||||
|
a b
|
||||||
|
foo 4
|
||||||
|
bar 1
|
||||||
|
create table t3 (
|
||||||
|
a varchar(100) collate utf8_unicode_ci,
|
||||||
|
b int
|
||||||
|
);
|
||||||
|
insert into t3 values ('foo', 1),('bar', 1);
|
||||||
|
select * from t3;
|
||||||
|
a b
|
||||||
|
foo 1
|
||||||
|
bar 1
|
||||||
|
explain format=json
|
||||||
|
update t3 set b=b+1 where a= NAME_CONST('var1',_latin1'foo' COLLATE 'latin1_swedish_ci');
|
||||||
|
EXPLAIN
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"table": {
|
||||||
|
"update": 1,
|
||||||
|
"table_name": "t3",
|
||||||
|
"access_type": "ALL",
|
||||||
|
"rows": 2,
|
||||||
|
"attached_condition": "t3.a = convert(_latin1'foo' collate latin1_swedish_ci using utf8mb3)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select * from t3 where a= NAME_CONST('var1',_latin1'foo' COLLATE 'latin1_swedish_ci');
|
||||||
|
a b
|
||||||
|
foo 1
|
||||||
|
drop procedure p1;
|
||||||
|
drop table t1, t2, t3;
|
38
mysql-test/main/name_const_replacement.test
Normal file
38
mysql-test/main/name_const_replacement.test
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#
|
||||||
|
# MDEV-33971 Using NAME_CONST() changes the plan
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (a int, b int);
|
||||||
|
insert into t1 values (1,1),(2,2);
|
||||||
|
explain format=json
|
||||||
|
select * from t1 where a=name_const('varname',1);
|
||||||
|
explain format=json
|
||||||
|
select * from t1 left join t1 as t2 on t1.a=name_const('varname',1) and t1.b=t2.b;
|
||||||
|
|
||||||
|
|
||||||
|
create table t2 (
|
||||||
|
a varchar(100) collate utf8_unicode_ci,
|
||||||
|
b int
|
||||||
|
);
|
||||||
|
insert into t2 values ('foo', 1),('bar', 1);
|
||||||
|
create procedure p1(var1 varchar(10))
|
||||||
|
update t2 set b=b+1 where a=var1;
|
||||||
|
call p1('foo');
|
||||||
|
call p1('foo');
|
||||||
|
call p1('foo');
|
||||||
|
select * from t2;
|
||||||
|
|
||||||
|
|
||||||
|
create table t3 (
|
||||||
|
a varchar(100) collate utf8_unicode_ci,
|
||||||
|
b int
|
||||||
|
);
|
||||||
|
insert into t3 values ('foo', 1),('bar', 1);
|
||||||
|
select * from t3;
|
||||||
|
explain format=json
|
||||||
|
update t3 set b=b+1 where a= NAME_CONST('var1',_latin1'foo' COLLATE 'latin1_swedish_ci');
|
||||||
|
select * from t3 where a= NAME_CONST('var1',_latin1'foo' COLLATE 'latin1_swedish_ci');
|
||||||
|
|
||||||
|
|
||||||
|
drop procedure p1;
|
||||||
|
drop table t1, t2, t3;
|
@ -80,7 +80,7 @@ a b
|
|||||||
2 b
|
2 b
|
||||||
1 a
|
1 a
|
||||||
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b;
|
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b;
|
||||||
ERROR 42000: Table 't1' from one of the SELECTs cannot be used in ORDER clause
|
ERROR 42000: Table 't1' from one of the SELECTs cannot be used in order clause
|
||||||
explain extended (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
|
explain extended (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
|
||||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00
|
||||||
@ -493,7 +493,7 @@ drop temporary table t1;
|
|||||||
create table t1 select a from t1 union select a from t2;
|
create table t1 select a from t1 union select a from t2;
|
||||||
ERROR 42S01: Table 't1' already exists
|
ERROR 42S01: Table 't1' already exists
|
||||||
select a from t1 union select a from t2 order by t2.a;
|
select a from t1 union select a from t2 order by t2.a;
|
||||||
ERROR 42000: Table 't2' from one of the SELECTs cannot be used in ORDER clause
|
ERROR 42000: Table 't2' from one of the SELECTs cannot be used in order clause
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
select length(version()) > 1 as `*` UNION select 2;
|
select length(version()) > 1 as `*` UNION select 2;
|
||||||
*
|
*
|
||||||
|
@ -129,7 +129,7 @@ group by
|
|||||||
a.text, b.id, b.betreff
|
a.text, b.id, b.betreff
|
||||||
order by
|
order by
|
||||||
match(b.betreff) against ('+abc' in boolean mode) desc;
|
match(b.betreff) against ('+abc' in boolean mode) desc;
|
||||||
ERROR 42000: Table 'b' from one of the SELECTs cannot be used in ORDER clause
|
ERROR 42000: Table 'b' from one of the SELECTs cannot be used in order clause
|
||||||
select a.text, b.id, b.betreff
|
select a.text, b.id, b.betreff
|
||||||
from
|
from
|
||||||
t2 a inner join t3 b on a.id = b.forum inner join
|
t2 a inner join t3 b on a.id = b.forum inner join
|
||||||
@ -145,7 +145,7 @@ where
|
|||||||
match(c.beitrag) against ('+abc' in boolean mode)
|
match(c.beitrag) against ('+abc' in boolean mode)
|
||||||
order by
|
order by
|
||||||
match(b.betreff) against ('+abc' in boolean mode) desc;
|
match(b.betreff) against ('+abc' in boolean mode) desc;
|
||||||
ERROR 42000: Table 'b' from one of the SELECTs cannot be used in ORDER clause
|
ERROR 42000: Table 'b' from one of the SELECTs cannot be used in order clause
|
||||||
select a.text, b.id, b.betreff
|
select a.text, b.id, b.betreff
|
||||||
from
|
from
|
||||||
t2 a inner join t3 b on a.id = b.forum inner join
|
t2 a inner join t3 b on a.id = b.forum inner join
|
||||||
|
44
sql/item.cc
44
sql/item.cc
@ -2184,6 +2184,36 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref)
|
|||||||
my_error(ER_RESERVED_SYNTAX, MYF(0), "NAME_CONST");
|
my_error(ER_RESERVED_SYNTAX, MYF(0), "NAME_CONST");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
If we have either of the following:
|
||||||
|
... WHERE foo=NAME_CONST(...)
|
||||||
|
... JOIN ... ON foo=NAME_CONST(...)
|
||||||
|
then we have an opportunity to unwrap the NAME_CONST and
|
||||||
|
use the enclosed value directly, replacing NAME_CONST in
|
||||||
|
the parse tree with the value it encloses.
|
||||||
|
*/
|
||||||
|
if ((thd->where == THD_WHERE::WHERE_CLAUSE ||
|
||||||
|
thd->where == THD_WHERE::ON_CLAUSE) &&
|
||||||
|
(value_item->type() == FUNC_ITEM ||
|
||||||
|
value_item->type() == CONST_ITEM))
|
||||||
|
{
|
||||||
|
thd->change_item_tree(ref, value_item);
|
||||||
|
|
||||||
|
/*
|
||||||
|
We're replacing NAME_CONST('name', value_item) with value_item.
|
||||||
|
Only a few constants and functions are possible as value_item, see
|
||||||
|
Create_func_name_const::create_2_arg.
|
||||||
|
Set the value_item's coercibility to be the same as NAME_CONST(...)
|
||||||
|
would have (see how it's set a few lines below).
|
||||||
|
*/
|
||||||
|
if (value_item->collation.derivation != DERIVATION_NUMERIC)
|
||||||
|
value_item->collation.set(value_item->collation.collation,
|
||||||
|
DERIVATION_IMPLICIT);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
// else, could not unwrap, fall back to default handling below.
|
||||||
|
|
||||||
if (value_item->collation.derivation == DERIVATION_NUMERIC)
|
if (value_item->collation.derivation == DERIVATION_NUMERIC)
|
||||||
collation= DTCollation_numeric();
|
collation= DTCollation_numeric();
|
||||||
else
|
else
|
||||||
@ -5528,7 +5558,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
|
|||||||
is ambiguous.
|
is ambiguous.
|
||||||
*/
|
*/
|
||||||
my_error(ER_NON_UNIQ_ERROR, MYF(0),
|
my_error(ER_NON_UNIQ_ERROR, MYF(0),
|
||||||
find_item->full_name(), current_thd->where);
|
find_item->full_name(), thd_where(current_thd));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5613,7 +5643,7 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
|
|||||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||||
ER_NON_UNIQ_ERROR,
|
ER_NON_UNIQ_ERROR,
|
||||||
ER_THD(thd,ER_NON_UNIQ_ERROR), ref->full_name(),
|
ER_THD(thd,ER_NON_UNIQ_ERROR), ref->full_name(),
|
||||||
thd->where);
|
thd_where(thd));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5947,7 +5977,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
|
|||||||
if (upward_lookup)
|
if (upward_lookup)
|
||||||
{
|
{
|
||||||
// We can't say exactly what absent table or field
|
// We can't say exactly what absent table or field
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where);
|
my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd_where(thd));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -6174,7 +6204,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
|||||||
{
|
{
|
||||||
/* The column to which we link isn't valid. */
|
/* The column to which we link isn't valid. */
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0), (*res)->name.str,
|
my_error(ER_BAD_FIELD_ERROR, MYF(0), (*res)->name.str,
|
||||||
thd->where);
|
thd_where(thd));
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6219,7 +6249,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
|||||||
|
|
||||||
if (unlikely(!select))
|
if (unlikely(!select))
|
||||||
{
|
{
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where);
|
my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd_where(thd));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
|
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
|
||||||
@ -8163,7 +8193,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
|
|||||||
if (unlikely(!outer_context))
|
if (unlikely(!outer_context))
|
||||||
{
|
{
|
||||||
/* The current reference cannot be resolved in this query. */
|
/* The current reference cannot be resolved in this query. */
|
||||||
my_error(ER_BAD_FIELD_ERROR,MYF(0), full_name(), thd->where);
|
my_error(ER_BAD_FIELD_ERROR,MYF(0), full_name(), thd_where(thd));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8314,7 +8344,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
|
|||||||
{
|
{
|
||||||
/* The item was not a table field and not a reference */
|
/* The item was not a table field and not a reference */
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
||||||
this->full_name(), thd->where);
|
this->full_name(), thd_where(thd));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
/* Should be checked in resolve_ref_in_select_and_group(). */
|
/* Should be checked in resolve_ref_in_select_and_group(). */
|
||||||
|
@ -241,7 +241,7 @@ Item_subselect::select_transformer(JOIN *join)
|
|||||||
|
|
||||||
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
|
bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
|
||||||
{
|
{
|
||||||
char const *save_where= thd_param->where;
|
THD_WHERE save_where= thd_param->where;
|
||||||
uint8 uncacheable;
|
uint8 uncacheable;
|
||||||
bool res;
|
bool res;
|
||||||
|
|
||||||
@ -320,7 +320,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
|
|||||||
if (have_to_be_excluded)
|
if (have_to_be_excluded)
|
||||||
engine->exclude();
|
engine->exclude();
|
||||||
substitution= 0;
|
substitution= 0;
|
||||||
thd->where= "checking transformed subquery";
|
thd->where= THD_WHERE::CHECKING_TRANSFORMED_SUBQUERY;
|
||||||
res= (*ref)->fix_fields_if_needed(thd, ref);
|
res= (*ref)->fix_fields_if_needed(thd, ref);
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
@ -3403,13 +3403,13 @@ Item_in_subselect::select_in_like_transformer(JOIN *join)
|
|||||||
{
|
{
|
||||||
Query_arena *arena= 0, backup;
|
Query_arena *arena= 0, backup;
|
||||||
SELECT_LEX *current= thd->lex->current_select;
|
SELECT_LEX *current= thd->lex->current_select;
|
||||||
const char *save_where= thd->where;
|
THD_WHERE save_where= thd->where;
|
||||||
bool trans_res= true;
|
bool trans_res= true;
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
|
DBUG_ENTER("Item_in_subselect::select_in_like_transformer");
|
||||||
DBUG_ASSERT(thd == join->thd);
|
DBUG_ASSERT(thd == join->thd);
|
||||||
thd->where= "IN/ALL/ANY subquery";
|
thd->where= THD_WHERE::IN_ALL_ANY_SUBQUERY;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In some optimisation cases we will not need this Item_in_optimizer
|
In some optimisation cases we will not need this Item_in_optimizer
|
||||||
@ -3496,7 +3496,7 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
|
|||||||
{
|
{
|
||||||
uint outer_cols_num;
|
uint outer_cols_num;
|
||||||
List<Item> *inner_cols;
|
List<Item> *inner_cols;
|
||||||
char const *save_where= thd_arg->where;
|
THD_WHERE save_where= thd_arg->where;
|
||||||
DBUG_ENTER("Item_in_subselect::fix_fields");
|
DBUG_ENTER("Item_in_subselect::fix_fields");
|
||||||
|
|
||||||
thd= thd_arg;
|
thd= thd_arg;
|
||||||
@ -3505,7 +3505,7 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
|
|||||||
if (test_strategy(SUBS_SEMI_JOIN))
|
if (test_strategy(SUBS_SEMI_JOIN))
|
||||||
DBUG_RETURN( !( (*ref)= new (thd->mem_root) Item_int(thd, 1)) );
|
DBUG_RETURN( !( (*ref)= new (thd->mem_root) Item_int(thd, 1)) );
|
||||||
|
|
||||||
thd->where= "IN/ALL/ANY subquery";
|
thd->where= THD_WHERE::IN_ALL_ANY_SUBQUERY;
|
||||||
/*
|
/*
|
||||||
Check if the outer and inner IN operands match in those cases when we
|
Check if the outer and inner IN operands match in those cases when we
|
||||||
will not perform IN=>EXISTS transformation. Currently this is when we
|
will not perform IN=>EXISTS transformation. Currently this is when we
|
||||||
@ -4016,7 +4016,7 @@ int join_read_next_same_or_null(READ_RECORD *info);
|
|||||||
|
|
||||||
int subselect_single_select_engine::exec()
|
int subselect_single_select_engine::exec()
|
||||||
{
|
{
|
||||||
char const *save_where= thd->where;
|
THD_WHERE save_where= thd->where;
|
||||||
SELECT_LEX *save_select= thd->lex->current_select;
|
SELECT_LEX *save_select= thd->lex->current_select;
|
||||||
thd->lex->current_select= select_lex;
|
thd->lex->current_select= select_lex;
|
||||||
DBUG_ENTER("subselect_single_select_engine::exec");
|
DBUG_ENTER("subselect_single_select_engine::exec");
|
||||||
@ -4137,7 +4137,7 @@ int subselect_single_select_engine::exec()
|
|||||||
|
|
||||||
int subselect_union_engine::exec()
|
int subselect_union_engine::exec()
|
||||||
{
|
{
|
||||||
char const *save_where= thd->where;
|
THD_WHERE save_where= thd->where;
|
||||||
int res= unit->exec();
|
int res= unit->exec();
|
||||||
thd->where= save_where;
|
thd->where= save_where;
|
||||||
return res;
|
return res;
|
||||||
|
@ -1146,7 +1146,7 @@ bool push_table_function_arg_context(LEX *lex, MEM_ROOT *alloc)
|
|||||||
bool Table_function_json_table::setup(THD *thd, TABLE_LIST *sql_table,
|
bool Table_function_json_table::setup(THD *thd, TABLE_LIST *sql_table,
|
||||||
SELECT_LEX *s_lex)
|
SELECT_LEX *s_lex)
|
||||||
{
|
{
|
||||||
thd->where= "JSON_TABLE argument";
|
thd->where= THD_WHERE::JSON_TABLE_ARGUMENT;
|
||||||
|
|
||||||
if (!m_context_setup_done)
|
if (!m_context_setup_done)
|
||||||
{
|
{
|
||||||
|
@ -638,8 +638,8 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
|
|||||||
{
|
{
|
||||||
SELECT_LEX *current= thd->lex->current_select;
|
SELECT_LEX *current= thd->lex->current_select;
|
||||||
thd->lex->current_select= current->return_after_parsing();
|
thd->lex->current_select= current->return_after_parsing();
|
||||||
char const *save_where= thd->where;
|
THD_WHERE save_where= thd->where;
|
||||||
thd->where= "IN/ALL/ANY subquery";
|
thd->where= THD_WHERE::IN_ALL_ANY_SUBQUERY;
|
||||||
|
|
||||||
Item **left= in_subs->left_exp_ptr();
|
Item **left= in_subs->left_exp_ptr();
|
||||||
bool failure= (*left)->fix_fields_if_needed(thd, left);
|
bool failure= (*left)->fix_fields_if_needed(thd, left);
|
||||||
|
@ -1824,7 +1824,7 @@ bool partition_info::add_column_list_value(THD *thd, Item *item)
|
|||||||
part_column_list_val *col_val;
|
part_column_list_val *col_val;
|
||||||
Name_resolution_context *context= &thd->lex->current_select->context;
|
Name_resolution_context *context= &thd->lex->current_select->context;
|
||||||
TABLE_LIST *save_list= context->table_list;
|
TABLE_LIST *save_list= context->table_list;
|
||||||
const char *save_where= thd->where;
|
THD_WHERE save_where= thd->where;
|
||||||
DBUG_ENTER("partition_info::add_column_list_value");
|
DBUG_ENTER("partition_info::add_column_list_value");
|
||||||
|
|
||||||
if (part_type == LIST_PARTITION &&
|
if (part_type == LIST_PARTITION &&
|
||||||
@ -1838,9 +1838,9 @@ bool partition_info::add_column_list_value(THD *thd, Item *item)
|
|||||||
|
|
||||||
context->table_list= 0;
|
context->table_list= 0;
|
||||||
if (column_list)
|
if (column_list)
|
||||||
thd->where= "field list";
|
thd->where= THD_WHERE::FIELD_LIST;
|
||||||
else
|
else
|
||||||
thd->where= "partition function";
|
thd->where= THD_WHERE::PARTITION_FUNCTION;
|
||||||
|
|
||||||
if (item->walk(&Item::check_partition_func_processor, 0, NULL))
|
if (item->walk(&Item::check_partition_func_processor, 0, NULL))
|
||||||
{
|
{
|
||||||
|
@ -5957,7 +5957,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, si
|
|||||||
{
|
{
|
||||||
if (nj_col)
|
if (nj_col)
|
||||||
{
|
{
|
||||||
my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where);
|
my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd_where(thd));
|
||||||
DBUG_RETURN(NULL);
|
DBUG_RETURN(NULL);
|
||||||
}
|
}
|
||||||
nj_col= curr_nj_col;
|
nj_col= curr_nj_col;
|
||||||
@ -6604,7 +6604,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
|||||||
item->cached_field_index= NO_CACHED_FIELD_INDEX;
|
item->cached_field_index= NO_CACHED_FIELD_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_ASSERT(thd->where);
|
DBUG_ASSERT(thd->where != THD_WHERE::NOWHERE);
|
||||||
/*
|
/*
|
||||||
If we found a fully qualified field we return it directly as it can't
|
If we found a fully qualified field we return it directly as it can't
|
||||||
have duplicates.
|
have duplicates.
|
||||||
@ -6617,7 +6617,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
|||||||
if (report_error == REPORT_ALL_ERRORS ||
|
if (report_error == REPORT_ALL_ERRORS ||
|
||||||
report_error == IGNORE_EXCEPT_NON_UNIQUE)
|
report_error == IGNORE_EXCEPT_NON_UNIQUE)
|
||||||
my_error(ER_NON_UNIQ_ERROR, MYF(0),
|
my_error(ER_NON_UNIQ_ERROR, MYF(0),
|
||||||
table_name ? item->full_name() : name, thd->where);
|
table_name ? item->full_name() : name, thd_where(thd));
|
||||||
return (Field*) 0;
|
return (Field*) 0;
|
||||||
}
|
}
|
||||||
found= cur_field;
|
found= cur_field;
|
||||||
@ -6645,13 +6645,13 @@ find_field_in_tables(THD *thd, Item_ident *item,
|
|||||||
strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS);
|
strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS);
|
||||||
table_name=buff;
|
table_name=buff;
|
||||||
}
|
}
|
||||||
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where);
|
my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd_where(thd));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (report_error == REPORT_ALL_ERRORS ||
|
if (report_error == REPORT_ALL_ERRORS ||
|
||||||
report_error == REPORT_EXCEPT_NON_UNIQUE)
|
report_error == REPORT_EXCEPT_NON_UNIQUE)
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where);
|
my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd_where(thd));
|
||||||
else
|
else
|
||||||
found= not_found_field;
|
found= not_found_field;
|
||||||
}
|
}
|
||||||
@ -6784,7 +6784,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
|
|||||||
*/
|
*/
|
||||||
if (report_error != IGNORE_ERRORS)
|
if (report_error != IGNORE_ERRORS)
|
||||||
my_error(ER_NON_UNIQ_ERROR, MYF(0),
|
my_error(ER_NON_UNIQ_ERROR, MYF(0),
|
||||||
find->full_name(), current_thd->where);
|
find->full_name(), thd_where(current_thd));
|
||||||
return (Item**) 0;
|
return (Item**) 0;
|
||||||
}
|
}
|
||||||
found_unaliased= li.ref();
|
found_unaliased= li.ref();
|
||||||
@ -6815,7 +6815,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
|
|||||||
continue; // Same field twice
|
continue; // Same field twice
|
||||||
if (report_error != IGNORE_ERRORS)
|
if (report_error != IGNORE_ERRORS)
|
||||||
my_error(ER_NON_UNIQ_ERROR, MYF(0),
|
my_error(ER_NON_UNIQ_ERROR, MYF(0),
|
||||||
find->full_name(), current_thd->where);
|
find->full_name(), thd_where(current_thd));
|
||||||
return (Item**) 0;
|
return (Item**) 0;
|
||||||
}
|
}
|
||||||
found= li.ref();
|
found= li.ref();
|
||||||
@ -6870,7 +6870,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
|
|||||||
{
|
{
|
||||||
if (report_error != IGNORE_ERRORS)
|
if (report_error != IGNORE_ERRORS)
|
||||||
my_error(ER_NON_UNIQ_ERROR, MYF(0),
|
my_error(ER_NON_UNIQ_ERROR, MYF(0),
|
||||||
find->full_name(), current_thd->where);
|
find->full_name(), thd_where(current_thd));
|
||||||
return (Item **) 0;
|
return (Item **) 0;
|
||||||
}
|
}
|
||||||
if (found_unaliased)
|
if (found_unaliased)
|
||||||
@ -6887,7 +6887,7 @@ find_item_in_list(Item *find, List<Item> &items, uint *counter,
|
|||||||
{
|
{
|
||||||
if (report_error == REPORT_ALL_ERRORS)
|
if (report_error == REPORT_ALL_ERRORS)
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
||||||
find->full_name(), current_thd->where);
|
find->full_name(), thd_where(current_thd));
|
||||||
return (Item **) 0;
|
return (Item **) 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -7093,7 +7093,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
|
|||||||
DBUG_PRINT ("info", ("match c1.is_common=%d", nj_col_1->is_common));
|
DBUG_PRINT ("info", ("match c1.is_common=%d", nj_col_1->is_common));
|
||||||
if (cur_nj_col_2->is_common || found)
|
if (cur_nj_col_2->is_common || found)
|
||||||
{
|
{
|
||||||
my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1->str, thd->where);
|
my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1->str, thd_where(thd));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if ((!using_fields && !field_2_invisible) || is_using_column_1)
|
if ((!using_fields && !field_2_invisible) || is_using_column_1)
|
||||||
@ -7307,7 +7307,7 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
|
|||||||
if (!(common_field= it++))
|
if (!(common_field= it++))
|
||||||
{
|
{
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
|
my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
|
||||||
current_thd->where);
|
thd_where(current_thd));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (!my_strcasecmp(system_charset_info,
|
if (!my_strcasecmp(system_charset_info,
|
||||||
@ -7561,7 +7561,7 @@ static bool setup_natural_join_row_types(THD *thd,
|
|||||||
Name_resolution_context *context)
|
Name_resolution_context *context)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("setup_natural_join_row_types");
|
DBUG_ENTER("setup_natural_join_row_types");
|
||||||
thd->where= "from clause";
|
thd->where= THD_WHERE::FROM_CLAUSE;
|
||||||
if (from_clause->elements == 0)
|
if (from_clause->elements == 0)
|
||||||
DBUG_RETURN(false); /* We come here in the case of UNIONs. */
|
DBUG_RETURN(false); /* We come here in the case of UNIONs. */
|
||||||
|
|
||||||
@ -7732,7 +7732,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
|
|||||||
thd->lex->current_select->nest_level);
|
thd->lex->current_select->nest_level);
|
||||||
if (allow_sum_func)
|
if (allow_sum_func)
|
||||||
thd->lex->allow_sum_func.set_bit(thd->lex->current_select->nest_level);
|
thd->lex->allow_sum_func.set_bit(thd->lex->current_select->nest_level);
|
||||||
thd->where= THD::DEFAULT_WHERE;
|
thd->where= THD_WHERE::DEFAULT_WHERE;
|
||||||
save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
|
save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
|
||||||
thd->lex->current_select->is_item_list_lookup= 0;
|
thd->lex->current_select->is_item_list_lookup= 0;
|
||||||
|
|
||||||
@ -8491,7 +8491,7 @@ bool setup_on_expr(THD *thd, TABLE_LIST *table, bool is_update)
|
|||||||
embedded= embedding;
|
embedded= embedding;
|
||||||
if (embedded->on_expr)
|
if (embedded->on_expr)
|
||||||
{
|
{
|
||||||
thd->where="on clause";
|
thd->where= THD_WHERE::ON_CLAUSE;
|
||||||
embedded->on_expr->mark_as_condition_AND_part(embedded);
|
embedded->on_expr->mark_as_condition_AND_part(embedded);
|
||||||
if (embedded->on_expr->fix_fields_if_needed_for_bool(thd,
|
if (embedded->on_expr->fix_fields_if_needed_for_bool(thd,
|
||||||
&embedded->on_expr))
|
&embedded->on_expr))
|
||||||
@ -8592,7 +8592,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
|
|||||||
|
|
||||||
if (*conds)
|
if (*conds)
|
||||||
{
|
{
|
||||||
thd->where="where clause";
|
thd->where= THD_WHERE::WHERE_CLAUSE;
|
||||||
DBUG_EXECUTE("where",
|
DBUG_EXECUTE("where",
|
||||||
print_where(*conds,
|
print_where(*conds,
|
||||||
"WHERE in setup_conds",
|
"WHERE in setup_conds",
|
||||||
|
@ -83,8 +83,6 @@
|
|||||||
char internal_table_name[2]= "*";
|
char internal_table_name[2]= "*";
|
||||||
char empty_c_string[1]= {0}; /* used for not defined db */
|
char empty_c_string[1]= {0}; /* used for not defined db */
|
||||||
|
|
||||||
const char * const THD::DEFAULT_WHERE= "field list";
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** User variables
|
** User variables
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -629,6 +627,64 @@ extern "C" void thd_kill_timeout(THD* thd)
|
|||||||
thd->awake(KILL_TIMEOUT);
|
thd->awake(KILL_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *thd_where(THD *thd)
|
||||||
|
{
|
||||||
|
switch(thd->where) {
|
||||||
|
case THD_WHERE::CHECKING_TRANSFORMED_SUBQUERY:
|
||||||
|
return "checking transformed subquery";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::IN_ALL_ANY_SUBQUERY:
|
||||||
|
return "IN/ALL/ANY subquery";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::JSON_TABLE_ARGUMENT:
|
||||||
|
return "JSON_TABLE argument";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::DEFAULT_WHERE: // same as FIELD_LIST
|
||||||
|
case THD_WHERE::FIELD_LIST:
|
||||||
|
return "field list";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::PARTITION_FUNCTION:
|
||||||
|
return "partition function";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::FROM_CLAUSE:
|
||||||
|
return "from clause";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::ON_CLAUSE:
|
||||||
|
return "on clause";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::WHERE_CLAUSE:
|
||||||
|
return "where clause";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::CONVERT_CHARSET_CONST:
|
||||||
|
return "convert character set partition constant";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::FOR_SYSTEM_TIME:
|
||||||
|
return "FOR SYSTEM_TIME";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::ORDER_CLAUSE:
|
||||||
|
return "order clause";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::HAVING_CLAUSE:
|
||||||
|
return "having clause";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::GROUP_STATEMENT:
|
||||||
|
return "group statement";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::PROCEDURE_LIST:
|
||||||
|
return "procedure list";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::CHECK_OPTION:
|
||||||
|
return "check option";
|
||||||
|
break;
|
||||||
|
case THD_WHERE::USE_WHERE_STRING:
|
||||||
|
return thd->where_str;
|
||||||
|
default:
|
||||||
|
break; // "fall-through" to default return below
|
||||||
|
};
|
||||||
|
DBUG_ASSERT(false);
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
THD::THD(my_thread_id id, bool is_wsrep_applier)
|
THD::THD(my_thread_id id, bool is_wsrep_applier)
|
||||||
:Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION,
|
:Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION,
|
||||||
/* statement id */ 0),
|
/* statement id */ 0),
|
||||||
@ -838,7 +894,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
|
|||||||
|
|
||||||
/* Variables with default values */
|
/* Variables with default values */
|
||||||
proc_info="login";
|
proc_info="login";
|
||||||
where= THD::DEFAULT_WHERE;
|
where= THD_WHERE::DEFAULT_WHERE;
|
||||||
slave_net = 0;
|
slave_net = 0;
|
||||||
m_command=COM_CONNECT;
|
m_command=COM_CONNECT;
|
||||||
*scramble= '\0';
|
*scramble= '\0';
|
||||||
@ -2328,7 +2384,7 @@ void THD::cleanup_after_query()
|
|||||||
/* Free Items that were created during this execution */
|
/* Free Items that were created during this execution */
|
||||||
free_items();
|
free_items();
|
||||||
/* Reset where. */
|
/* Reset where. */
|
||||||
where= THD::DEFAULT_WHERE;
|
where= THD_WHERE::DEFAULT_WHERE;
|
||||||
/* reset table map for multi-table update */
|
/* reset table map for multi-table update */
|
||||||
table_map_for_update= 0;
|
table_map_for_update= 0;
|
||||||
m_binlog_invoker= INVOKER_NONE;
|
m_binlog_invoker= INVOKER_NONE;
|
||||||
|
@ -2668,6 +2668,33 @@ struct thd_async_state
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum class THD_WHERE
|
||||||
|
{
|
||||||
|
NOWHERE = 0,
|
||||||
|
CHECKING_TRANSFORMED_SUBQUERY,
|
||||||
|
IN_ALL_ANY_SUBQUERY,
|
||||||
|
JSON_TABLE_ARGUMENT,
|
||||||
|
FIELD_LIST,
|
||||||
|
PARTITION_FUNCTION,
|
||||||
|
FROM_CLAUSE,
|
||||||
|
DEFAULT_WHERE,
|
||||||
|
ON_CLAUSE,
|
||||||
|
WHERE_CLAUSE,
|
||||||
|
CONVERT_CHARSET_CONST,
|
||||||
|
FOR_SYSTEM_TIME,
|
||||||
|
ORDER_CLAUSE,
|
||||||
|
HAVING_CLAUSE,
|
||||||
|
GROUP_STATEMENT,
|
||||||
|
PROCEDURE_LIST,
|
||||||
|
CHECK_OPTION,
|
||||||
|
USE_WHERE_STRING, // ugh, a compromise for vcol...
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class THD;
|
||||||
|
const char *thd_where(THD *thd);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@class THD
|
@class THD
|
||||||
For each client connection we create a separate thread with THD serving as
|
For each client connection we create a separate thread with THD serving as
|
||||||
@ -2720,13 +2747,6 @@ public:
|
|||||||
MDL_request *backup_commit_lock;
|
MDL_request *backup_commit_lock;
|
||||||
|
|
||||||
void reset_for_next_command(bool do_clear_errors= 1);
|
void reset_for_next_command(bool do_clear_errors= 1);
|
||||||
/*
|
|
||||||
Constant for THD::where initialization in the beginning of every query.
|
|
||||||
|
|
||||||
It's needed because we do not save/restore THD::where normally during
|
|
||||||
primary (non subselect) query execution.
|
|
||||||
*/
|
|
||||||
static const char * const DEFAULT_WHERE;
|
|
||||||
|
|
||||||
#ifdef EMBEDDED_LIBRARY
|
#ifdef EMBEDDED_LIBRARY
|
||||||
struct st_mysql *mysql;
|
struct st_mysql *mysql;
|
||||||
@ -2882,12 +2902,15 @@ public:
|
|||||||
const char *get_proc_info() const
|
const char *get_proc_info() const
|
||||||
{ return proc_info; }
|
{ return proc_info; }
|
||||||
|
|
||||||
|
// Used by thd_where() when where==USE_WHERE_STRING
|
||||||
|
const char *where_str;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Used in error messages to tell user in what part of MySQL we found an
|
Used in error messages to tell user in what part of MySQL we found an
|
||||||
error. E. g. when where= "having clause", if fix_fields() fails, user
|
error. E. g. when where= "having clause", if fix_fields() fails, user
|
||||||
will know that the error was in having clause.
|
will know that the error was in having clause.
|
||||||
*/
|
*/
|
||||||
const char *where;
|
THD_WHERE where;
|
||||||
|
|
||||||
/* Needed by MariaDB semi sync replication */
|
/* Needed by MariaDB semi sync replication */
|
||||||
Trans_binlog_info *semisync_info;
|
Trans_binlog_info *semisync_info;
|
||||||
|
@ -431,7 +431,7 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
|
|||||||
derived->on_expr= expr;
|
derived->on_expr= expr;
|
||||||
derived->prep_on_expr= expr->copy_andor_structure(thd);
|
derived->prep_on_expr= expr->copy_andor_structure(thd);
|
||||||
}
|
}
|
||||||
thd->where= "on clause";
|
thd->where= THD_WHERE::ON_CLAUSE;
|
||||||
if (derived->on_expr &&
|
if (derived->on_expr &&
|
||||||
derived->on_expr->fix_fields_if_needed_for_bool(thd, &derived->on_expr))
|
derived->on_expr->fix_fields_if_needed_for_bool(thd, &derived->on_expr))
|
||||||
{
|
{
|
||||||
|
@ -8147,7 +8147,7 @@ bool LEX::check_expr_allows_fields_or_error(THD *thd, const char *name) const
|
|||||||
{
|
{
|
||||||
if (select_stack_top > 0)
|
if (select_stack_top > 0)
|
||||||
return false; // OK, fields are allowed
|
return false; // OK, fields are allowed
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0), name, thd->where);
|
my_error(ER_BAD_FIELD_ERROR, MYF(0), name, thd_where(thd));
|
||||||
return true; // Error, fields are not allowed
|
return true; // Error, fields are not allowed
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8170,7 +8170,7 @@ Item *LEX::create_item_ident_nospvar(THD *thd,
|
|||||||
|
|
||||||
if (unlikely(current_select->no_table_names_allowed))
|
if (unlikely(current_select->no_table_names_allowed))
|
||||||
{
|
{
|
||||||
my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), a->str, thd->where);
|
my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), a->str, thd_where(thd));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8385,7 +8385,7 @@ Item *LEX::create_item_ident(THD *thd,
|
|||||||
|
|
||||||
if (current_select->no_table_names_allowed)
|
if (current_select->no_table_names_allowed)
|
||||||
{
|
{
|
||||||
my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), b->str, thd->where);
|
my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), b->str, thd_where(thd));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,11 +142,11 @@ Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs)
|
|||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
Name_resolution_context *context= &thd->lex->current_select->context;
|
Name_resolution_context *context= &thd->lex->current_select->context;
|
||||||
TABLE_LIST *save_list= context->table_list;
|
TABLE_LIST *save_list= context->table_list;
|
||||||
const char *save_where= thd->where;
|
THD_WHERE save_where= thd->where;
|
||||||
|
|
||||||
item= item->safe_charset_converter(thd, cs);
|
item= item->safe_charset_converter(thd, cs);
|
||||||
context->table_list= NULL;
|
context->table_list= NULL;
|
||||||
thd->where= "convert character set partition constant";
|
thd->where= THD_WHERE::CONVERT_CHARSET_CONST;
|
||||||
if (item && item->fix_fields_if_needed(thd, (Item**)NULL))
|
if (item && item->fix_fields_if_needed(thd, (Item**)NULL))
|
||||||
item= NULL;
|
item= NULL;
|
||||||
thd->where= save_where;
|
thd->where= save_where;
|
||||||
@ -841,7 +841,7 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
|
|||||||
|
|
||||||
func_expr->walk(&Item::change_context_processor, 0,
|
func_expr->walk(&Item::change_context_processor, 0,
|
||||||
&lex.first_select_lex()->context);
|
&lex.first_select_lex()->context);
|
||||||
thd->where= "partition function";
|
thd->where= THD_WHERE::PARTITION_FUNCTION;
|
||||||
/*
|
/*
|
||||||
In execution we must avoid the use of thd->change_item_tree since
|
In execution we must avoid the use of thd->change_item_tree since
|
||||||
we might release memory before statement is completed. We do this
|
we might release memory before statement is completed. We do this
|
||||||
|
@ -1245,7 +1245,7 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
|
|||||||
|
|
||||||
if (vers_conditions.is_set() && vers_conditions.type != SYSTEM_TIME_HISTORY)
|
if (vers_conditions.is_set() && vers_conditions.type != SYSTEM_TIME_HISTORY)
|
||||||
{
|
{
|
||||||
thd->where= "FOR SYSTEM_TIME";
|
thd->where= THD_WHERE::FOR_SYSTEM_TIME;
|
||||||
/* TODO: do resolve fix_length_and_dec(), fix_fields(). This requires
|
/* TODO: do resolve fix_length_and_dec(), fix_fields(). This requires
|
||||||
storing vers_conditions as Item and make some magic related to
|
storing vers_conditions as Item and make some magic related to
|
||||||
vers_system_time_t/VERS_TRX_ID at stage of fix_fields()
|
vers_system_time_t/VERS_TRX_ID at stage of fix_fields()
|
||||||
@ -1530,7 +1530,7 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
|
|||||||
{
|
{
|
||||||
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
|
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
|
||||||
thd->lex->allow_sum_func.set_bit(select_lex->nest_level);
|
thd->lex->allow_sum_func.set_bit(select_lex->nest_level);
|
||||||
thd->where= "order clause";
|
thd->where= THD_WHERE::ORDER_CLAUSE;
|
||||||
for (ORDER *order= select_lex->order_list.first; order; order= order->next)
|
for (ORDER *order= select_lex->order_list.first; order; order= order->next)
|
||||||
{
|
{
|
||||||
/* Don't add the order items to all fields. Just resolve them to ensure
|
/* Don't add the order items to all fields. Just resolve them to ensure
|
||||||
@ -1546,7 +1546,7 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
|
|||||||
if (having)
|
if (having)
|
||||||
{
|
{
|
||||||
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
|
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
|
||||||
thd->where="having clause";
|
thd->where= THD_WHERE::HAVING_CLAUSE;
|
||||||
thd->lex->allow_sum_func.set_bit(select_lex_arg->nest_level);
|
thd->lex->allow_sum_func.set_bit(select_lex_arg->nest_level);
|
||||||
select_lex->having_fix_field= 1;
|
select_lex->having_fix_field= 1;
|
||||||
/*
|
/*
|
||||||
@ -25986,7 +25986,7 @@ find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array,
|
|||||||
if (!count || count > fields.elements)
|
if (!count || count > fields.elements)
|
||||||
{
|
{
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
||||||
order_item->full_name(), thd->where);
|
order_item->full_name(), thd_where(thd));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
thd->change_item_tree((Item **)&order->item, (Item *)&ref_pointer_array[count - 1]);
|
thd->change_item_tree((Item **)&order->item, (Item *)&ref_pointer_array[count - 1]);
|
||||||
@ -26065,7 +26065,7 @@ find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array,
|
|||||||
ER_NON_UNIQ_ERROR,
|
ER_NON_UNIQ_ERROR,
|
||||||
ER_THD(thd, ER_NON_UNIQ_ERROR),
|
ER_THD(thd, ER_NON_UNIQ_ERROR),
|
||||||
((Item_ident*) order_item)->field_name.str,
|
((Item_ident*) order_item)->field_name.str,
|
||||||
thd->where);
|
thd_where(thd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (from_window_spec)
|
else if (from_window_spec)
|
||||||
@ -26135,7 +26135,7 @@ int setup_order(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
|
|||||||
SELECT_LEX *select = thd->lex->current_select;
|
SELECT_LEX *select = thd->lex->current_select;
|
||||||
enum_parsing_place context_analysis_place=
|
enum_parsing_place context_analysis_place=
|
||||||
thd->lex->current_select->context_analysis_place;
|
thd->lex->current_select->context_analysis_place;
|
||||||
thd->where="order clause";
|
thd->where= THD_WHERE::ORDER_CLAUSE;
|
||||||
const bool for_union= select->master_unit()->is_unit_op() &&
|
const bool for_union= select->master_unit()->is_unit_op() &&
|
||||||
select == select->master_unit()->fake_select_lex;
|
select == select->master_unit()->fake_select_lex;
|
||||||
for (uint number = 1; order; order=order->next, number++)
|
for (uint number = 1; order; order=order->next, number++)
|
||||||
@ -26214,7 +26214,7 @@ setup_group(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
|
|||||||
|
|
||||||
uint org_fields=all_fields.elements;
|
uint org_fields=all_fields.elements;
|
||||||
|
|
||||||
thd->where="group statement";
|
thd->where= THD_WHERE::GROUP_STATEMENT;
|
||||||
for (ord= order; ord; ord= ord->next)
|
for (ord= order; ord; ord= ord->next)
|
||||||
{
|
{
|
||||||
if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
|
if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
|
||||||
@ -26332,7 +26332,7 @@ setup_new_fields(THD *thd, List<Item> &fields,
|
|||||||
new_field->item=item; /* Change to shared Item */
|
new_field->item=item; /* Change to shared Item */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
thd->where="procedure list";
|
thd->where= THD_WHERE::PROCEDURE_LIST;
|
||||||
if ((*new_field->item)->fix_fields(thd, new_field->item))
|
if ((*new_field->item)->fix_fields(thd, new_field->item))
|
||||||
DBUG_RETURN(1); /* purecov: inspected */
|
DBUG_RETURN(1); /* purecov: inspected */
|
||||||
all_fields.push_front(*new_field->item, thd->mem_root);
|
all_fields.push_front(*new_field->item, thd->mem_root);
|
||||||
|
@ -312,7 +312,7 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl,
|
|||||||
(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)
|
(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
thd->where="order clause";
|
thd->where= THD_WHERE::ORDER_CLAUSE;
|
||||||
ORDER *order= sl->order_list.first;
|
ORDER *order= sl->order_list.first;
|
||||||
for (; order; order=order->next)
|
for (; order; order=order->next)
|
||||||
{
|
{
|
||||||
@ -327,7 +327,7 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl,
|
|||||||
if (!count || count > first_elem->elements)
|
if (!count || count > first_elem->elements)
|
||||||
{
|
{
|
||||||
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
my_error(ER_BAD_FIELD_ERROR, MYF(0),
|
||||||
order_item->full_name(), thd->where);
|
order_item->full_name(), thd_where(thd));
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
order->in_field_list= 1;
|
order->in_field_list= 1;
|
||||||
|
@ -12520,7 +12520,7 @@ opt_order_clause:
|
|||||||
order_clause:
|
order_clause:
|
||||||
ORDER_SYM BY
|
ORDER_SYM BY
|
||||||
{
|
{
|
||||||
thd->where= "ORDER clause";
|
thd->where= THD_WHERE::ORDER_CLAUSE;
|
||||||
}
|
}
|
||||||
order_list
|
order_list
|
||||||
{
|
{
|
||||||
|
@ -1212,7 +1212,8 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
|
|||||||
|
|
||||||
expr_str.length(parse_vcol_keyword.length);
|
expr_str.length(parse_vcol_keyword.length);
|
||||||
expr_str.append((char*)pos, expr_length);
|
expr_str.append((char*)pos, expr_length);
|
||||||
thd->where= vcol_type_name(static_cast<enum_vcol_info_type>(type));
|
thd->where= THD_WHERE::USE_WHERE_STRING;
|
||||||
|
thd->where_str= vcol_type_name(static_cast<enum_vcol_info_type>(type));
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VCOL_GENERATED_VIRTUAL:
|
case VCOL_GENERATED_VIRTUAL:
|
||||||
@ -6282,8 +6283,8 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
|
|||||||
|
|
||||||
if (check_option)
|
if (check_option)
|
||||||
{
|
{
|
||||||
const char *save_where= thd->where;
|
THD_WHERE save_where= thd->where;
|
||||||
thd->where= "check option";
|
thd->where= THD_WHERE::CHECK_OPTION;
|
||||||
if (check_option->fix_fields_if_needed_for_bool(thd, &check_option))
|
if (check_option->fix_fields_if_needed_for_bool(thd, &check_option))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
thd->where= save_where;
|
thd->where= save_where;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user