mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-30 18:36:12 +01:00 
			
		
		
		
	 5a8e6230d7
			
		
	
	
	5a8e6230d7
	
	
	
		
			
			normalize_cond() translated `WHERE col` into `WHERE col<>0`
But the opetator "not equal to 0" does not necessarily exists
for all data types.
For example, the query:
  SELECT * FROM t1 WHERE inet6col;
was translated to:
  SELECT * FROM t1 WHERE inet6col<>0;
which further failed with this error:
  ERROR : Illegal parameter data types inet6 and bigint for operation '<>'
This patch changes the translation from `col<>0` to `col IS TRUE`.
So now
  SELECT * FROM t1 WHERE inet6col;
gets translated to:
  SELECT * FROM t1 WHERE inet6col IS TRUE;
Details:
1. Implementing methods:
   - Field_longstr::val_bool()
   - Field_string::val_bool()
   - Item::val_int_from_val_str()
   If the input contains bad data,
   these methods raise a better error message:
     Truncated incorrect BOOLEAN value
   Before the change, the error was:
     Truncated incorrect DOUBLE value
2. Fixing normalize_cond() to generate Item_func_istrue/Item_func_isfalse
   instances instead of Item_func_ne/Item_func_eq
3. Making Item_func_truth sargable, so it uses the range optimizer.
   Implementing the following methods:
   - get_mm_tree(), get_mm_leaf(), add_key_fields() in Item_func_truth.
   - get_func_mm_tree(), for all Item_func_truth descendants.
4. Implementing the method negated_item() for all Item_func_truth
   descendants, so the negated item has a chance to be sargable:
   For example,
     WHERE NOT col IS NOT FALSE    -- this notation is not sargable
   is now translated to:
     WHERE col IS FALSE            -- this notation is sargable
		
	
			
		
			
				
	
	
		
			506 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			506 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| drop table if exists t1;
 | |
| create table t1 (a int, key (a));
 | |
| insert into t1 values (NULL), (0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
 | |
| (10), (11), (12), (13), (14), (15), (16), (17), (18), (19);
 | |
| explain select * from t1 where not(not(a));
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	20	Using where; Using index
 | |
| select * from t1 where not(not(a));
 | |
| a
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where not(not(not(a > 10)));
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	11	Using where; Using index
 | |
| select * from t1 where not(not(not(a > 10)));
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| explain select * from t1 where not(not(not(a < 5) and not(a > 10)));
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	6	Using where; Using index
 | |
| select * from t1 where not(not(not(a < 5) and not(a > 10)));
 | |
| a
 | |
| 5
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| explain select * from t1 where not(a = 10);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	19	Using where; Using index
 | |
| select * from t1 where not(a = 10);
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where not(a != 10);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	ref	a	a	5	const	1	Using index
 | |
| select * from t1 where not(a != 1);
 | |
| a
 | |
| 1
 | |
| explain select * from t1 where not(a < 10);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	10	Using where; Using index
 | |
| select * from t1 where not(a < 10);
 | |
| a
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where not(a >= 10);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	10	Using where; Using index
 | |
| select * from t1 where not(a >= 10);
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| explain select * from t1 where not(a > 10);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	11	Using where; Using index
 | |
| select * from t1 where not(a > 10);
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| explain select * from t1 where not(a <= 10);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	9	Using where; Using index
 | |
| select * from t1 where not(a <= 10);
 | |
| a
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where not(a is null);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	20	Using where; Using index
 | |
| select * from t1 where not(a is null);
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where not(a is not null);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	ref	a	a	5	const	1	Using where; Using index
 | |
| select * from t1 where not(a is not null);
 | |
| a
 | |
| NULL
 | |
| explain select * from t1 where not(a < 5 or a > 15);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	11	Using where; Using index
 | |
| select * from t1 where not(a < 5 or a > 15);
 | |
| a
 | |
| 5
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| explain select * from t1 where not(a < 15 and a > 5);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	11	Using where; Using index
 | |
| select * from t1 where not(a < 15 and a > 5);
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where a = 2 or not(a < 10);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	11	Using where; Using index
 | |
| select * from t1 where a = 2 or not(a < 10);
 | |
| a
 | |
| 2
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where a > 5 and not(a > 10);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	5	Using where; Using index
 | |
| select * from t1 where a > 5 and not(a > 10);
 | |
| a
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| explain select * from t1 where a > 5 xor a < 10;
 | |
| 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
 | |
| select * from t1 where a > 5 xor a < 10;
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where a = 2 or not(a < 5 or a > 15);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	12	Using where; Using index
 | |
| select * from t1 where a = 2 or not(a < 5 or a > 15);
 | |
| a
 | |
| 2
 | |
| 5
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| explain select * from t1 where a = 7 or not(a < 15 and a > 5);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	12	Using where; Using index
 | |
| select * from t1 where a = 7 or not(a < 15 and a > 5);
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 7
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where NULL or not(a < 15 and a > 5);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	11	Using where; Using index
 | |
| select * from t1 where NULL or not(a < 15 and a > 5);
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where not(NULL and a > 5);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	6	Using where; Using index
 | |
| select * from t1 where not(NULL and a > 5);
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| explain select * from t1 where not(NULL or a);
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE
 | |
| 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	ref	a	a	5	const	1	Using index
 | |
| select * from t1 where not(NULL and a);
 | |
| a
 | |
| 0
 | |
| explain select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17));
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	10	Using where; Using index
 | |
| select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17));
 | |
| a
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	15	Using where; Using index
 | |
| select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
 | |
| a
 | |
| 5
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| explain select * from t1 where ((a between 5 and 15) and (not(a like 10)));
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 | |
| 1	SIMPLE	t1	range	a	a	5	NULL	11	Using where; Using index
 | |
| select * from t1 where ((a between 5 and 15) and (not(a like 10)));
 | |
| a
 | |
| 5
 | |
| 6
 | |
| 7
 | |
| 8
 | |
| 9
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| # XOR (Note: XOR is negated by negating one of the operands)
 | |
| # Should return 6,7
 | |
| SELECT * FROM t1 WHERE ((a > 5) XOR (a > 7));
 | |
| a
 | |
| 6
 | |
| 7
 | |
| # Should return 0..5,8..19
 | |
| SELECT * FROM t1 WHERE ((NOT (a > 5)) XOR (a > 7));
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| SELECT * FROM t1 WHERE ((a > 5) XOR (NOT (a > 7)));
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| SELECT * FROM t1 WHERE NOT ((a > 5) XOR (a > 7));
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| # Should return 6,7
 | |
| SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (a > 7));
 | |
| a
 | |
| 6
 | |
| 7
 | |
| SELECT * FROM t1 WHERE NOT ((a > 5) XOR (NOT (a > 7)));
 | |
| a
 | |
| 6
 | |
| 7
 | |
| # Should return 0..5,8..19
 | |
| SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (NOT (a > 7)));
 | |
| a
 | |
| 0
 | |
| 1
 | |
| 2
 | |
| 3
 | |
| 4
 | |
| 5
 | |
| 8
 | |
| 9
 | |
| 10
 | |
| 11
 | |
| 12
 | |
| 13
 | |
| 14
 | |
| 15
 | |
| 16
 | |
| 17
 | |
| 18
 | |
| 19
 | |
| # Should have empty result
 | |
| SELECT * FROM t1 WHERE (NULL XOR (a > 7));
 | |
| a
 | |
| SELECT * FROM t1 WHERE NOT (NULL XOR (a > 7));
 | |
| a
 | |
| # Should be simplified to "...WHERE (a XOR a)
 | |
| EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT ((NOT a) XOR (a));
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 | |
| 1	SIMPLE	t1	index	NULL	a	5	NULL	21	100.00	Using where; Using index
 | |
| Warnings:
 | |
| Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` xor `test`.`t1`.`a`
 | |
| # Should be simplified to "...WHERE (a XOR a)
 | |
| EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT (a XOR (NOT a));
 | |
| id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 | |
| 1	SIMPLE	t1	index	NULL	a	5	NULL	21	100.00	Using where; Using index
 | |
| Warnings:
 | |
| Note	1003	select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` xor `test`.`t1`.`a`
 | |
| # End XOR
 | |
| delete from t1 where a > 3;
 | |
| select a, not(not(a)) from t1;
 | |
| a	not(not(a))
 | |
| NULL	NULL
 | |
| 0	0
 | |
| 1	1
 | |
| 2	1
 | |
| 3	1
 | |
| explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a));
 | |
| 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` <> 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` is true having `test`.`t1`.`a` is true
 | |
| drop table t1;
 |