在编写 SQL 解析器的时候,无意中发现 Oracle 官方文档中关于 constraint_state 的 BNF 描述是错误的,以 21c 版本为例,描述是这样的:
[ [NOT] DEFERRABLE [INITIALLY {IMMEDIATE | DEFERRED}] ] | INITIALLY { IMMEDIATE | DEFERRED } [ NOT ] [ DEFERRABLE ]][ RELY | NORELY ][ using_index_clause ][ ENABLE | DISABLE ][ VALIDATE | NOVALIDATE ][ exceptions_clause ]
复制代码
这里有 10 个“[”,但有 11 个“]”,括号的数量不匹配,导致语义不明确。
这个问题从 18c 开始就存在,下面链接是 21c 的:
https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/img_text/constraint_state.html
我对此做了一定的修改:
constraint_state::=notDeferrableAndInitiallyClause | initiallyClauseAndNotDeferrable[ RELY | NORELY ][ using_index_clause ][ ENABLE | DISABLE ][ VALIDATE | NOVALIDATE][ exceptions_clause ]
notDeferrableAndInitiallyClause ::= notDeferrable [initiallyClause]initiallyClauseAndNotDeferrable ::= initiallyClause [notDeferrable]
notDeferrable ::= [NOT] DEFERRABLEinitiallyClause ::= INITIALLY {IMMEDIATE | DEFERRABLE}
复制代码
这样的语义比较明确。如果用 g4 文件来表示,则如下:
constraintState : (notDeferrable initiallyClause? | initiallyClause notDeferrable?) (RELY | NORELY)? usingIndexClause? (ENABLE | DISABLE)? (VALIDATE | NOVALIDATE)? exceptionsClause? notDeferrable : NOT? DEFERRABLE ;
initiallyClause : INITIALLY (IMMEDIATE | DEFERRED) ;
复制代码
这个问题还没有见有公开的资料有记载。
评论