BNF规则的解释

时间:2013-05-13 04:54:44

标签: mysql parsing bison yacc

我正在调查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

代替?

LOL (实际上不再是LOL)

此查询执行 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)

(此处添加了更新)......实际上 预期。

据推测,它会将第二个表达式直接转换为01并将其用作操作数。

UPD

我提交了一个错误 - http://bugs.mysql.com/bug.php?id=69208

它绝对不是预期的语法

UPD 2 :所以看起来它只是一个小错字,根本不会改变解析器的行为(好吧,要清楚它会使公共BETWEEN的速度变得不明显表达)。

1 个答案:

答案 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 0foo >= 1 AND f <= 0的简写,并且没有值这是真的,甚至允许NULL)。相反,如果bar介于1和2之间,那么foo中选定值的集合将是`foo1等于1的集合。

对你的另一个问题是“如果你用'bit_expr'替换'谓词'这个术语你会失去什么?”可能是“如果用'谓词'替换'bit_expr',你会得到任何东西吗?”

没有仔细审查完整的语法(或者至少仔细检查bit_exprpredicate引用的部分,并且可能会审查bit_expr和{{使用1}},很难知道这两个问题的答案。