Commit fb22eb13 authored by Igor Babaev's avatar Igor Babaev

Fixed LP bug #798576.

If a view/derived table is non-mergeable then the definition of the tmp table
to store the rows for it is created at the prepare stage. In this case if the
view definition uses outer joins and a view column belongs to an inner table
of one of them then the column should be considered as nullable independently
on nullability of the underlying column. If the underlying column happens to be
defined as non-nullable then the function create_tmp_field_from_item rather 
than the function create_tmp_field_from_field should be employed to create
the definition of the interesting column in the tmp table.
 
parent 7880039f
...@@ -4207,3 +4207,25 @@ Warnings: ...@@ -4207,3 +4207,25 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where ((`test`.`t1`.`b` = 1) or ((`test`.`t1`.`a` = 'a') and (length(`test`.`t1`.`a`) >= `test`.`t1`.`b`))) Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where ((`test`.`t1`.`b` = 1) or ((`test`.`t1`.`a` = 'a') and (length(`test`.`t1`.`a`) >= `test`.`t1`.`b`)))
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# Bug#798576: abort on a GROUP BY query over a view with left join
# that can be converted to inner join
#
CREATE TABLE t1 (a int NOT NULL , b int NOT NULL) ;
INSERT INTO t1 VALUES (214,0), (6,6), (6,0), (7,0);
CREATE TABLE t2 (b int) ;
INSERT INTO t2 VALUES (88), (78), (6);
CREATE ALGORITHM=MERGE VIEW v1 AS
SELECT t1.a, t2.b FROM (t2 LEFT JOIN t1 ON t2.b > t1.a) WHERE t1.b <= 0;
SELECT * FROM v1;
a b
6 88
6 78
7 88
7 78
SELECT a, MIN(b) FROM v1 GROUP BY a;
a MIN(b)
6 78
7 78
DROP VIEW v1;
DROP TABLE t1,t2;
...@@ -4155,3 +4155,24 @@ SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a ...@@ -4155,3 +4155,24 @@ SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # Bug#798576: abort on a GROUP BY query over a view with left join
--echo # that can be converted to inner join
--echo #
CREATE TABLE t1 (a int NOT NULL , b int NOT NULL) ;
INSERT INTO t1 VALUES (214,0), (6,6), (6,0), (7,0);
CREATE TABLE t2 (b int) ;
INSERT INTO t2 VALUES (88), (78), (6);
CREATE ALGORITHM=MERGE VIEW v1 AS
SELECT t1.a, t2.b FROM (t2 LEFT JOIN t1 ON t2.b > t1.a) WHERE t1.b <= 0;
SELECT * FROM v1;
SELECT a, MIN(b) FROM v1 GROUP BY a;
DROP VIEW v1;
DROP TABLE t1,t2;
...@@ -814,6 +814,7 @@ THD::THD() ...@@ -814,6 +814,7 @@ THD::THD()
memset(&invoker_user, 0, sizeof(invoker_user)); memset(&invoker_user, 0, sizeof(invoker_user));
memset(&invoker_host, 0, sizeof(invoker_host)); memset(&invoker_host, 0, sizeof(invoker_host));
prepare_derived_at_open= FALSE; prepare_derived_at_open= FALSE;
create_tmp_table_for_derived= FALSE;
} }
......
...@@ -1571,6 +1571,12 @@ public: ...@@ -1571,6 +1571,12 @@ public:
bool prepare_derived_at_open; bool prepare_derived_at_open;
/*
To signal that the tmp table to be created is created for materialized
derived table or a view.
*/
bool create_tmp_table_for_derived;
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
int binlog_setup_trx_data(); int binlog_setup_trx_data();
......
...@@ -659,13 +659,18 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) ...@@ -659,13 +659,18 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
!unit->union_distinct->next_select() (i.e. it is union and last distinct !unit->union_distinct->next_select() (i.e. it is union and last distinct
SELECT is last SELECT of UNION). SELECT is last SELECT of UNION).
*/ */
thd->create_tmp_table_for_derived= TRUE;
if (derived->derived_result->create_result_table(thd, &unit->types, FALSE, if (derived->derived_result->create_result_table(thd, &unit->types, FALSE,
(first_select->options | (first_select->options |
thd->options | thd->options |
TMP_TABLE_ALL_COLUMNS), TMP_TABLE_ALL_COLUMNS),
derived->alias, derived->alias,
FALSE, FALSE)) FALSE, FALSE))
{
thd->create_tmp_table_for_derived= FALSE;
goto exit; goto exit;
}
thd->create_tmp_table_for_derived= FALSE;
derived->table= derived->derived_result->table; derived->table= derived->derived_result->table;
if (derived->is_derived() && derived->is_merged_derived()) if (derived->is_derived() && derived->is_merged_derived())
......
...@@ -12772,8 +12772,9 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, ...@@ -12772,8 +12772,9 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
If item have to be able to store NULLs but underlaid field can't do it, If item have to be able to store NULLs but underlaid field can't do it,
create_tmp_field_from_field() can't be used for tmp field creation. create_tmp_field_from_field() can't be used for tmp field creation.
*/ */
if (((field->maybe_null && field->in_rollup) || if (((field->maybe_null && field->in_rollup) ||
(orig_item && orig_item->maybe_null)) && /* for outer joined views/dt*/ (thd->create_tmp_table_for_derived && /* for mat. view/dt */
orig_item && orig_item->maybe_null)) &&
!field->field->maybe_null()) !field->field->maybe_null())
{ {
bool save_maybe_null= FALSE; bool save_maybe_null= FALSE;
......
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