diff --git a/browser/sql-parser.js b/browser/sql-parser.js index 4ebe726..34e224c 100644 --- a/browser/sql-parser.js +++ b/browser/sql-parser.js @@ -213,7 +213,7 @@ SUB_SELECT_OP = ['IN', 'NOT IN', 'ANY', 'ALL', 'SOME']; - SUB_SELECT_UNARY_OP = ['EXISTS']; + SUB_SELECT_UNARY_OP = ['EXISTS', 'NOT EXISTS']; SQL_CONDITIONALS = ['AND', 'OR']; diff --git a/lib/lexer.js b/lib/lexer.js index 3f0ed9c..b54f8e2 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -208,7 +208,7 @@ SUB_SELECT_OP = ['IN', 'NOT IN', 'ANY', 'ALL', 'SOME']; - SUB_SELECT_UNARY_OP = ['EXISTS']; + SUB_SELECT_UNARY_OP = ['EXISTS', 'NOT EXISTS']; SQL_CONDITIONALS = ['AND', 'OR']; diff --git a/src/lexer.coffee b/src/lexer.coffee index 4cb3d8b..8ec5fd1 100644 --- a/src/lexer.coffee +++ b/src/lexer.coffee @@ -142,7 +142,7 @@ class Lexer SQL_SORT_ORDERS = ['ASC', 'DESC'] SQL_OPERATORS = ['=', '!=', '>=', '>', '<=', '<>', '<', 'LIKE', 'IS NOT', 'IS'] SUB_SELECT_OP = ['IN', 'NOT IN', 'ANY', 'ALL', 'SOME'] - SUB_SELECT_UNARY_OP = ['EXISTS'] + SUB_SELECT_UNARY_OP = ['EXISTS', 'NOT EXISTS'] SQL_CONDITIONALS = ['AND', 'OR'] SQL_BETWEENS = ['BETWEEN', 'NOT BETWEEN'] BOOLEAN = ['TRUE', 'FALSE', 'NULL'] diff --git a/test/grammar.spec.coffee b/test/grammar.spec.coffee index c681f7c..6ec1c4a 100644 --- a/test/grammar.spec.coffee +++ b/test/grammar.spec.coffee @@ -353,6 +353,16 @@ describe "SQL Grammar", -> )) """ + it "parses an EXISTS clause containing a query", -> + parse("""select * from a where not exists (select foo from bar)""").toString().should.eql """ + SELECT * + FROM `a` + WHERE (NOT EXISTS ( + SELECT `foo` + FROM `bar` + )) + """ + describe "aliases", -> it "parses aliased table names", -> parse("""select * from a b""").toString().should.eql """