diff --git a/src/keywords.ts b/src/keywords.ts index 87dee02..cc6a003 100644 --- a/src/keywords.ts +++ b/src/keywords.ts @@ -5,4 +5,5 @@ export const sqlKeywords = [ // added manually , "PRECISION" -]; \ No newline at end of file + , "UNKNOWN" +]; diff --git a/src/syntax/ast.ts b/src/syntax/ast.ts index e405263..9e6ebfc 100644 --- a/src/syntax/ast.ts +++ b/src/syntax/ast.ts @@ -862,7 +862,7 @@ export interface ExprCast extends PGNode { } -export type UnaryOperator = '+' | '-' | 'NOT' | 'IS NULL' | 'IS NOT NULL' | 'IS TRUE' | 'IS FALSE' | 'IS NOT TRUE' | 'IS NOT FALSE'; +export type UnaryOperator = '+' | '-' | 'NOT' | 'IS NULL' | 'IS NOT NULL' | 'IS TRUE' | 'IS FALSE' | 'IS NOT TRUE' | 'IS NOT FALSE' | 'IS UNKNOWN' | 'IS NOT UNKNOWN'; export interface ExprUnary extends PGNode { type: 'unary'; operand: Expr; diff --git a/src/syntax/expr.ne b/src/syntax/expr.ne index aff8c67..13c2423 100644 --- a/src/syntax/expr.ne +++ b/src/syntax/expr.ne @@ -77,7 +77,7 @@ expr_star -> star {% x => track(x, { type: 'ref', name: '*' }) %} expr_is -> (expr_is | expr_paren) (%kw_isnull | %kw_is %kw_null) {% x => track(x, { type: 'unary', op: 'IS NULL', operand: unwrap(x[0]) }) %} | (expr_is | expr_paren) (%kw_notnull | %kw_is kw_not_null) {% x => track(x, { type: 'unary', op: 'IS NOT NULL', operand: unwrap(x[0])}) %} - | (expr_is | expr_paren) %kw_is %kw_not:? (%kw_true | %kw_false) {% x => track(x, { + | (expr_is | expr_paren) %kw_is %kw_not:? (%kw_true | %kw_false | %kw_unknown) {% x => track(x, { type: 'unary', op: 'IS ' + flattenStr([x[2], x[3]]) .join(' ') @@ -249,6 +249,7 @@ expr_primary | value_keyword {% x => track(x, {type: 'keyword', keyword: toStr(x) }) %} | %qparam {% x => track(x, { type: 'parameter', name: toStr(x[0]) }) %} | %kw_default {% x => track(x, { type: 'default'}) %} + | %kw_unknown {% x => track(x, { type: 'unknown' }) %} # LIKE-kind operators diff --git a/src/syntax/expr.spec.ts b/src/syntax/expr.spec.ts index 5cb2efd..bd06fbe 100644 --- a/src/syntax/expr.spec.ts +++ b/src/syntax/expr.spec.ts @@ -835,6 +835,30 @@ line`, operand: { type: 'ref', name: 'a' } }); + checkTreeExpr('a isnull', { + type: 'unary', + op: 'IS NULL', + operand: { type: 'ref', name: 'a' } + }); + + checkTreeExpr('a notnull', { + type: 'unary', + op: 'IS NOT NULL', + operand: { type: 'ref', name: 'a' } + }); + + checkTreeExpr('a is unknown', { + type: 'unary', + op: 'IS UNKNOWN', + operand: { type: 'ref', name: 'a' } + }); + + checkTreeExpr('a is not unknown', { + type: 'unary', + op: 'IS NOT UNKNOWN', + operand: { type: 'ref', name: 'a' } + }); + }); @@ -1635,4 +1659,4 @@ line`, args: [], }); }) -}); \ No newline at end of file +});