mirror of
https://github.com/MariaDB/server.git
synced 2025-03-29 18:35:35 +01:00
fix for MDEV-367
The problem was that was_null and null_value variables was reset in each reexecution of IN subquery, but engine rerun only for non-constant subqueries. Fixed checking constant in Item_equal sort. Fix constant reporting in Item_subselect.
This commit is contained in:
parent
b02ad35e94
commit
4d2b05b7d7
9 changed files with 180 additions and 3 deletions
|
@ -6137,5 +6137,31 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
|
|||
SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
|
||||
min_a a
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-367: Different results with and without subquery_cache on
|
||||
# a query with a constant NOT IN condition
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1),(2),(3);
|
||||
set @mdev367_optimizer_switch = @@optimizer_switch;
|
||||
set optimizer_switch = 'subquery_cache=on';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
a
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
|
||||
1 NULL
|
||||
2 NULL
|
||||
3 NULL
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
set optimizer_switch = 'subquery_cache=off';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
a
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
|
||||
1 NULL
|
||||
2 NULL
|
||||
3 NULL
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
DROP TABLE t1;
|
||||
# return optimizer switch changed in the beginning of this test
|
||||
set optimizer_switch=@subselect_tmp;
|
||||
|
|
|
@ -6136,6 +6136,32 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
|
|||
SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
|
||||
min_a a
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-367: Different results with and without subquery_cache on
|
||||
# a query with a constant NOT IN condition
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1),(2),(3);
|
||||
set @mdev367_optimizer_switch = @@optimizer_switch;
|
||||
set optimizer_switch = 'subquery_cache=on';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
a
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
|
||||
1 NULL
|
||||
2 NULL
|
||||
3 NULL
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
set optimizer_switch = 'subquery_cache=off';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
a
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
|
||||
1 NULL
|
||||
2 NULL
|
||||
3 NULL
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
DROP TABLE t1;
|
||||
# return optimizer switch changed in the beginning of this test
|
||||
set optimizer_switch=@subselect_tmp;
|
||||
set optimizer_switch=default;
|
||||
|
|
|
@ -6132,6 +6132,32 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
|
|||
SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
|
||||
min_a a
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-367: Different results with and without subquery_cache on
|
||||
# a query with a constant NOT IN condition
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1),(2),(3);
|
||||
set @mdev367_optimizer_switch = @@optimizer_switch;
|
||||
set optimizer_switch = 'subquery_cache=on';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
a
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
|
||||
1 NULL
|
||||
2 NULL
|
||||
3 NULL
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
set optimizer_switch = 'subquery_cache=off';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
a
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
|
||||
1 NULL
|
||||
2 NULL
|
||||
3 NULL
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
DROP TABLE t1;
|
||||
# return optimizer switch changed in the beginning of this test
|
||||
set optimizer_switch=@subselect_tmp;
|
||||
set @optimizer_switch_for_subselect_test=null;
|
||||
|
|
|
@ -6143,6 +6143,32 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
|
|||
SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
|
||||
min_a a
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-367: Different results with and without subquery_cache on
|
||||
# a query with a constant NOT IN condition
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1),(2),(3);
|
||||
set @mdev367_optimizer_switch = @@optimizer_switch;
|
||||
set optimizer_switch = 'subquery_cache=on';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
a
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
|
||||
1 NULL
|
||||
2 NULL
|
||||
3 NULL
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
set optimizer_switch = 'subquery_cache=off';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
a
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
|
||||
1 NULL
|
||||
2 NULL
|
||||
3 NULL
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
DROP TABLE t1;
|
||||
# return optimizer switch changed in the beginning of this test
|
||||
set optimizer_switch=@subselect_tmp;
|
||||
set optimizer_switch=default;
|
||||
|
|
|
@ -6132,6 +6132,32 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
|
|||
SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 UNION select a+1 from t1 ) OR min_a != 1;
|
||||
min_a a
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-367: Different results with and without subquery_cache on
|
||||
# a query with a constant NOT IN condition
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1),(2),(3);
|
||||
set @mdev367_optimizer_switch = @@optimizer_switch;
|
||||
set optimizer_switch = 'subquery_cache=on';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
a
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
|
||||
1 NULL
|
||||
2 NULL
|
||||
3 NULL
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
set optimizer_switch = 'subquery_cache=off';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
a
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
a ( 3, 3 ) NOT IN ( SELECT NULL, NULL )
|
||||
1 NULL
|
||||
2 NULL
|
||||
3 NULL
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
DROP TABLE t1;
|
||||
# return optimizer switch changed in the beginning of this test
|
||||
set optimizer_switch=@subselect_tmp;
|
||||
set @optimizer_switch_for_subselect_test=null;
|
||||
|
|
|
@ -5208,5 +5208,26 @@ SELECT MIN(a) AS min_a, a FROM t1 WHERE 1=2 HAVING a NOT IN ( SELECT a from t1 U
|
|||
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-367: Different results with and without subquery_cache on
|
||||
--echo # a query with a constant NOT IN condition
|
||||
--echo #
|
||||
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1),(2),(3);
|
||||
|
||||
set @mdev367_optimizer_switch = @@optimizer_switch;
|
||||
|
||||
set optimizer_switch = 'subquery_cache=on';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
|
||||
set optimizer_switch = 'subquery_cache=off';
|
||||
SELECT * FROM t1 WHERE ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) OR a > 100;
|
||||
SELECT *, ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) FROM t1;
|
||||
set optimizer_switch=@mdev367_optimizer_switch;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo # return optimizer switch changed in the beginning of this test
|
||||
set optimizer_switch=@subselect_tmp;
|
||||
|
|
|
@ -765,7 +765,9 @@ table_map Item_subselect::used_tables() const
|
|||
|
||||
bool Item_subselect::const_item() const
|
||||
{
|
||||
return thd->lex->context_analysis_only ? FALSE : const_item_cache;
|
||||
return (thd->lex->context_analysis_only ?
|
||||
FALSE :
|
||||
forced_const || const_item_cache);
|
||||
}
|
||||
|
||||
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
|
||||
|
@ -1484,6 +1486,10 @@ double Item_in_subselect::val_real()
|
|||
*/
|
||||
DBUG_ASSERT(0);
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (forced_const)
|
||||
return value;
|
||||
DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
|
||||
! engine->is_executed());
|
||||
null_value= was_null= FALSE;
|
||||
if (exec())
|
||||
{
|
||||
|
@ -1504,6 +1510,10 @@ longlong Item_in_subselect::val_int()
|
|||
*/
|
||||
DBUG_ASSERT(0);
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (forced_const)
|
||||
return value;
|
||||
DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
|
||||
! engine->is_executed());
|
||||
null_value= was_null= FALSE;
|
||||
if (exec())
|
||||
{
|
||||
|
@ -1524,6 +1534,10 @@ String *Item_in_subselect::val_str(String *str)
|
|||
*/
|
||||
DBUG_ASSERT(0);
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (forced_const)
|
||||
goto value_is_ready;
|
||||
DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
|
||||
! engine->is_executed());
|
||||
null_value= was_null= FALSE;
|
||||
if (exec())
|
||||
{
|
||||
|
@ -1535,6 +1549,7 @@ String *Item_in_subselect::val_str(String *str)
|
|||
null_value= TRUE;
|
||||
return 0;
|
||||
}
|
||||
value_is_ready:
|
||||
str->set((ulonglong)value, &my_charset_bin);
|
||||
return str;
|
||||
}
|
||||
|
@ -1545,6 +1560,8 @@ bool Item_in_subselect::val_bool()
|
|||
DBUG_ASSERT(fixed == 1);
|
||||
if (forced_const)
|
||||
return value;
|
||||
DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
|
||||
! engine->is_executed());
|
||||
null_value= was_null= FALSE;
|
||||
if (exec())
|
||||
{
|
||||
|
@ -1563,6 +1580,10 @@ my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
|
|||
method should not be used
|
||||
*/
|
||||
DBUG_ASSERT(0);
|
||||
if (forced_const)
|
||||
goto value_is_ready;
|
||||
DBUG_ASSERT((engine->uncacheable() & ~UNCACHEABLE_EXPLAIN) ||
|
||||
! engine->is_executed());
|
||||
null_value= was_null= FALSE;
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (exec())
|
||||
|
@ -1572,6 +1593,7 @@ my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
|
|||
}
|
||||
if (was_null && !value)
|
||||
null_value= TRUE;
|
||||
value_is_ready:
|
||||
int2my_decimal(E_DEC_FATAL_ERROR, value, 0, decimal_value);
|
||||
return decimal_value;
|
||||
}
|
||||
|
@ -3117,6 +3139,8 @@ int subselect_single_select_engine::exec()
|
|||
tab->read_record.read_record= tab->save_read_record;
|
||||
}
|
||||
executed= 1;
|
||||
if (!(uncacheable() & ~UNCACHEABLE_EXPLAIN))
|
||||
item->make_const();
|
||||
thd->where= save_where;
|
||||
thd->lex->current_select= save_select;
|
||||
DBUG_RETURN(join->error || thd->is_fatal_error || thd->is_error());
|
||||
|
|
|
@ -11621,9 +11621,9 @@ static int compare_fields_by_table_order(Item *field1,
|
|||
bool outer_ref= 0;
|
||||
Item_field *f1= (Item_field *) (field1->real_item());
|
||||
Item_field *f2= (Item_field *) (field2->real_item());
|
||||
if (f1->const_item())
|
||||
if (field1->const_item() || f1->const_item())
|
||||
return 1;
|
||||
if (f2->const_item())
|
||||
if (field2->const_item() || f2->const_item())
|
||||
return -1;
|
||||
if (f2->used_tables() & OUTER_REF_TABLE_BIT)
|
||||
{
|
||||
|
|
|
@ -616,6 +616,8 @@ bool st_select_lex_unit::exec()
|
|||
if (executed && !uncacheable && !describe)
|
||||
DBUG_RETURN(FALSE);
|
||||
executed= 1;
|
||||
if (!(uncacheable & ~UNCACHEABLE_EXPLAIN) && item)
|
||||
item->make_const();
|
||||
|
||||
saved_error= optimize();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue