| Bug #46867 | Support SQL 2003 SYMMETRIC/ASYMMETRIC options for BETWEEN clause | ||
|---|---|---|---|
| Submitted: | 23 Aug 2009 1:32 | Modified: | 23 Aug 2009 10:12 |
| Reporter: | Justin Swanhart | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: General | Severity: | S4 (Feature request) |
| Version: | 5.4.1, 5.1.15,5.0.51a | OS: | Linux (CentOS 5.2) |
| Assigned to: | CPU Architecture: | Any | |
[23 Aug 2009 1:45]
Justin Swanhart
here is an easy way to duplicate w/out creating any tables: mysql> select 1 from dual where 5 between 1 and 10; +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.00 sec) mysql> select 1 from dual where 5 between 10 and 1; Empty set (0.00 sec)
[23 Aug 2009 2:11]
Justin Swanhart
duplicated on 5.0.51a as well: [root@localhost mysql]# mysql Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 to server version: 5.0.51a-debug-log Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> (select 'Yes' from dual where 5 between 10 and 1 ) union (select 'No') limit 1; +-----+ | Yes | +-----+ | No | +-----+ 1 row in set (0.08 sec) mysql>
[23 Aug 2009 7:00]
Valeriy Kravchuk
Sorry, but this is NOT a bug. c BETWEEN a AND b is always interpreted as: (c >= a) and (c <= b) so if b < a there are no rows that can match this condition. Read http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html#operator_between also.
[23 Aug 2009 9:09]
Justin Swanhart
Then an error should be raised in min is greater than max. The empty result is wrong.
Regardless, I am reopening as feature request for the SQL2003 standard BETWEEN clause:
From the SQL:2003 spec, foundation, section 8.3:
<between predicate part 2> ::=
[ NOT ] BETWEEN [ ASYMMETRIC | SYMMETRIC ]
<row value predicand> AND <row value predicand>
1) If neither SYMMETRIC nor ASYMMETRIC is specified, then ASYMMETRIC is implicit.
...
6) “X BETWEEN ASYMMETRIC Y AND Z” is equivalent to “X>=Y AND X<=Z”.
[23 Aug 2009 9:10]
Justin Swanhart
Changed synopsis.
[23 Aug 2009 10:00]
Bradley Kuszmaul
I agree that it's not a bug. As far as I can tell, the mysql behavior matches the SQL:2003 standard.

Description: This query (between 1 and 2) returns results: --------------------------- select d.i1, count(*) from f join d using(i1) where d.i2=1 and f.i1 between 1 and 2; This query returns empty set and the EXPLAIN plan detects and "impossible where clause", which is clearly not impossible: --------------------------- select d.i1, count(*) from f join d using(i1) where d.i2=1 and f.i1 between 2 and 1; I encountered this bug on an older 5.1, then tested on newest 5.4 and found the exact same problem. This may be a problem in many versions. How to repeat: mysql> create table f ( id bigint auto_increment primary key, i1 tinyint ) engine=myisam; Query OK, 0 rows affected (0.00 sec) mysql> insert into f values (null, 1),(null,2),(null,3); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> create table d (i1 tinyint, i2 tinyint, primary key(i1,i2)) engine=myisam; Query OK, 0 rows affected (0.01 sec) mysql> insert into d values (1,1),(1,2),(2,1),(2,2),(3,1),(3,2); Query OK, 6 rows affected (0.00 sec) Records: 6 Duplicates: 0 Warnings: 0 mysql> explain select d.i1, count(*) from f join d using(i1) where d.i2=1 and f.i1 between 1 and 2; +----+-------------+-------+--------+---------------+---------+---------+--------------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+--------+---------------+---------+---------+--------------------+------+-------------+ | 1 | SIMPLE | f | ALL | NULL | NULL | NULL | NULL | 3 | Using where | | 1 | SIMPLE | d | eq_ref | PRIMARY | PRIMARY | 2 | example.f.i1,const | 1 | Using index | +----+-------------+-------+--------+---------------+---------+---------+--------------------+------+-------------+ 2 rows in set (0.00 sec) mysql> explain select d.i1, count(*) from f join d using(i1) where d.i2=1 and f.i1 between 2 and 1; +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables | +----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+ 1 row in set (0.00 sec)