我正在调查mysql的SQL解析器。
这是我注意到并且无法解释的有趣的事情:
(在sql_yacc.yy
)
predicate:
...
| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
{
$$= new (YYTHD->mem_root) Item_func_between($1,$3,$5);
if ($$ == NULL)
MYSQL_YYABORT;
}
同样在Expression Syntax页面上:
predicate:
...
| bit_expr [NOT] BETWEEN bit_expr AND predicate
这意味着
foo BETWEEN 1 AND bar BETWEEN 1 AND 2
查询语法正确,但根本没有意义。
我的问题:这可以用于什么?如果使用我们会错过什么
bit_expr [NOT] BETWEEN bit_expr AND bit_expr
代替?
此查询执行 WITHOUT 错误:
select * from users where id between 1 and id between 1 and 10;
// returns row with id = 1
select * from users where id between 2 and id between 2 and 10;
Empty set (0.00 sec)
(此处添加了更新)......实际上 预期。
据推测,它会将第二个表达式直接转换为0
或1
并将其用作操作数。
UPD :
我提交了一个错误 - http://bugs.mysql.com/bug.php?id=69208
它绝对不是预期的语法
UPD 2 :所以看起来它只是一个小错字,根本不会改变解析器的行为(好吧,要清楚它会使公共BETWEEN
的速度变得不明显表达)。
答案 0 :(得分:2)
您的分析基本上是正确的:
foo BETWEEN 1 AND bar BETWEEN 1 AND 2
被解析为:
foo BETWEEN 1 AND (bar BETWEEN 1 AND 2)
并且第二个(带括号的)谓词可能会评估为0或1(对于false或true)。因此,如果bar
不在1和2之间,则foo
中的所选值集将为空(因为foo BETWEEN 1 AND 0
是foo >= 1 AND f <= 0
的简写,并且没有值这是真的,甚至允许NULL)。相反,如果bar
介于1和2之间,那么foo
中选定值的集合将是`foo1等于1的集合。
对你的另一个问题是“如果你用'bit_expr'替换'谓词'这个术语你会失去什么?”可能是“如果用'谓词'替换'bit_expr',你会得到任何东西吗?”
没有仔细审查完整的语法(或者至少仔细检查bit_expr
和predicate
引用的部分,并且可能会审查bit_expr
和{{使用1}},很难知道这两个问题的答案。