Skip to content

Commit c20803c

Browse files
committed
Merge pull request #34 from joshcom/API-2831
Handle SparkQL strings that begin with "Not (Not ...)"
2 parents 2227666 + d71aed9 commit c20803c

File tree

4 files changed

+51
-1
lines changed

4 files changed

+51
-1
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
v0.3.24, 2016-01-05 ([changes](https://github.com/sparkapi/sparkql/compare/v0.3.23...v0.3.24))
2+
-------------------
3+
4+
* [BUGFIX] Support opening Not operator for "Not (Not ...)" expressions.
5+
16
v0.3.23, 2015-10-09 ([changes](https://github.com/sparkapi/sparkql/compare/v0.3.22...v0.3.23))
27
-------------------
38

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.3.23
1+
0.3.24

lib/sparkql/parser_tools.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module Sparkql::ParserTools
77

88
def parse(str)
99
@lexer = Sparkql::Lexer.new(str)
10+
@expression_count = 0
1011
results = do_parse
1112
return if results.nil?
1213
validate_expressions results
@@ -33,6 +34,7 @@ def tokenize_expression(field, op, val)
3334
tokenizer_error(:token => op, :expression => expression,
3435
:message => "Operator not supported for this type and value string", :status => :fatal )
3536
end
37+
@expression_count += 1
3638
[expression]
3739
end
3840

@@ -43,6 +45,14 @@ def tokenize_conjunction(exp1, conj, exp2)
4345
end
4446

4547
def tokenize_unary_conjunction(conj, exp)
48+
49+
# Handles the case when a SparkQL filter string
50+
# begins with a unary operator, and is nested, such as:
51+
# Not (Not Field Eq 1)
52+
if @expression_count == 1 && @lexer.level > 0
53+
exp.first[:conjunction] = conj
54+
end
55+
4656
exp.first[:unary] = conj
4757
exp.first[:unary_level] = @lexer.level
4858
exp

test/unit/parser_test.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ def test_not_unary_expression
409409
expression = expressions.first
410410
assert_equal 10.to_s, expression[:value]
411411
assert_equal "Not", expression[:unary]
412+
assert_equal "And", expression[:conjunction]
412413
assert_equal expression[:level], expression[:unary_level]
413414
end
414415

@@ -434,6 +435,40 @@ def test_not_unary_expression_keeps_conjunction
434435
assert_equal 0, expression[:conjunction_level]
435436
end
436437

438+
def test_not_not_expression
439+
@parser = Parser.new
440+
filter = "Not (Not ListPrice Eq 1) Not (Not BathsTotal Eq 2) And " +
441+
"(Not TotalRooms Eq 3) Or (HasPool Eq true)"
442+
443+
expressions = @parser.parse(filter)
444+
assert !@parser.errors?, @parser.inspect
445+
446+
e1 = expressions.first
447+
e2 = expressions[1]
448+
e3 = expressions[2]
449+
e4 = expressions[3]
450+
451+
assert_equal "Not", e1[:unary]
452+
assert_equal "Not", e1[:conjunction]
453+
assert_equal "Not", e2[:unary]
454+
assert_equal "Not", e2[:conjunction]
455+
assert_equal "Not", e3[:unary]
456+
assert_equal "And", e3[:conjunction]
457+
assert_nil e4[:unary]
458+
assert_equal "Or", e4[:conjunction]
459+
460+
@parser = Parser.new
461+
filter = "Not (ListPrice Eq 1)"
462+
463+
expressions = @parser.parse(filter)
464+
assert !@parser.errors?, @parser.inspect
465+
466+
e1 = expressions.first
467+
468+
assert_equal "Not", e1[:unary]
469+
assert_equal "And", e1[:conjunction]
470+
end
471+
437472
def test_expression_conditions_attribute
438473
conditions = [
439474
"1",

0 commit comments

Comments
 (0)