Commit 54bb28d4 authored by unknown's avatar unknown

MDEV-486 LP BUG#1010116 fix.

Link view/derived table fields to a real table to check turning the table record to null row.

Item_direct_view_ref wrapper now checks if table is turned to null row.
parent 589c62fe
......@@ -1677,7 +1677,6 @@ SELECT t.b, t.c, t1.a
FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
WHERE t.b AND t.c = t1.a;
b c a
8 c c
EXPLAIN EXTENDED
SELECT t.b, t.c, t1.a
FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
......@@ -1692,7 +1691,6 @@ SELECT t.b, t.c, t1.a
FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
WHERE t.b <> 0 AND t.c = t1.a;
b c a
8 c c
INSERT INTO t3 VALUES (100), (200);
EXPLAIN EXTENDED
SELECT t.b, t.c, t1.a
......@@ -1708,7 +1706,7 @@ SELECT t.b, t.c, t1.a
FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
WHERE t.b AND t.c = t1.a;
b c a
8 c c
NULL NULL c
EXPLAIN EXTENDED
SELECT t.b, t.c, t1.a
FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
......@@ -1723,7 +1721,7 @@ SELECT t.b, t.c, t1.a
FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
WHERE t.b <> 0 AND t.c = t1.a;
b c a
8 c c
NULL NULL c
SET optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2,t3;
#
......
......@@ -4485,6 +4485,39 @@ a
1
drop view v2,v1;
drop table t1;
#
# MDEV-486 LP BUG#1010116 Incorrect query results in
# view and derived tables
#
SELECT
`Derived1`.`id`,
`Derived2`.`Val1`
FROM (select 30631 as `id`) AS `Derived1` LEFT OUTER JOIN (SELECT
2 as `id`,
1 AS `Val1`
FROM (select 30631 as `id`) AS `Derived3`) AS `Derived2` ON `Derived1`.`id` = `Derived2`.`id`;
id Val1
30631 NULL
create table t1 ( id int );
insert into t1 values (30631);
create table t2 ( id int );
insert into t2 values (30631);
create algorithm=MERGE view v2 as select 2 as id, 1 as val1 from t2;
select t1.*, v2.* from t1 left join v2 on t1.id = v2.id;
id id val1
30631 NULL NULL
drop view v2;
drop table t1,t2;
create table t1 ( id int );
insert into t1 values (30631);
create table t2 ( id int );
insert into t2 values (30631);
create algorithm=MERGE view v2 as select 2 as id, id is null as bbb, id as iddqd, 1 as val1 from t2;
select t1.*, v2.* from t1 left join v2 on t1.id = v2.id;
id id bbb iddqd val1
30631 NULL NULL NULL NULL
drop view v2;
drop table t1,t2;
# -----------------------------------------------------------------
# -- End of 5.3 tests.
# -----------------------------------------------------------------
......
......@@ -4433,6 +4433,36 @@ select * from t1;
drop view v2,v1;
drop table t1;
--echo #
--echo # MDEV-486 LP BUG#1010116 Incorrect query results in
--echo # view and derived tables
--echo #
SELECT
`Derived1`.`id`,
`Derived2`.`Val1`
FROM (select 30631 as `id`) AS `Derived1` LEFT OUTER JOIN (SELECT
2 as `id`,
1 AS `Val1`
FROM (select 30631 as `id`) AS `Derived3`) AS `Derived2` ON `Derived1`.`id` = `Derived2`.`id`;
create table t1 ( id int );
insert into t1 values (30631);
create table t2 ( id int );
insert into t2 values (30631);
create algorithm=MERGE view v2 as select 2 as id, 1 as val1 from t2;
select t1.*, v2.* from t1 left join v2 on t1.id = v2.id;
drop view v2;
drop table t1,t2;
create table t1 ( id int );
insert into t1 values (30631);
create table t2 ( id int );
insert into t2 values (30631);
create algorithm=MERGE view v2 as select 2 as id, id is null as bbb, id as iddqd, 1 as val1 from t2;
select t1.*, v2.* from t1 left join v2 on t1.id = v2.id;
drop view v2;
drop table t1,t2;
--echo # -----------------------------------------------------------------
--echo # -- End of 5.3 tests.
--echo # -----------------------------------------------------------------
......
......@@ -7339,6 +7339,7 @@ Item* Item_cache_wrapper::get_tmp_table_item(THD *thd_arg)
bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
{
DBUG_ASSERT(1);
/* view fild reference must be defined */
DBUG_ASSERT(*ref);
/* (*ref)->check_cols() will be made in Item_direct_ref::fix_fields */
......
......@@ -2925,20 +2925,29 @@ class Item_direct_view_ref :public Item_direct_ref
{
Item_equal *item_equal;
TABLE_LIST *view;
TABLE *null_ref_table;
bool check_null_ref()
{
if (null_ref_table == NULL)
{
null_ref_table= view->get_real_join_table();
}
if (null_ref_table->null_row)
{
null_value= 1;
return TRUE;
}
return FALSE;
}
public:
Item_direct_view_ref(Name_resolution_context *context_arg, Item **item,
const char *table_name_arg,
const char *field_name_arg,
TABLE_LIST *view_arg)
:Item_direct_ref(context_arg, item, table_name_arg, field_name_arg),
item_equal(0), view(view_arg) {}
/* Constructor need to process subselect with temporary tables (see Item) */
Item_direct_view_ref(THD *thd, Item_direct_ref *item)
:Item_direct_ref(thd, item), item_equal(0) {}
Item_direct_view_ref(TABLE_LIST *view_arg, Item **item,
const char *field_name_arg)
:Item_direct_ref(view_arg, item, field_name_arg), item_equal(0)
{}
item_equal(0), view(view_arg),
null_ref_table(NULL) {}
bool fix_fields(THD *, Item **);
bool eq(const Item *item, bool binary_cmp) const;
......@@ -2969,6 +2978,84 @@ class Item_direct_view_ref :public Item_direct_ref
view_arg->view_used_tables|= (*ref)->used_tables();
return 0;
}
void save_val(Field *to)
{
if (check_null_ref())
to->set_null();
else
Item_direct_ref::save_val(to);
}
double val_real()
{
if (check_null_ref())
return 0;
else
return Item_direct_ref::val_real();
}
longlong val_int()
{
if (check_null_ref())
return 0;
else
return Item_direct_ref::val_int();
}
String *val_str(String* tmp)
{
if (check_null_ref())
return NULL;
else
return Item_direct_ref::val_str(tmp);
}
my_decimal *val_decimal(my_decimal *tmp)
{
if (check_null_ref())
return NULL;
else
return Item_direct_ref::val_decimal(tmp);
}
bool val_bool()
{
if (check_null_ref())
return 0;
else
return Item_direct_ref::val_bool();
}
bool is_null()
{
if (check_null_ref())
return 1;
else
return Item_direct_ref::is_null();
}
bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
if (check_null_ref())
{
bzero((char*) ltime,sizeof(*ltime));
return 1;
}
return Item_direct_ref::get_date(ltime, fuzzydate);
}
bool send(Protocol *protocol, String *buffer)
{
if (check_null_ref())
return protocol->store_null();
return Item_direct_ref::send(protocol, buffer);
}
void save_org_in_field(Field *field)
{
if (check_null_ref())
field->set_null();
else
Item_direct_ref::save_val(field);
}
void save_in_result_field(bool no_conversions)
{
if (check_null_ref())
result_field->set_null();
else
Item_direct_ref::save_in_result_field(no_conversions);
}
};
......
......@@ -4441,6 +4441,28 @@ void TABLE_LIST::set_check_materialized()
}
}
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)
break;
/* we do not support merging of union yet */
DBUG_ASSERT(tbl->view == NULL ||
tbl->view->select_lex.next_select() == NULL);
DBUG_ASSERT(tbl->derived == NULL ||
tbl->derived->first_select()->next_select() == NULL);
if (tbl->table)
table= tbl->table;
tbl= (tbl->view != NULL ?
tbl->view->select_lex.get_table_list() :
tbl->derived->first_select()->get_table_list());
}
return tbl->table;
}
Natural_join_column::Natural_join_column(Field_translator *field_param,
TABLE_LIST *tab)
......
......@@ -1671,6 +1671,7 @@ struct TABLE_LIST
TABLE_LIST *find_underlying_table(TABLE *table);
TABLE_LIST *first_leaf_for_name_resolution();
TABLE_LIST *last_leaf_for_name_resolution();
TABLE *get_real_join_table();
bool is_leaf_for_name_resolution();
inline TABLE_LIST *top_table()
{ return belong_to_view ? belong_to_view : this; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment