在编写 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] DEFERRABLE
initiallyClause ::= INITIALLY {IMMEDIATE | DEFERRABLE}
复制代码
这样的语义比较明确。如果用 g4 文件来表示,则如下:
constraintState
: (notDeferrable initiallyClause?
| initiallyClause notDeferrable?)
(RELY | NORELY)? usingIndexClause? (ENABLE | DISABLE)? (VALIDATE | NOVALIDATE)? exceptionsClause?
notDeferrable
: NOT? DEFERRABLE
;
initiallyClause
: INITIALLY (IMMEDIATE | DEFERRED)
;
复制代码
这个问题还没有见有公开的资料有记载。
评论