[Commits] Rev 3565: MDEV-486 LP BUG#1010116 fix. in file:///home/bell/maria/bzr/work-maria-5.3-MDEV-486/
sanja at askmonty.org
sanja at askmonty.org
Tue Sep 4 13:09:21 EEST 2012
At file:///home/bell/maria/bzr/work-maria-5.3-MDEV-486/
------------------------------------------------------------
revno: 3565
revision-id: sanja at askmonty.org-20120904100919-xc8mo81oel2kgl7b
parent: sergii at pisem.net-20120824214318-ra5ipntw7udwfoki
committer: sanja at askmonty.org
branch nick: work-maria-5.3-MDEV-486
timestamp: Tue 2012-09-04 13:09:19 +0300
message:
MDEV-486 LP BUG#1010116 fix.
Link view/derived table fields linked to a real table to check turnng record to NULL.
Item_direct_view_ref wrapper now checks if table turned to NULL.
-------------- next part --------------
=== modified file 'mysql-test/r/view.result'
--- a/mysql-test/r/view.result 2012-06-26 18:43:34 +0000
+++ b/mysql-test/r/view.result 2012-09-04 10:09:19 +0000
@@ -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.
# -----------------------------------------------------------------
=== modified file 'mysql-test/t/view.test'
--- a/mysql-test/t/view.test 2012-06-26 18:43:34 +0000
+++ b/mysql-test/t/view.test 2012-09-04 10:09:19 +0000
@@ -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 # -----------------------------------------------------------------
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2012-08-24 13:39:34 +0000
+++ b/sql/item.cc 2012-09-04 10:09:19 +0000
@@ -7339,6 +7339,7 @@ Item* Item_cache_wrapper::get_tmp_table_
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 */
=== modified file 'sql/item.h'
--- a/sql/item.h 2012-08-24 12:02:32 +0000
+++ b/sql/item.h 2012-09-04 10:09:19 +0000
@@ -2925,20 +2925,23 @@ class Item_direct_view_ref :public Item_
{
Item_equal *item_equal;
TABLE_LIST *view;
+ TABLE *null_ref_table;
+
+ void check_null_ref()
+ {
+ if (null_ref_table == NULL)
+ {
+ null_ref_table= view->get_any_real_table();
+ }
+ }
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 +2972,113 @@ public:
view_arg->view_used_tables|= (*ref)->used_tables();
return 0;
}
+ void save_val(Field *to)
+ {
+ check_null_ref();
+ if (null_ref_table->null_row)
+ to->set_null();
+ else
+ Item_direct_ref::save_val(to);
+ }
+ double val_real()
+ {
+ check_null_ref();
+ if (null_ref_table->null_row)
+ {
+ null_value= 1;
+ return 0;
+ }
+ else
+ return Item_direct_ref::val_real();
+ }
+ longlong val_int()
+ {
+ check_null_ref();
+ if (null_ref_table->null_row)
+ {
+ null_value= 1;
+ return 0;
+ }
+ else
+ return Item_direct_ref::val_int();
+ }
+ String *val_str(String* tmp)
+ {
+ check_null_ref();
+ if (null_ref_table->null_row)
+ {
+ null_value= 1;
+ return NULL;
+ }
+ else
+ return Item_direct_ref::val_str(tmp);
+ }
+ my_decimal *val_decimal(my_decimal *tmp)
+ {
+ check_null_ref();
+ if (null_ref_table->null_row)
+ {
+ null_value= 1;
+ return NULL;
+ }
+ else
+ return Item_direct_ref::val_decimal(tmp);
+ }
+ bool val_bool()
+ {
+ check_null_ref();
+ if (null_ref_table->null_row)
+ {
+ null_value= 1;
+ return 0;
+ }
+ else
+ return Item_direct_ref::val_bool();
+ }
+ bool is_null()
+ {
+ check_null_ref();
+ if (null_ref_table->null_row)
+ {
+ null_value= 1;
+ return 1;
+ }
+ else
+ return Item_direct_ref::is_null();
+ }
+ bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
+ {
+ check_null_ref();
+ if (null_ref_table->null_row)
+ {
+ bzero((char*) ltime,sizeof(*ltime));
+ return 1;
+ }
+ return Item_direct_ref::get_date(ltime, fuzzydate);
+ }
+ bool send(Protocol *protocol, String *buffer)
+ {
+ check_null_ref();
+ if (null_ref_table->null_row)
+ return protocol->store_null();
+ return Item_direct_ref::send(protocol, buffer);
+ }
+ void save_org_in_field(Field *field)
+ {
+ check_null_ref();
+ if (null_ref_table->null_row)
+ field->set_null();
+ else
+ Item_direct_ref::save_val(field);
+ }
+ void save_in_result_field(bool no_conversions)
+ {
+ check_null_ref();
+ if (null_ref_table->null_row)
+ result_field->set_null();
+ else
+ Item_direct_ref::save_in_result_field(no_conversions);
+ }
};
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2012-06-26 18:43:34 +0000
+++ b/sql/table.cc 2012-09-04 10:09:19 +0000
@@ -4441,6 +4441,28 @@ void TABLE_LIST::set_check_materialized(
}
}
+TABLE *TABLE_LIST::get_any_real_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)
=== modified file 'sql/table.h'
--- a/sql/table.h 2012-04-20 19:09:16 +0000
+++ b/sql/table.h 2012-09-04 10:09:19 +0000
@@ -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_any_real_table();
bool is_leaf_for_name_resolution();
inline TABLE_LIST *top_table()
{ return belong_to_view ? belong_to_view : this; }
More information about the commits
mailing list