1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-9619: Assertion `null_ref_table' failed in virtual table_map Item_direct_view_ref::used_tables() const on 2nd execution of PS

Refer left expression indirectly in case it changes from execution to execution.
This commit is contained in:
Oleksandr Byelkin
2017-02-18 17:47:31 +01:00
parent 2bab29ebba
commit 235b68299b
16 changed files with 332 additions and 33 deletions

View File

@ -4203,4 +4203,117 @@ execute stmt;
1 1
1 1
drop table t1,t2; drop table t1,t2;
#
# MDEV-9619: Assertion `null_ref_table' failed in virtual
# table_map Item_direct_view_ref::used_tables() const on 2nd
# execution of PS
#
CREATE TABLE t1 (f1 VARCHAR(10)) ENGINE=MyISAM;
CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES ('a'),('b');
CREATE TABLE t2 (f2 VARCHAR(10)) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('c'),('d');
PREPARE stmt FROM "SELECT * FROM v1 WHERE f1 = SOME ( SELECT f2 FROM t2 )";
EXECUTE stmt;
f1
EXECUTE stmt;
f1
insert into t1 values ('c');
EXECUTE stmt;
f1
c
EXECUTE stmt;
f1
c
deallocate prepare stmt;
drop view v1;
drop table t1,t2;
CREATE TABLE t1 (f1 VARCHAR(10)) ENGINE=MyISAM;
CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES ('a'),('b');
CREATE TABLE t2 (f2 VARCHAR(10)) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('c'),('d');
PREPARE stmt FROM "SELECT * FROM v1 WHERE (f1,f1) = SOME ( SELECT f2,f2 FROM t2 )";
EXECUTE stmt;
f1
EXECUTE stmt;
f1
insert into t1 values ('c');
EXECUTE stmt;
f1
c
EXECUTE stmt;
f1
c
deallocate prepare stmt;
drop view v1;
drop table t1,t2;
CREATE TABLE t1 (column1 INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (3),(9);
CREATE TABLE t2 (column2 INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1),(4);
CREATE TABLE t3 (column3 INT) ENGINE=MyISAM;
INSERT INTO t3 VALUES (6),(8);
CREATE TABLE t4 (column4 INT) ENGINE=MyISAM;
INSERT INTO t4 VALUES (2),(5);
PREPARE stmt FROM "
SELECT (
SELECT MAX( table1.column1 ) AS field1
FROM t1 AS table1
WHERE (111,table3.column3) IN ( SELECT 111,table2.column2 AS field2 FROM t2 AS table2 )
) AS sq
FROM t3 AS table3, t4 AS table4 GROUP BY sq
";
EXECUTE stmt;
sq
NULL
EXECUTE stmt;
sq
NULL
deallocate prepare stmt;
drop table t1,t2,t3,t4;
create table t1 (a int, b int, c int);
create table t2 (x int, y int, z int);
create table t3 as select * from t1;
insert into t1 values (1,2,3),(4,5,6),(100,200,300),(400,500,600);
insert into t2 values (1,2,3),(7,8,9),(100,200,300),(400,500,600);
insert into t3 values (1,2,3),(11,12,13),(100,0,0),(400,500,600);
set @optimizer_switch_save=@@optimizer_switch;
set @join_cache_level_save=@@join_cache_level;
set optimizer_switch='materialization=off';
set join_cache_level=0;
select * from t1 where (select a,b from t3 where t3.c=t1.c) in (select x,y from t2 where t1.c= t2.z);
a b c
1 2 3
400 500 600
prepare stmt from "select * from t1 where (select a,b from t3 where t3.c=t1.c) in (select x,y from t2 where t1.c= t2.z)";
EXECUTE stmt;
a b c
1 2 3
400 500 600
EXECUTE stmt;
a b c
1 2 3
400 500 600
create view v1 as select * from t1;
create view v2 as select * from t2;
create view v3 as select * from t3;
select * from v1 where (select a,b from v3 where v3.c=v1.c) in (select x,y from v2 where v1.c= v2.z);
a b c
1 2 3
400 500 600
prepare stmt from "select * from v1 where (select a,b from v3 where v3.c=v1.c) in (select x,y from v2 where v1.c= v2.z)";
EXECUTE stmt;
a b c
1 2 3
400 500 600
EXECUTE stmt;
a b c
1 2 3
400 500 600
set optimizer_switch=@optimizer_switch_save;
set join_cache_level=@join_cache_level_save;
deallocate prepare stmt;
drop view v1,v2,v3;
drop table t1,t2,t3;
# End of 5.5 tests # End of 5.5 tests

View File

@ -3740,4 +3740,107 @@ execute stmt;
drop table t1,t2; drop table t1,t2;
--echo #
--echo # MDEV-9619: Assertion `null_ref_table' failed in virtual
--echo # table_map Item_direct_view_ref::used_tables() const on 2nd
--echo # execution of PS
--echo #
CREATE TABLE t1 (f1 VARCHAR(10)) ENGINE=MyISAM;
CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES ('a'),('b');
CREATE TABLE t2 (f2 VARCHAR(10)) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('c'),('d');
PREPARE stmt FROM "SELECT * FROM v1 WHERE f1 = SOME ( SELECT f2 FROM t2 )";
EXECUTE stmt;
EXECUTE stmt;
insert into t1 values ('c');
EXECUTE stmt;
EXECUTE stmt;
deallocate prepare stmt;
drop view v1;
drop table t1,t2;
CREATE TABLE t1 (f1 VARCHAR(10)) ENGINE=MyISAM;
CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES ('a'),('b');
CREATE TABLE t2 (f2 VARCHAR(10)) ENGINE=MyISAM;
INSERT INTO t2 VALUES ('c'),('d');
PREPARE stmt FROM "SELECT * FROM v1 WHERE (f1,f1) = SOME ( SELECT f2,f2 FROM t2 )";
EXECUTE stmt;
EXECUTE stmt;
insert into t1 values ('c');
EXECUTE stmt;
EXECUTE stmt;
deallocate prepare stmt;
drop view v1;
drop table t1,t2;
CREATE TABLE t1 (column1 INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (3),(9);
CREATE TABLE t2 (column2 INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1),(4);
CREATE TABLE t3 (column3 INT) ENGINE=MyISAM;
INSERT INTO t3 VALUES (6),(8);
CREATE TABLE t4 (column4 INT) ENGINE=MyISAM;
INSERT INTO t4 VALUES (2),(5);
PREPARE stmt FROM "
SELECT (
SELECT MAX( table1.column1 ) AS field1
FROM t1 AS table1
WHERE (111,table3.column3) IN ( SELECT 111,table2.column2 AS field2 FROM t2 AS table2 )
) AS sq
FROM t3 AS table3, t4 AS table4 GROUP BY sq
";
EXECUTE stmt;
EXECUTE stmt;
deallocate prepare stmt;
drop table t1,t2,t3,t4;
create table t1 (a int, b int, c int);
create table t2 (x int, y int, z int);
create table t3 as select * from t1;
insert into t1 values (1,2,3),(4,5,6),(100,200,300),(400,500,600);
insert into t2 values (1,2,3),(7,8,9),(100,200,300),(400,500,600);
insert into t3 values (1,2,3),(11,12,13),(100,0,0),(400,500,600);
set @optimizer_switch_save=@@optimizer_switch;
set @join_cache_level_save=@@join_cache_level;
set optimizer_switch='materialization=off';
set join_cache_level=0;
select * from t1 where (select a,b from t3 where t3.c=t1.c) in (select x,y from t2 where t1.c= t2.z);
prepare stmt from "select * from t1 where (select a,b from t3 where t3.c=t1.c) in (select x,y from t2 where t1.c= t2.z)";
EXECUTE stmt;
EXECUTE stmt;
create view v1 as select * from t1;
create view v2 as select * from t2;
create view v3 as select * from t3;
select * from v1 where (select a,b from v3 where v3.c=v1.c) in (select x,y from v2 where v1.c= v2.z);
prepare stmt from "select * from v1 where (select a,b from v3 where v3.c=v1.c) in (select x,y from v2 where v1.c= v2.z)";
EXECUTE stmt;
EXECUTE stmt;
set optimizer_switch=@optimizer_switch_save;
set join_cache_level=@join_cache_level_save;
deallocate prepare stmt;
drop view v1,v2,v3;
drop table t1,t2,t3;
--echo # End of 5.5 tests --echo # End of 5.5 tests

View File

@ -44,7 +44,14 @@ Item_row::Item_row(List<Item> &arg):
//TODO: think placing 2-3 component items in item (as it done for function) //TODO: think placing 2-3 component items in item (as it done for function)
if ((arg_count= arg.elements)) if ((arg_count= arg.elements))
{
items= (Item**) sql_alloc(sizeof(Item*)*arg_count); items= (Item**) sql_alloc(sizeof(Item*)*arg_count);
if (!items)
{
arg_count= 0;
return;
}
}
else else
items= 0; items= 0;
List_iterator<Item> li(arg); List_iterator<Item> li(arg);
@ -57,6 +64,27 @@ Item_row::Item_row(List<Item> &arg):
} }
} }
Item_row::Item_row(Item *item):
Item(),
used_tables_cache(0),
not_null_tables_cache(0),
arg_count(item->cols()),
const_item_cache(1),
with_null(0)
{
items= (Item**) sql_alloc(sizeof(Item*) * arg_count);
if (!items)
{
arg_count= 0;
return;
}
for (uint i= 0; i < arg_count; i++)
{
items[i]= item->element_index(i);
}
}
void Item_row::illegal_method_call(const char *method) void Item_row::illegal_method_call(const char *method)
{ {
DBUG_ENTER("Item_row::illegal_method_call"); DBUG_ENTER("Item_row::illegal_method_call");

View File

@ -35,6 +35,7 @@ public:
const_item_cache(item->const_item_cache), const_item_cache(item->const_item_cache),
with_null(0) with_null(0)
{} {}
Item_row(Item *item);
enum Type type() const { return ROW_ITEM; }; enum Type type() const { return ROW_ITEM; };
void illegal_method_call(const char *); void illegal_method_call(const char *);

View File

@ -1374,6 +1374,9 @@ Item_in_subselect::Item_in_subselect(Item * left_exp,
{ {
DBUG_ENTER("Item_in_subselect::Item_in_subselect"); DBUG_ENTER("Item_in_subselect::Item_in_subselect");
left_expr_orig= left_expr= left_exp; left_expr_orig= left_expr= left_exp;
/* prepare to possible disassembling the item in convert_subq_to_sj() */
if (left_exp->type() == Item::ROW_ITEM)
left_expr_orig= new Item_row(left_exp);
func= &eq_creator; func= &eq_creator;
init(select_lex, new select_exists_subselect(this)); init(select_lex, new select_exists_subselect(this));
max_columns= UINT_MAX; max_columns= UINT_MAX;
@ -1398,6 +1401,9 @@ Item_allany_subselect::Item_allany_subselect(Item * left_exp,
{ {
DBUG_ENTER("Item_allany_subselect::Item_allany_subselect"); DBUG_ENTER("Item_allany_subselect::Item_allany_subselect");
left_expr_orig= left_expr= left_exp; left_expr_orig= left_expr= left_exp;
/* prepare to possible disassembling the item in convert_subq_to_sj() */
if (left_exp->type() == Item::ROW_ITEM)
left_expr_orig= new Item_row(left_exp);
func= func_creator(all_arg); func= func_creator(all_arg);
init(select_lex, new select_exists_subselect(this)); init(select_lex, new select_exists_subselect(this));
max_columns= 1; max_columns= 1;

View File

@ -1609,6 +1609,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
sj-nest. sj-nest.
*/ */
st_select_lex *subq_lex= subq_pred->unit->first_select(); st_select_lex *subq_lex= subq_pred->unit->first_select();
DBUG_ASSERT(subq_lex->next_select() == NULL);
nested_join->join_list.empty(); nested_join->join_list.empty();
List_iterator_fast<TABLE_LIST> li(subq_lex->top_join_list); List_iterator_fast<TABLE_LIST> li(subq_lex->top_join_list);
TABLE_LIST *tl; TABLE_LIST *tl;
@ -1706,7 +1707,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
if (subq_pred->left_expr->cols() == 1) if (subq_pred->left_expr->cols() == 1)
{ {
nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr); /* add left = select_list_element */
nested_join->sj_outer_expr_list.push_back(&subq_pred->left_expr);
/* /*
Create Item_func_eq. Note that Create Item_func_eq. Note that
1. this is done on the statement, not execution, arena 1. this is done on the statement, not execution, arena
@ -1718,24 +1720,61 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
*/ */
Item_func_eq *item_eq= Item_func_eq *item_eq=
new Item_func_eq(subq_pred->left_expr_orig, subq_lex->ref_pointer_array[0]); new Item_func_eq(subq_pred->left_expr_orig, subq_lex->ref_pointer_array[0]);
if (!item_eq)
DBUG_RETURN(TRUE);
if (subq_pred->left_expr_orig != subq_pred->left_expr) if (subq_pred->left_expr_orig != subq_pred->left_expr)
thd->change_item_tree(item_eq->arguments(), subq_pred->left_expr); thd->change_item_tree(item_eq->arguments(), subq_pred->left_expr);
item_eq->in_equality_no= 0; item_eq->in_equality_no= 0;
sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq); sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq);
} }
else else if (subq_pred->left_expr->type() == Item::ROW_ITEM)
{ {
/*
disassemple left expression and add
left1 = select_list_element1 and left2 = select_list_element2 ...
*/
for (uint i= 0; i < subq_pred->left_expr->cols(); i++) for (uint i= 0; i < subq_pred->left_expr->cols(); i++)
{ {
nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr-> nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr->
element_index(i)); addr(i));
Item_func_eq *item_eq= Item_func_eq *item_eq=
new Item_func_eq(subq_pred->left_expr->element_index(i), new Item_func_eq(subq_pred->left_expr_orig->element_index(i),
subq_lex->ref_pointer_array[i]); subq_lex->ref_pointer_array[i]);
if (!item_eq)
DBUG_RETURN(TRUE);
DBUG_ASSERT(subq_pred->left_expr->element_index(i)->fixed);
if (subq_pred->left_expr_orig->element_index(i) !=
subq_pred->left_expr->element_index(i))
thd->change_item_tree(item_eq->arguments(),
subq_pred->left_expr->element_index(i));
item_eq->in_equality_no= i; item_eq->in_equality_no= i;
sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq); sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq);
} }
} }
else
{
/*
add row operation
left = (select_list_element1, select_list_element2, ...)
*/
Item_row *row= new Item_row(subq_lex->pre_fix);
/* fix fields on subquery was call so they should be the same */
DBUG_ASSERT(subq_pred->left_expr->cols() == row->cols());
if (!row)
DBUG_RETURN(TRUE);
nested_join->sj_outer_expr_list.push_back(&subq_pred->left_expr);
Item_func_eq *item_eq=
new Item_func_eq(subq_pred->left_expr_orig, row);
if (!item_eq)
DBUG_RETURN(TRUE);
for (uint i= 0; i < row->cols(); i++)
{
if (row->element_index(i) != subq_lex->ref_pointer_array[i])
thd->change_item_tree(row->addr(i), subq_lex->ref_pointer_array[i]);
}
item_eq->in_equality_no= 0;
sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq);
}
/* /*
Fix the created equality and AND Fix the created equality and AND
@ -3285,8 +3324,8 @@ void restore_prev_sj_state(const table_map remaining_tables,
ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest, ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest,
table_map remaining_tables) table_map remaining_tables)
{ {
List_iterator<Item> li(sj_nest->nested_join->sj_outer_expr_list); List_iterator<Item_ptr> li(sj_nest->nested_join->sj_outer_expr_list);
Item *item; Item **item;
uint i= 0; uint i= 0;
ulonglong res= 0; ulonglong res= 0;
while ((item= li++)) while ((item= li++))
@ -3297,7 +3336,7 @@ ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest,
class and see if there is an element that is bound? class and see if there is an element that is bound?
(this is an optional feature) (this is an optional feature)
*/ */
if (!(item->used_tables() & remaining_tables)) if (!(item[0]->used_tables() & remaining_tables))
{ {
res |= 1ULL << i; res |= 1ULL << i;
} }

View File

@ -8128,13 +8128,15 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
bool setup_fields(THD *thd, Item **ref_pointer_array, bool setup_fields(THD *thd, Item **ref_pointer_array,
List<Item> &fields, enum_mark_columns mark_used_columns, List<Item> &fields, enum_mark_columns mark_used_columns,
List<Item> *sum_func_list, bool allow_sum_func) List<Item> *sum_func_list, List<Item> *pre_fix,
bool allow_sum_func)
{ {
reg2 Item *item; reg2 Item *item;
enum_mark_columns save_mark_used_columns= thd->mark_used_columns; enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
nesting_map save_allow_sum_func= thd->lex->allow_sum_func; nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
List_iterator<Item> it(fields); List_iterator<Item> it(fields);
bool save_is_item_list_lookup; bool save_is_item_list_lookup;
bool make_pre_fix= (pre_fix && (pre_fix->elements == 0));
DBUG_ENTER("setup_fields"); DBUG_ENTER("setup_fields");
DBUG_PRINT("enter", ("ref_pointer_array: %p", ref_pointer_array)); DBUG_PRINT("enter", ("ref_pointer_array: %p", ref_pointer_array));
@ -8181,6 +8183,9 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
thd->lex->current_select->cur_pos_in_select_list= 0; thd->lex->current_select->cur_pos_in_select_list= 0;
while ((item= it++)) while ((item= it++))
{ {
if (make_pre_fix)
pre_fix->push_back(item, thd->stmt_arena->mem_root);
if ((!item->fixed && item->fix_fields(thd, it.ref())) || if ((!item->fixed && item->fix_fields(thd, it.ref())) ||
(item= *(it.ref()))->check_cols(1)) (item= *(it.ref()))->check_cols(1))
{ {

View File

@ -216,7 +216,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
List<Item> *sum_func_list, uint wild_num); List<Item> *sum_func_list, uint wild_num);
bool setup_fields(THD *thd, Item** ref_pointer_array, bool setup_fields(THD *thd, Item** ref_pointer_array,
List<Item> &item, enum_mark_columns mark_used_columns, List<Item> &item, enum_mark_columns mark_used_columns,
List<Item> *sum_func_list, bool allow_sum_func); List<Item> *sum_func_list, List<Item> *pre_fix,
bool allow_sum_func);
void unfix_fields(List<Item> &items); void unfix_fields(List<Item> &items);
bool fill_record(THD *thd, Field **field, List<Item> &values, bool fill_record(THD *thd, Field **field, List<Item> &values,
bool ignore_errors, bool use_value); bool ignore_errors, bool use_value);
@ -407,7 +408,7 @@ inline bool setup_fields_with_no_wrap(THD *thd, Item **ref_pointer_array,
bool res; bool res;
thd->lex->select_lex.no_wrap_view_item= TRUE; thd->lex->select_lex.no_wrap_view_item= TRUE;
res= setup_fields(thd, ref_pointer_array, item, mark_used_columns, res= setup_fields(thd, ref_pointer_array, item, mark_used_columns,
sum_func_list, allow_sum_func); sum_func_list, NULL, allow_sum_func);
thd->lex->select_lex.no_wrap_view_item= FALSE; thd->lex->select_lex.no_wrap_view_item= FALSE;
return res; return res;
} }

View File

@ -28,7 +28,7 @@ bool mysql_do(THD *thd, List<Item> &values)
List_iterator<Item> li(values); List_iterator<Item> li(values);
Item *value; Item *value;
DBUG_ENTER("mysql_do"); DBUG_ENTER("mysql_do");
if (setup_fields(thd, 0, values, MARK_COLUMNS_NONE, 0, 0)) if (setup_fields(thd, 0, values, MARK_COLUMNS_NONE, 0, NULL, 0))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
while ((value = li++)) while ((value = li++))
value->val_int(); value->val_int();

View File

@ -262,7 +262,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
if (table_list->is_view()) if (table_list->is_view())
unfix_fields(fields); unfix_fields(fields);
res= setup_fields(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0); res= setup_fields(thd, 0, fields, MARK_COLUMNS_WRITE, 0, NULL, 0);
/* Restore the current context. */ /* Restore the current context. */
ctx_state.restore_state(context, table_list); ctx_state.restore_state(context, table_list);
@ -373,7 +373,7 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
} }
/* Check the fields we are going to modify */ /* Check the fields we are going to modify */
if (setup_fields(thd, 0, update_fields, MARK_COLUMNS_WRITE, 0, 0)) if (setup_fields(thd, 0, update_fields, MARK_COLUMNS_WRITE, 0, NULL, 0))
return -1; return -1;
if (insert_table_list->is_view() && if (insert_table_list->is_view() &&
@ -810,7 +810,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
goto abort; goto abort;
} }
if (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0)) if (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, NULL, 0))
goto abort; goto abort;
} }
its.rewind (); its.rewind ();
@ -1452,7 +1452,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
table_list->next_local= 0; table_list->next_local= 0;
context->resolve_in_table_list_only(table_list); context->resolve_in_table_list_only(table_list);
res= (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0) || res= (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, NULL, 0) ||
check_insert_fields(thd, context->table_list, fields, *values, check_insert_fields(thd, context->table_list, fields, *values,
!insert_into_view, 0, &map)); !insert_into_view, 0, &map));
@ -1468,7 +1468,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
} }
if (!res) if (!res)
res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0); res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, NULL, 0);
if (!res && duplic == DUP_UPDATE) if (!res && duplic == DUP_UPDATE)
{ {
@ -3369,7 +3369,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
*/ */
lex->current_select= &lex->select_lex; lex->current_select= &lex->select_lex;
res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0) || res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, NULL, 0) ||
check_insert_fields(thd, table_list, *fields, values, check_insert_fields(thd, table_list, *fields, values,
!insert_into_view, 1, &map)); !insert_into_view, 1, &map));
@ -3425,7 +3425,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
ctx_state.get_first_name_resolution_table(); ctx_state.get_first_name_resolution_table();
res= res || setup_fields(thd, 0, *info.update_values, res= res || setup_fields(thd, 0, *info.update_values,
MARK_COLUMNS_READ, 0, 0); MARK_COLUMNS_READ, 0, NULL, 0);
if (!res) if (!res)
{ {
/* /*

View File

@ -758,6 +758,7 @@ public:
Group_list_ptrs *group_list_ptrs; Group_list_ptrs *group_list_ptrs;
List<Item> item_list; /* list of fields & expressions */ List<Item> item_list; /* list of fields & expressions */
List<Item> pre_fix; /* above list before fix_fields */
List<String> interval_list; List<String> interval_list;
bool is_item_list_lookup; bool is_item_list_lookup;
/* /*

View File

@ -293,15 +293,15 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
Let us also prepare SET clause, altough it is probably empty Let us also prepare SET clause, altough it is probably empty
in this case. in this case.
*/ */
if (setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) || if (setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, NULL, 0) ||
setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0)) setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, NULL, 0))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
else else
{ // Part field list { // Part field list
/* TODO: use this conds for 'WITH CHECK OPTIONS' */ /* TODO: use this conds for 'WITH CHECK OPTIONS' */
if (setup_fields(thd, 0, fields_vars, MARK_COLUMNS_WRITE, 0, 0) || if (setup_fields(thd, 0, fields_vars, MARK_COLUMNS_WRITE, 0, NULL, 0) ||
setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) || setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, NULL, 0) ||
check_that_all_fields_are_given_values(thd, table, table_list)) check_that_all_fields_are_given_values(thd, table, table_list))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
/* /*
@ -320,7 +320,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
} }
} }
/* Fix the expressions in SET clause */ /* Fix the expressions in SET clause */
if (setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0)) if (setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, NULL, 0))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }

View File

@ -1307,7 +1307,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter);
goto error; goto error;
} }
if (setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, 0)) if (setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, NULL, 0))
goto error; goto error;
} }
} }
@ -1397,7 +1397,7 @@ static int mysql_test_update(Prepared_statement *stmt,
table_list->register_want_access(want_privilege); table_list->register_want_access(want_privilege);
#endif #endif
thd->lex->select_lex.no_wrap_view_item= TRUE; thd->lex->select_lex.no_wrap_view_item= TRUE;
res= setup_fields(thd, 0, select->item_list, MARK_COLUMNS_READ, 0, 0); res= setup_fields(thd, 0, select->item_list, MARK_COLUMNS_READ, 0, NULL, 0);
thd->lex->select_lex.no_wrap_view_item= FALSE; thd->lex->select_lex.no_wrap_view_item= FALSE;
if (res) if (res)
goto error; goto error;
@ -1408,7 +1408,8 @@ static int mysql_test_update(Prepared_statement *stmt,
(SELECT_ACL & ~table_list->table->grant.privilege); (SELECT_ACL & ~table_list->table->grant.privilege);
table_list->register_want_access(SELECT_ACL); table_list->register_want_access(SELECT_ACL);
#endif #endif
if (setup_fields(thd, 0, stmt->lex->value_list, MARK_COLUMNS_NONE, 0, 0) || if (setup_fields(thd, 0, stmt->lex->value_list, MARK_COLUMNS_NONE, 0, NULL,
0) ||
check_unique_table(thd, table_list)) check_unique_table(thd, table_list))
goto error; goto error;
/* TODO: here we should send types of placeholders to the client. */ /* TODO: here we should send types of placeholders to the client. */
@ -1575,7 +1576,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt,
if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL, if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL,
DT_PREPARE | DT_CREATE)) DT_PREPARE | DT_CREATE))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
DBUG_RETURN(setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, 0)); DBUG_RETURN(setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, NULL, 0));
} }

View File

@ -724,7 +724,7 @@ JOIN::prepare(Item ***rref_pointer_array,
wild_num)) || wild_num)) ||
select_lex->setup_ref_array(thd, real_og_num) || select_lex->setup_ref_array(thd, real_og_num) ||
setup_fields(thd, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ, setup_fields(thd, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
&all_fields, 1) || &all_fields, &select_lex->pre_fix, 1) ||
setup_without_group(thd, (*rref_pointer_array), tables_list, setup_without_group(thd, (*rref_pointer_array), tables_list,
select_lex->leaf_tables, fields_list, select_lex->leaf_tables, fields_list,
all_fields, &conds, order, group_list, all_fields, &conds, order, group_list,

View File

@ -361,7 +361,7 @@ int mysql_update(THD *thd,
table_list->grant.want_privilege= table->grant.want_privilege= table_list->grant.want_privilege= table->grant.want_privilege=
(SELECT_ACL & ~table->grant.privilege); (SELECT_ACL & ~table->grant.privilege);
#endif #endif
if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0)) if (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, NULL, 0))
{ {
free_underlaid_joins(thd, select_lex); free_underlaid_joins(thd, select_lex);
DBUG_RETURN(1); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */
@ -1521,7 +1521,7 @@ int multi_update::prepare(List<Item> &not_used_values,
reference tables reference tables
*/ */
int error= setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0); int error= setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, NULL, 0);
ti.rewind(); ti.rewind();
while ((table_ref= ti++)) while ((table_ref= ti++))

View File

@ -33,6 +33,7 @@
/* Structs that defines the TABLE */ /* Structs that defines the TABLE */
class Item; /* Needed by ORDER */ class Item; /* Needed by ORDER */
typedef Item (*Item_ptr);
class Item_subselect; class Item_subselect;
class Item_field; class Item_field;
class GRANT_TABLE; class GRANT_TABLE;
@ -2348,7 +2349,7 @@ typedef struct st_nested_join
table_map sj_depends_on; table_map sj_depends_on;
/* Outer non-trivially correlated tables */ /* Outer non-trivially correlated tables */
table_map sj_corr_tables; table_map sj_corr_tables;
List<Item> sj_outer_expr_list; List<Item_ptr> sj_outer_expr_list;
/** /**
True if this join nest node is completely covered by the query execution True if this join nest node is completely covered by the query execution
plan. This means two things. plan. This means two things.