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:
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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");
|
||||||
|
@ -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 *);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
||||||
/*
|
/*
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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> ¬_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++))
|
||||||
|
@ -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.
|
||||||
|
Reference in New Issue
Block a user