Skip to content

Commit

Permalink
NOT BETWEEN
Browse files Browse the repository at this point in the history
  • Loading branch information
elliotchance committed Apr 11, 2015
1 parent 5b47284 commit ea1ee2f
Show file tree
Hide file tree
Showing 15 changed files with 164 additions and 14 deletions.
8 changes: 8 additions & 0 deletions tesseract/lua/operator/between.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,13 @@ local function operator_between(left, right)
return cjson.null
end

-- We can only deal with numbers.
if type(left) ~= 'number' or type(right[1]) ~= 'number'
or type(right[2]) ~= 'number' then
error(string.format('No such operator %s BETWEEN %s AND %s.',
type(left), type(right[1]), type(right[2])))
end

-- Perform comparison.
return left >= right[1] and left <= right[2]
end
17 changes: 17 additions & 0 deletions tesseract/lua/operator/not_between.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
local function operator_not_between(left, right)
-- If the value is null then the result is always null.
if left == cjson.null or right[1] == cjson.null
or right[2] == cjson.null then
return cjson.null
end

-- We can only deal with numbers.
if type(left) ~= 'number' or type(right[1]) ~= 'number'
or type(right[2]) ~= 'number' then
error(string.format('No such operator %s NOT BETWEEN %s AND %s.',
type(left), type(right[1]), type(right[2])))
end

-- Perform comparison.
return left < right[1] or left > right[2]
end
9 changes: 6 additions & 3 deletions tesseract/sql/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,12 @@ def __str__(self):


class BetweenExpression(BinaryExpression):
def __init__(self, left, right):
BinaryExpression.__init__(self, left, 'BETWEEN', right,
':operator_between')
def __init__(self, left, right, is_not):
function = ':operator_not_between' if is_not else ':operator_between'
operator = 'NOT BETWEEN' if is_not else 'BETWEEN'
BinaryExpression.__init__(self, left, operator, right, function)

self.is_not = is_not

def __str__(self):
return '%s %s %s AND %s' % (
Expand Down
11 changes: 8 additions & 3 deletions tesseract/sql/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
('left', 'GREATER', 'LESS', 'GREATER_EQUAL', 'LESS_EQUAL'),
('left', 'LIKE'),
('right', 'IS'),
('left', 'BETWEEN'),
('right', 'BETWEEN'),
)


Expand Down Expand Up @@ -413,10 +413,15 @@ def p_function_call(p):
def p_between_expression(p):
"""
between_expression : expression BETWEEN expression AND expression
| expression NOT BETWEEN expression AND expression
"""

add_requirement(p, 'operator/between')
p[0] = BetweenExpression(p[1], Value([p[3], p[5]]))
if p[2] == 'BETWEEN':
add_requirement(p, 'operator/between')
p[0] = BetweenExpression(p[1], Value([p[3], p[5]]), False)
else:
add_requirement(p, 'operator/not_between')
p[0] = BetweenExpression(p[1], Value([p[4], p[6]]), True)


# in_expression
Expand Down
6 changes: 5 additions & 1 deletion tests/expressions/operator/and.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ tests:
result:
- {"col1": false}

incompatible_types:
incompatible_left:
sql: SELECT false AND 3.5
error: No such operator boolean AND number.

incompatible_right:
sql: SELECT 3.5 AND false
error: No such operator number AND boolean.
32 changes: 32 additions & 0 deletions tests/expressions/operator/between.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,35 @@ tests:
sql: SELECT 2 BETWEEN 3 AND 7
result:
- {"col1": false}

bottom:
sql: SELECT 3 BETWEEN 3 AND 7
result:
- {"col1": true}

middle:
sql: SELECT 5 BETWEEN 3 AND 7
result:
- {"col1": true}

top:
sql: SELECT 7 BETWEEN 3 AND 7
result:
- {"col1": true}

greater_than:
sql: SELECT 8 BETWEEN 3 AND 7
result:
- {"col1": false}

incompatible_a:
sql: SELECT "foo" BETWEEN 3 AND 7
error: No such operator string BETWEEN number AND number.

incompatible_b:
sql: SELECT 123 BETWEEN "foo" AND 7
error: No such operator number BETWEEN string AND number.

incompatible_c:
sql: SELECT 123 BETWEEN 3 AND "foo"
error: No such operator number BETWEEN number AND string.
6 changes: 5 additions & 1 deletion tests/expressions/operator/divide.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ tests:
result:
- {"col1": 2.5}

incompatible_types:
incompatible_left:
sql: SELECT false / 3.5
error: No such operator boolean / number.

incompatible_right:
sql: SELECT 3.5 / false
error: No such operator number / boolean.
1 change: 1 addition & 0 deletions tests/expressions/operator/equal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ tests:
result:
- {"col1": false}

# Bad types.
incompatible_types:
sql: SELECT false = 3.5
error: No such operator boolean = number.
6 changes: 5 additions & 1 deletion tests/expressions/operator/minus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ tests:
result:
- {"col1": 4.5}

incompatible_types:
incompatible_left:
sql: SELECT false - 3.5
error: No such operator boolean - number.

incompatible_right:
sql: SELECT 3.5 - false
error: No such operator number - boolean.
6 changes: 5 additions & 1 deletion tests/expressions/operator/modulo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ tests:
result:
- {"col1": 1}

incompatible_types:
incompatible_left:
sql: SELECT false % 3.5
error: No such operator boolean % number.

incompatible_right:
sql: SELECT 3.5 % false
error: No such operator number % boolean.
6 changes: 5 additions & 1 deletion tests/expressions/operator/multiply.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ tests:
result:
- {"col1": 22.5}

incompatible_types:
incompatible_left:
sql: SELECT false * 3.5
error: No such operator boolean * number.

incompatible_right:
sql: SELECT 3.5 * false
error: No such operator number * boolean.
52 changes: 52 additions & 0 deletions tests/expressions/operator/not_between.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
tests:
a_null:
sql: SELECT null NOT BETWEEN 3 AND 7
result:
- {"col1": null}

b_null:
sql: SELECT 5 NOT BETWEEN null AND 7
result:
- {"col1": null}

c_null:
sql: SELECT 5 NOT BETWEEN 3 AND null
result:
- {"col1": null}

less_than:
sql: SELECT 2 NOT BETWEEN 3 AND 7
result:
- {"col1": true}

bottom:
sql: SELECT 3 NOT BETWEEN 3 AND 7
result:
- {"col1": false}

middle:
sql: SELECT 5 NOT BETWEEN 3 AND 7
result:
- {"col1": false}

top:
sql: SELECT 7 NOT BETWEEN 3 AND 7
result:
- {"col1": false}

greater_than:
sql: SELECT 8 NOT BETWEEN 3 AND 7
result:
- {"col1": true}

incompatible_a:
sql: SELECT "foo" NOT BETWEEN 3 AND 7
error: No such operator string NOT BETWEEN number AND number.

incompatible_b:
sql: SELECT 123 NOT BETWEEN "foo" AND 7
error: No such operator number NOT BETWEEN string AND number.

incompatible_c:
sql: SELECT 123 NOT BETWEEN 3 AND "foo"
error: No such operator number NOT BETWEEN number AND string.
6 changes: 5 additions & 1 deletion tests/expressions/operator/or.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ tests:
result:
- {"col1": false}

incompatible_types:
incompatible_left:
sql: SELECT false OR 3.5
error: No such operator boolean OR number.

incompatible_right:
sql: SELECT 3.5 OR false
error: No such operator number OR boolean.
6 changes: 5 additions & 1 deletion tests/expressions/operator/plus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ tests:
result:
- {"col1": 10.5}

incompatible_types:
incompatible_left:
sql: SELECT false + 3.5
error: No such operator boolean + number.

incompatible_right:
sql: SELECT 3.5 + false
error: No such operator number + boolean.
6 changes: 5 additions & 1 deletion tests/expressions/operator/power.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ tests:
result:
- {"col1": 56.25}

incompatible_types:
incompatible_left:
sql: SELECT false ^ 3.5
error: No such operator boolean ^ number.

incompatible_right:
sql: SELECT 3.5 ^ false
error: No such operator number ^ boolean.

0 comments on commit ea1ee2f

Please sign in to comment.