Skip to content

Commit 3403bf7

Browse files
committed
Merge pull request #13 from mistic100/between
Add support of BETWEEN operator
2 parents 54d4b2d + 6a8b65c commit 3403bf7

File tree

4 files changed

+19
-0
lines changed

4 files changed

+19
-0
lines changed

src/grammar.coffee

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,18 @@ grammar =
144144
o 'Expression MATH Expression', -> new Op($2, $1, $3)
145145
o 'Expression MATH_MULTI Expression', -> new Op($2, $1, $3)
146146
o 'Expression OPERATOR Expression', -> new Op($2, $1, $3)
147+
o 'Expression BETWEEN BetweenExpression', -> new Op($2, $1, $3)
147148
o 'Expression CONDITIONAL Expression', -> new Op($2, $1, $3)
148149
o 'Value SUB_SELECT_OP LEFT_PAREN List RIGHT_PAREN', -> new Op($2, $1, $4)
149150
o 'Value SUB_SELECT_OP SubSelectExpression', -> new Op($2, $1, $3)
150151
o 'SUB_SELECT_UNARY_OP SubSelectExpression', -> new UnaryOp($1, $2)
151152
o 'Value'
152153
]
153154

155+
BetweenExpression: [
156+
o 'Expression CONDITIONAL Expression', -> new BetweenOp([$1, $3])
157+
]
158+
154159
SubSelectExpression: [
155160
o 'LEFT_PAREN Query RIGHT_PAREN', -> new SubSelect($2)
156161
]

src/lexer.coffee

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Lexer
1717
@mathToken() or
1818
@dotToken() or
1919
@conditionalToken() or
20+
@betweenToken() or
2021
@subSelectOpToken() or
2122
@subSelectUnaryOpToken() or
2223
@numberToken() or
@@ -98,6 +99,7 @@ class Lexer
9899
@tokenizeFromList('MATH', MATH) or
99100
@tokenizeFromList('MATH_MULTI', MATH_MULTI)
100101
conditionalToken: -> @tokenizeFromList('CONDITIONAL', SQL_CONDITIONALS)
102+
betweenToken: -> @tokenizeFromList('BETWEEN', SQL_BETWEENS)
101103
subSelectOpToken: -> @tokenizeFromList('SUB_SELECT_OP', SUB_SELECT_OP)
102104
subSelectUnaryOpToken: -> @tokenizeFromList('SUB_SELECT_UNARY_OP', SUB_SELECT_UNARY_OP)
103105
functionToken: -> @tokenizeFromList('FUNCTION', SQL_FUNCTIONS)
@@ -142,6 +144,7 @@ class Lexer
142144
SUB_SELECT_OP = ['IN', 'NOT IN', 'ANY', 'ALL', 'SOME']
143145
SUB_SELECT_UNARY_OP = ['EXISTS']
144146
SQL_CONDITIONALS = ['AND', 'OR']
147+
SQL_BETWEENS = ['BETWEEN', 'NOT BETWEEN']
145148
BOOLEAN = ['TRUE', 'FALSE', 'NULL']
146149
MATH = ['+', '-']
147150
MATH_MULTI = ['/', '*']

src/nodes.coffee

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ exports.UnaryOp = class UnaryOp
150150
constructor: (@operator, @operand) -> null
151151
toString: -> "(#{@operator.toUpperCase()} #{@operand})"
152152

153+
exports.BetweenOp = class BetweenOp
154+
constructor: (@value) -> null
155+
toString: -> "#{@value.join(' AND ')}"
156+
153157
exports.Field = class Field
154158
constructor: (@field, @name=null) -> null
155159
toString: -> if @name then "#{@field} AS #{@name}" else @field.toString()

test/grammar.spec.coffee

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ describe "SQL Grammar", ->
114114
WHERE ((`a` > 10) AND ((`a` < 30) OR (`b` = 'c')))
115115
"""
116116

117+
it "parses WHERE clauses with BETWEEN operator", ->
118+
parse("SELECT * FROM my_table WHERE a > 10 AND b BETWEEN 4 AND 6 AND c = 4").toString().should.eql """
119+
SELECT *
120+
FROM `my_table`
121+
WHERE (((`a` > 10) AND (`b` BETWEEN 4 AND 6)) AND (`c` = 4))
122+
"""
123+
117124
it "parses WHERE with ORDER BY clauses", ->
118125
parse("SELECT * FROM my_table WHERE x > 1 ORDER BY y").toString().should.eql """
119126
SELECT *

0 commit comments

Comments
 (0)