mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-6892: WHERE does not apply
Taking into account implicit dependence of constant view field from nullable table of left join added. Fixed finding real table to check if it turned to NULL (materialized view & derived taken into account) Removed incorrect uninitialization.
This commit is contained in:
@ -568,3 +568,15 @@ update t1 set balance=(select sum(balance) from (SELECT balance FROM t1 where ac
|
||||
set optimizer_switch=@save_derived_optimizer_switch_bug;
|
||||
drop table t1;
|
||||
set optimizer_switch=@save_derived_optimizer_switch;
|
||||
#
|
||||
# MDEV-6892: WHERE does not apply
|
||||
#
|
||||
create table t1 (id int);
|
||||
create table t2 (id int);
|
||||
insert into t1 values(1),(2),(3);
|
||||
insert into t2 values(4),(5),(6);
|
||||
select x.id, message from (select id from t1) x left join
|
||||
(select id, 1 as message from t2) y on x.id=y.id
|
||||
where coalesce(message,0) <> 0;
|
||||
id message
|
||||
drop table t1,t2;
|
||||
|
@ -492,5 +492,17 @@ update t1 set balance=(select sum(balance) from (SELECT balance FROM t1 where ac
|
||||
set optimizer_switch=@save_derived_optimizer_switch_bug;
|
||||
drop table t1;
|
||||
|
||||
|
||||
set optimizer_switch=@save_derived_optimizer_switch;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-6892: WHERE does not apply
|
||||
--echo #
|
||||
create table t1 (id int);
|
||||
create table t2 (id int);
|
||||
insert into t1 values(1),(2),(3);
|
||||
insert into t2 values(4),(5),(6);
|
||||
#explain extended
|
||||
select x.id, message from (select id from t1) x left join
|
||||
(select id, 1 as message from t2) y on x.id=y.id
|
||||
where coalesce(message,0) <> 0;
|
||||
drop table t1,t2;
|
||||
|
26
sql/item.cc
26
sql/item.cc
@ -7949,6 +7949,7 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
|
||||
return TRUE;
|
||||
if (view->table && view->table->maybe_null)
|
||||
maybe_null= TRUE;
|
||||
set_null_ref_table();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -9790,13 +9791,28 @@ void Item_ref::update_used_tables()
|
||||
(*ref)->update_used_tables();
|
||||
}
|
||||
|
||||
void Item_direct_view_ref::update_used_tables()
|
||||
{
|
||||
set_null_ref_table();
|
||||
Item_direct_ref::update_used_tables();
|
||||
}
|
||||
|
||||
|
||||
table_map Item_direct_view_ref::used_tables() const
|
||||
{
|
||||
return get_depended_from() ?
|
||||
OUTER_REF_TABLE_BIT :
|
||||
((view->is_merged_derived() || view->merged || !view->table) ?
|
||||
(*ref)->used_tables() :
|
||||
view->table->map);
|
||||
DBUG_ASSERT(null_ref_table);
|
||||
|
||||
if (get_depended_from())
|
||||
return OUTER_REF_TABLE_BIT;
|
||||
|
||||
if (view->is_merged_derived() || view->merged || !view->table)
|
||||
return ((*ref)->used_tables() ?
|
||||
(*ref)->used_tables() :
|
||||
((null_ref_table != NO_NULL_TABLE) ?
|
||||
null_ref_table->map :
|
||||
(table_map)0 ));
|
||||
|
||||
return view->table->map;
|
||||
}
|
||||
|
||||
table_map Item_direct_view_ref::not_null_tables() const
|
||||
|
22
sql/item.h
22
sql/item.h
@ -3315,13 +3315,16 @@ class Item_direct_view_ref :public Item_direct_ref
|
||||
|
||||
#define NO_NULL_TABLE (reinterpret_cast<TABLE *>(0x1))
|
||||
|
||||
void set_null_ref_table()
|
||||
{
|
||||
if (!view->is_inner_table_of_outer_join() ||
|
||||
!(null_ref_table= view->get_real_join_table()))
|
||||
null_ref_table= NO_NULL_TABLE;
|
||||
}
|
||||
|
||||
bool check_null_ref()
|
||||
{
|
||||
if (null_ref_table == NULL)
|
||||
{
|
||||
if (!(null_ref_table= view->get_real_join_table()))
|
||||
null_ref_table= NO_NULL_TABLE;
|
||||
}
|
||||
DBUG_ASSERT(null_ref_table);
|
||||
if (null_ref_table != NO_NULL_TABLE && null_ref_table->null_row)
|
||||
{
|
||||
null_value= 1;
|
||||
@ -3329,6 +3332,7 @@ class Item_direct_view_ref :public Item_direct_ref
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public:
|
||||
Item_direct_view_ref(Name_resolution_context *context_arg, Item **item,
|
||||
const char *table_name_arg,
|
||||
@ -3336,7 +3340,11 @@ public:
|
||||
TABLE_LIST *view_arg)
|
||||
:Item_direct_ref(context_arg, item, table_name_arg, field_name_arg),
|
||||
item_equal(0), view(view_arg),
|
||||
null_ref_table(NULL) {}
|
||||
null_ref_table(NULL)
|
||||
{
|
||||
if (fixed)
|
||||
set_null_ref_table();
|
||||
}
|
||||
|
||||
bool fix_fields(THD *, Item **);
|
||||
bool eq(const Item *item, bool binary_cmp) const;
|
||||
@ -3354,7 +3362,9 @@ public:
|
||||
Item *equal_fields_propagator(uchar *arg);
|
||||
Item *replace_equal_field(uchar *arg);
|
||||
table_map used_tables() const;
|
||||
void update_used_tables();
|
||||
table_map not_null_tables() const;
|
||||
bool const_item() const { return used_tables() == 0; }
|
||||
bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
|
||||
{
|
||||
return (*ref)->walk(processor, walk_subquery, arg) ||
|
||||
|
42
sql/table.cc
42
sql/table.cc
@ -5034,7 +5034,8 @@ TABLE *TABLE_LIST::get_real_join_table()
|
||||
TABLE_LIST *tbl= this;
|
||||
while (tbl->table == NULL || tbl->table->reginfo.join_tab == NULL)
|
||||
{
|
||||
if (tbl->view == NULL && tbl->derived == NULL)
|
||||
if ((tbl->view == NULL && tbl->derived == NULL) ||
|
||||
tbl->is_materialized_derived())
|
||||
break;
|
||||
/* we do not support merging of union yet */
|
||||
DBUG_ASSERT(tbl->view == NULL ||
|
||||
@ -5043,28 +5044,25 @@ TABLE *TABLE_LIST::get_real_join_table()
|
||||
tbl->derived->first_select()->next_select() == NULL);
|
||||
|
||||
{
|
||||
List_iterator_fast<TABLE_LIST> ti;
|
||||
List_iterator_fast<TABLE_LIST>
|
||||
ti(tbl->view != NULL ?
|
||||
tbl->view->select_lex.top_join_list :
|
||||
tbl->derived->first_select()->top_join_list);
|
||||
for (;;)
|
||||
{
|
||||
List_iterator_fast<TABLE_LIST>
|
||||
ti(tbl->view != NULL ?
|
||||
tbl->view->select_lex.top_join_list :
|
||||
tbl->derived->first_select()->top_join_list);
|
||||
for (;;)
|
||||
{
|
||||
tbl= NULL;
|
||||
/*
|
||||
Find left table in outer join on this level
|
||||
(the list is reverted).
|
||||
*/
|
||||
for (TABLE_LIST *t= ti++; t; t= ti++)
|
||||
tbl= t;
|
||||
if (!tbl)
|
||||
return NULL; // view/derived with no tables
|
||||
if (!tbl->nested_join)
|
||||
break;
|
||||
/* go deeper if we've found nested join */
|
||||
ti= tbl->nested_join->join_list;
|
||||
}
|
||||
tbl= NULL;
|
||||
/*
|
||||
Find left table in outer join on this level
|
||||
(the list is reverted).
|
||||
*/
|
||||
for (TABLE_LIST *t= ti++; t; t= ti++)
|
||||
tbl= t;
|
||||
if (!tbl)
|
||||
return NULL; // view/derived with no tables
|
||||
if (!tbl->nested_join)
|
||||
break;
|
||||
/* go deeper if we've found nested join */
|
||||
ti= tbl->nested_join->join_list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user