mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Fix of LP bug#992380 + revise fix_fields about missing with_subselect collection
The problem is that some fix_fields do not call Item_func::fix_fields and do not collect with subselect_information.
This commit is contained in:
@ -279,3 +279,44 @@ NULL
|
||||
SELECT GREATEST(1.5E+2,1.3E+2,NULL) FROM DUAL;
|
||||
GREATEST(1.5E+2,1.3E+2,NULL)
|
||||
NULL
|
||||
create table t1 (a int);
|
||||
insert into t1 values (1), (100), (0), (NULL);
|
||||
select not a from t1;
|
||||
not a
|
||||
0
|
||||
0
|
||||
1
|
||||
NULL
|
||||
explain extended select not a from t1;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00
|
||||
Warnings:
|
||||
Note 1003 select (`test`.`t1`.`a` = 0) AS `not a` from `test`.`t1`
|
||||
select * from t1 where not a;
|
||||
a
|
||||
0
|
||||
explain extended select * from t1 where not a;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = 0)
|
||||
select not (a+0) from t1;
|
||||
not (a+0)
|
||||
0
|
||||
0
|
||||
1
|
||||
NULL
|
||||
explain extended select not (a+0) from t1;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00
|
||||
Warnings:
|
||||
Note 1003 select (not((`test`.`t1`.`a` + 0))) AS `not (a+0)` from `test`.`t1`
|
||||
select * from t1 where not (a+0);
|
||||
a
|
||||
0
|
||||
explain extended select * from t1 where not (a+0);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (not((`test`.`t1`.`a` + 0)))
|
||||
drop table t1;
|
||||
|
@ -321,7 +321,7 @@ select * from t1 where not(NULL or a);
|
||||
a
|
||||
explain select * from t1 where not(NULL and a);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL a 5 NULL 21 Using where; Using index
|
||||
1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
|
||||
select * from t1 where not(NULL and a);
|
||||
a
|
||||
0
|
||||
@ -387,5 +387,5 @@ explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE t1 range a a 5 NULL 4 100.00 Using where; Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or `test`.`t1`.`a`) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where (`test`.`t1`.`a` <> 0) having (`test`.`t1`.`a` <> 0)
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or (`test`.`t1`.`a` <> 0)) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where (`test`.`t1`.`a` <> 0) having (`test`.`t1`.`a` <> 0)
|
||||
drop table t1;
|
||||
|
@ -3040,3 +3040,59 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests.
|
||||
#
|
||||
# LP bug#1001500 Crash on the second execution of the PS for
|
||||
# a query with degenerated conjunctive condition
|
||||
# (see also mysql bug#12582849)
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
pk INTEGER AUTO_INCREMENT,
|
||||
col_int_nokey INTEGER,
|
||||
col_int_key INTEGER,
|
||||
col_varchar_key VARCHAR(1),
|
||||
col_varchar_nokey VARCHAR(1),
|
||||
PRIMARY KEY (pk),
|
||||
KEY (col_int_key),
|
||||
KEY (col_varchar_key, col_int_key)
|
||||
);
|
||||
INSERT INTO t1 (
|
||||
col_int_key, col_int_nokey,
|
||||
col_varchar_key, col_varchar_nokey
|
||||
) VALUES
|
||||
(4, 2, 'v', 'v'),
|
||||
(62, 150, 'v', 'v');
|
||||
CREATE TABLE t2 (
|
||||
pk INTEGER AUTO_INCREMENT,
|
||||
col_int_nokey INTEGER,
|
||||
col_int_key INTEGER,
|
||||
col_varchar_key VARCHAR(1),
|
||||
col_varchar_nokey VARCHAR(1),
|
||||
PRIMARY KEY (pk),
|
||||
KEY (col_int_key),
|
||||
KEY (col_varchar_key, col_int_key)
|
||||
);
|
||||
INSERT INTO t2 (
|
||||
col_int_key, col_int_nokey,
|
||||
col_varchar_key, col_varchar_nokey
|
||||
) VALUES
|
||||
(8, NULL, 'x', 'x'),
|
||||
(7, 8, 'd', 'd');
|
||||
PREPARE stmt FROM '
|
||||
SELECT
|
||||
( SELECT MAX( SQ1_alias2 .col_int_nokey ) AS SQ1_field1
|
||||
FROM ( t2 AS SQ1_alias1 RIGHT JOIN t1 AS SQ1_alias2
|
||||
ON ( SQ1_alias2.col_varchar_key = SQ1_alias1.col_varchar_nokey )
|
||||
)
|
||||
WHERE SQ1_alias2.pk < alias1.col_int_nokey OR alias1.pk
|
||||
) AS field1
|
||||
FROM ( t1 AS alias1 JOIN t2 AS alias2 ON alias2.pk )
|
||||
GROUP BY field1
|
||||
';
|
||||
EXECUTE stmt;
|
||||
field1
|
||||
150
|
||||
EXECUTE stmt;
|
||||
field1
|
||||
150
|
||||
DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1, t2;
|
||||
|
@ -160,3 +160,23 @@ SELECT LEAST(1.1,1.2,NULL,1.0) FROM DUAL;
|
||||
SELECT GREATEST(1.5E+2,1.3E+2,NULL) FROM DUAL;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
# test of replacing NOT <field>
|
||||
#
|
||||
create table t1 (a int);
|
||||
insert into t1 values (1), (100), (0), (NULL);
|
||||
|
||||
select not a from t1;
|
||||
explain extended select not a from t1;
|
||||
|
||||
select * from t1 where not a;
|
||||
explain extended select * from t1 where not a;
|
||||
|
||||
select not (a+0) from t1;
|
||||
explain extended select not (a+0) from t1;
|
||||
|
||||
select * from t1 where not (a+0);
|
||||
explain extended select * from t1 where not (a+0);
|
||||
|
||||
drop table t1;
|
||||
|
@ -3102,3 +3102,68 @@ DEALLOCATE PREPARE stmt;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 5.1 tests.
|
||||
|
||||
--echo #
|
||||
--echo # LP bug#1001500 Crash on the second execution of the PS for
|
||||
--echo # a query with degenerated conjunctive condition
|
||||
--echo # (see also mysql bug#12582849)
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (
|
||||
pk INTEGER AUTO_INCREMENT,
|
||||
col_int_nokey INTEGER,
|
||||
col_int_key INTEGER,
|
||||
|
||||
col_varchar_key VARCHAR(1),
|
||||
col_varchar_nokey VARCHAR(1),
|
||||
|
||||
PRIMARY KEY (pk),
|
||||
KEY (col_int_key),
|
||||
KEY (col_varchar_key, col_int_key)
|
||||
);
|
||||
|
||||
INSERT INTO t1 (
|
||||
col_int_key, col_int_nokey,
|
||||
col_varchar_key, col_varchar_nokey
|
||||
) VALUES
|
||||
(4, 2, 'v', 'v'),
|
||||
(62, 150, 'v', 'v');
|
||||
|
||||
CREATE TABLE t2 (
|
||||
pk INTEGER AUTO_INCREMENT,
|
||||
col_int_nokey INTEGER,
|
||||
col_int_key INTEGER,
|
||||
|
||||
col_varchar_key VARCHAR(1),
|
||||
col_varchar_nokey VARCHAR(1),
|
||||
|
||||
PRIMARY KEY (pk),
|
||||
KEY (col_int_key),
|
||||
KEY (col_varchar_key, col_int_key)
|
||||
);
|
||||
|
||||
INSERT INTO t2 (
|
||||
col_int_key, col_int_nokey,
|
||||
col_varchar_key, col_varchar_nokey
|
||||
) VALUES
|
||||
(8, NULL, 'x', 'x'),
|
||||
(7, 8, 'd', 'd');
|
||||
|
||||
PREPARE stmt FROM '
|
||||
SELECT
|
||||
( SELECT MAX( SQ1_alias2 .col_int_nokey ) AS SQ1_field1
|
||||
FROM ( t2 AS SQ1_alias1 RIGHT JOIN t1 AS SQ1_alias2
|
||||
ON ( SQ1_alias2.col_varchar_key = SQ1_alias1.col_varchar_nokey )
|
||||
)
|
||||
WHERE SQ1_alias2.pk < alias1.col_int_nokey OR alias1.pk
|
||||
) AS field1
|
||||
FROM ( t1 AS alias1 JOIN t2 AS alias2 ON alias2.pk )
|
||||
GROUP BY field1
|
||||
';
|
||||
|
||||
EXECUTE stmt;
|
||||
EXECUTE stmt;
|
||||
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
@ -4271,6 +4271,22 @@ Item_cond::fix_fields(THD *thd, Item **ref)
|
||||
if (abort_on_null)
|
||||
item->top_level_item();
|
||||
|
||||
/*
|
||||
replace degraded condition:
|
||||
was: <field>
|
||||
become: <field> = 1
|
||||
*/
|
||||
if (item->type() == FIELD_ITEM)
|
||||
{
|
||||
Query_arena backup, *arena;
|
||||
Item *new_item;
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
if ((new_item= new Item_func_ne(item, new Item_int(0, 1))))
|
||||
li.replace(item= new_item);
|
||||
if (arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
}
|
||||
|
||||
// item can be substituted in fix_fields
|
||||
if ((!item->fixed &&
|
||||
item->fix_fields(thd, li.ref())) ||
|
||||
@ -5283,6 +5299,28 @@ Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */
|
||||
}
|
||||
|
||||
|
||||
bool Item_func_not::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
if (args[0]->type() == FIELD_ITEM)
|
||||
{
|
||||
/* replace "NOT <field>" with "<filed> == 0" */
|
||||
Query_arena backup, *arena;
|
||||
Item *new_item;
|
||||
bool rc= TRUE;
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
if ((new_item= new Item_func_eq(args[0], new Item_int(0, 1))))
|
||||
{
|
||||
new_item->name= name;
|
||||
rc= (*ref= new_item)->fix_fields(thd, ref);
|
||||
}
|
||||
if (arena)
|
||||
thd->restore_active_arena(arena, &backup);
|
||||
return rc;
|
||||
}
|
||||
return Item_func::fix_fields(thd, ref);
|
||||
}
|
||||
|
||||
|
||||
Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
|
||||
{
|
||||
Item *item= negated_item();
|
||||
|
@ -413,6 +413,7 @@ public:
|
||||
enum Functype functype() const { return NOT_FUNC; }
|
||||
const char *func_name() const { return "not"; }
|
||||
Item *neg_transformer(THD *thd);
|
||||
bool fix_fields(THD *, Item **);
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
};
|
||||
|
||||
@ -479,6 +480,8 @@ public:
|
||||
longlong val_int();
|
||||
enum Functype functype() const { return NOT_ALL_FUNC; }
|
||||
const char *func_name() const { return "<not>"; }
|
||||
bool fix_fields(THD *thd, Item **ref)
|
||||
{return Item_func::fix_fields(thd, ref);}
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
|
||||
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
|
||||
|
Reference in New Issue
Block a user