sparkql 1.3.2 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/VERSION +1 -1
- data/lib/sparkql/evaluator.rb +17 -9
- data/lib/sparkql/token.rb +10 -3
- data/test/unit/evaluator_test.rb +63 -12
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fb6060ec97e59958c12e0ed3338540afa180bf28eab0224af3ffef568dbf469
|
4
|
+
data.tar.gz: 982d3956830686faeb210e6abf52125d18d4d68fa0d231b00a251a4876e1bd14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6754d10ca449bbd3467127a8470bb4233dd00b5162984ca636bcd93aff41743b25ace78fdd30ba77cbb6a79bef55d36118f67f2102b676ca9184db04c2437c01
|
7
|
+
data.tar.gz: d337d7169ceb202c6f4d8a066196c472404cccf5e1b6f0fc13bf07a4fba62fa6d135c04bfc017544c73fb84ca1834f5d06c78bbf5ee2848ac16b06372b09b711
|
data/CHANGELOG.md
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.
|
1
|
+
1.3.3
|
data/lib/sparkql/evaluator.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
|
1
2
|
# Using an instance of ExpressionResolver to resolve the individual expressions,
|
2
3
|
# this class will evaluate the rest of a parsed sparkql string to true or false.
|
3
4
|
# Namely, this class will handle all the nesting, boolean algebra, and dropped
|
4
5
|
# fields. Plus, it has some optimizations built in to skip the processing for
|
5
6
|
# any expressions that don't contribute to the net result of the filter.
|
6
7
|
class Sparkql::Evaluator
|
8
|
+
include Sparkql::Token
|
9
|
+
|
7
10
|
attr_reader :processed_count
|
8
11
|
|
9
12
|
def initialize(expression_resolver)
|
@@ -40,6 +43,11 @@ class Sparkql::Evaluator
|
|
40
43
|
block = expression[:block_group]
|
41
44
|
block_group = block_groups[block]
|
42
45
|
|
46
|
+
if expression[:conjunction] == NOT && expression[:conjunction_level] == level
|
47
|
+
expression[:conjunction] = AND
|
48
|
+
expression[:unary] = NOT
|
49
|
+
end
|
50
|
+
|
43
51
|
unless block_group
|
44
52
|
block_groups[block] ||= block_builder(expression, level)
|
45
53
|
block_group = block_groups[block]
|
@@ -48,9 +56,9 @@ class Sparkql::Evaluator
|
|
48
56
|
|
49
57
|
# When dealing with Not expression conjunctions at the block level,
|
50
58
|
# it's far simpler to convert it into the equivalent "And Not"
|
51
|
-
if block_group[:conjunction] ==
|
52
|
-
block_group[:unary] =
|
53
|
-
block_group[:conjunction] =
|
59
|
+
if block_group[:conjunction] == NOT
|
60
|
+
block_group[:unary] = NOT
|
61
|
+
block_group[:conjunction] = AND
|
54
62
|
end
|
55
63
|
|
56
64
|
# Every block group _must_ be seen as an expression in another block
|
@@ -100,7 +108,7 @@ class Sparkql::Evaluator
|
|
100
108
|
block_group[:expressions].each do |expression|
|
101
109
|
# If we encounter any or's in the same block group, we can cheat at
|
102
110
|
# resolving the rest, if we are at a true
|
103
|
-
if block_result && expression[:conjunction] ==
|
111
|
+
if block_result && expression[:conjunction] == OR
|
104
112
|
break
|
105
113
|
end
|
106
114
|
|
@@ -114,7 +122,7 @@ class Sparkql::Evaluator
|
|
114
122
|
end
|
115
123
|
next if expression_result == :drop
|
116
124
|
|
117
|
-
if expression[:unary] ==
|
125
|
+
if expression[:unary] == NOT
|
118
126
|
expression_result = !expression_result
|
119
127
|
end
|
120
128
|
|
@@ -124,11 +132,11 @@ class Sparkql::Evaluator
|
|
124
132
|
end
|
125
133
|
|
126
134
|
case expression[:conjunction]
|
127
|
-
when
|
135
|
+
when NOT
|
128
136
|
block_result &= !expression_result
|
129
|
-
when
|
137
|
+
when AND
|
130
138
|
block_result &= expression_result
|
131
|
-
when
|
139
|
+
when OR
|
132
140
|
block_result |= expression_result
|
133
141
|
else
|
134
142
|
# Not a supported conjunction. We skip over this for backwards
|
@@ -136,7 +144,7 @@ class Sparkql::Evaluator
|
|
136
144
|
end
|
137
145
|
end
|
138
146
|
|
139
|
-
|
147
|
+
block_group.delete(:expressions)
|
140
148
|
block_group[:result] = block_result
|
141
149
|
final_result = block_result
|
142
150
|
end
|
data/lib/sparkql/token.rb
CHANGED
@@ -24,8 +24,15 @@ module Sparkql::Token
|
|
24
24
|
NULL = /NULL|null|Null/.freeze
|
25
25
|
# Reserved words
|
26
26
|
RANGE_OPERATOR = 'Bt'.freeze
|
27
|
-
|
27
|
+
EQUAL = 'Eq'.freeze
|
28
|
+
NOT_EQUAL = 'Ne'.freeze
|
29
|
+
EQUALITY_OPERATORS = [EQUAL, NOT_EQUAL].freeze
|
30
|
+
|
28
31
|
OPERATORS = %w[Gt Ge Lt Le] + EQUALITY_OPERATORS
|
29
|
-
|
30
|
-
|
32
|
+
|
33
|
+
NOT = 'Not'.freeze
|
34
|
+
AND = 'And'.freeze
|
35
|
+
OR = 'Or'.freeze
|
36
|
+
UNARY_CONJUNCTIONS = [NOT].freeze
|
37
|
+
CONJUNCTIONS = [AND, OR].freeze
|
31
38
|
end
|
data/test/unit/evaluator_test.rb
CHANGED
@@ -64,39 +64,93 @@ class EvaluatorTest < Test::Unit::TestCase
|
|
64
64
|
def test_dropped_field_handling
|
65
65
|
assert sample("Test Eq 'Drop' And Test Eq true")
|
66
66
|
assert !sample("Test Eq 'Drop' And Test Eq false")
|
67
|
-
|
67
|
+
|
68
68
|
assert sample("Test Eq 'Drop' Or Test Eq true")
|
69
|
+
assert !sample("Test Eq 'Drop' Or Test Eq false")
|
70
|
+
|
69
71
|
assert sample("Test Eq false And Test Eq 'Drop' Or Test Eq true")
|
72
|
+
assert !sample("Test Eq false And Test Eq 'Drop' Or Test Eq false")
|
73
|
+
|
70
74
|
assert sample("Test Eq false Or (Test Eq 'Drop' And Test Eq true)")
|
75
|
+
assert !sample("Test Eq false Or (Test Eq 'Drop' And Test Eq false)")
|
76
|
+
|
77
|
+
assert sample("Test Eq false Or (Not Test Eq 'Drop' And Test Eq true)")
|
78
|
+
assert !sample("Test Eq false Or (Not Test Eq 'Drop' And Test Eq false)")
|
79
|
+
|
80
|
+
assert sample("Test Eq true Not Test Eq 'Drop' And Test Eq true")
|
81
|
+
assert !sample("Test Eq true Not Test Eq 'Drop' And Test Eq false")
|
82
|
+
assert !sample("Test Eq false Not Test Eq 'Drop' And Test Eq false")
|
83
|
+
|
84
|
+
assert sample("Test Eq true And Test Eq 'Drop' Not Test Eq false")
|
85
|
+
assert !sample("Test Eq true And Test Eq 'Drop' Not Test Eq true")
|
86
|
+
assert !sample("Test Eq true And Test Eq 'Drop' Not Test Eq true")
|
87
|
+
|
88
|
+
assert sample("Test Eq true Not (Test Eq 'Drop' And Test Eq false)")
|
89
|
+
assert !sample("Test Eq true Not (Test Eq 'Drop' And Test Eq true)")
|
90
|
+
assert !sample("Test Eq true Not (Test Eq 'Drop' And Test Eq true)")
|
71
91
|
end
|
72
92
|
|
73
93
|
def test_nesting
|
74
94
|
assert sample("Test Eq true Or (Test Eq true) And Test Eq false And (Test Eq true)")
|
95
|
+
assert sample("Test Eq true Or (Test Eq false) And Test Eq false And (Test Eq false)")
|
96
|
+
assert sample("Test Eq false Or (Test Eq true) And Test Eq true And (Test Eq true)")
|
97
|
+
assert !sample("Test Eq false Or (Test Eq false) And Test Eq false And (Test Eq false)")
|
98
|
+
assert !sample("Test Eq false Or (Test Eq true) And Test Eq false And (Test Eq false)")
|
99
|
+
assert !sample("Test Eq false Or (Test Eq false) And Test Eq true And (Test Eq false)")
|
100
|
+
assert !sample("Test Eq false Or (Test Eq false) And Test Eq false And (Test Eq true)")
|
101
|
+
|
75
102
|
assert sample("Test Eq true Or ((Test Eq false) And Test Eq false) And (Test Eq false)")
|
76
103
|
assert sample("(Test Eq false Or Test Eq true) Or (Test Eq false Or Test Eq false)")
|
77
104
|
assert sample("(Test Eq true And Test Eq true) Or (Test Eq false)")
|
78
105
|
assert sample("(Test Eq true And Test Eq true) Or (Test Eq false And Test Eq true)")
|
79
106
|
assert !sample("(Test Eq false And Test Eq true) Or (Test Eq false)")
|
107
|
+
|
80
108
|
assert sample("Test Eq true And ((Test Eq true And Test Eq false) Or Test Eq true)")
|
81
109
|
assert !sample("Test Eq true And ((Test Eq true And Test Eq false) Or Test Eq false) And Test Eq true")
|
82
110
|
assert !sample("Test Eq true And ((Test Eq true And Test Eq false) Or Test Eq false) Or Test Eq false")
|
83
111
|
assert sample("Test Eq true And ((Test Eq true And Test Eq false) Or Test Eq false) Or Test Eq true")
|
84
112
|
assert !sample("(Test Eq true Or Test Eq true) And Test Eq false")
|
85
113
|
assert !sample("(Test Eq true Or Test Eq true) And (Test Eq false)")
|
114
|
+
|
86
115
|
assert sample("(Test Eq true Or Test Eq true) And (Test Eq false Or Test Eq true)")
|
87
116
|
assert !sample("(Test Eq true Or Test Eq true) And (Test Eq false Or Test Eq false)")
|
117
|
+
|
118
|
+
assert sample("(Test Eq true) Not Test Eq false And (Test Eq true)")
|
119
|
+
assert !sample("(Test Eq true) Not Test Eq true And (Test Eq true)")
|
120
|
+
assert !sample("(Test Eq false) Not Test Eq false And (Test Eq true)")
|
121
|
+
assert !sample("(Test1 Eq true) Not Test2 Eq false And (Test3 Eq false)")
|
88
122
|
end
|
89
123
|
|
90
124
|
def test_nots
|
91
125
|
assert sample("Test Eq true Not Test Eq false")
|
92
126
|
assert !sample("Test Eq true Not Test Eq true")
|
127
|
+
assert !sample("Test Eq false Not Test Eq true")
|
128
|
+
assert !sample("Test Eq false Not Test Eq false")
|
129
|
+
|
130
|
+
assert sample("Test Eq true And Test Eq true Not Test Eq false")
|
131
|
+
assert !sample("Test Eq false And Test Eq true Not Test Eq false")
|
132
|
+
assert !sample("Test Eq true And Test Eq true Not Test Eq true")
|
133
|
+
assert !sample("Test Eq true And Test Eq false Not Test Eq false")
|
134
|
+
|
93
135
|
assert sample("Test Eq true Not (Test Eq false Or Test Eq false)")
|
94
|
-
assert sample("Test Eq true Not (Test Eq false And Test Eq false)")
|
95
136
|
assert !sample("Test Eq true Not (Test Eq false Or Test Eq true)")
|
96
137
|
assert !sample("Test Eq true Not (Test Eq true Or Test Eq false)")
|
97
|
-
assert !sample("Test Eq true Not (
|
98
|
-
assert !sample("Test Eq false
|
138
|
+
assert !sample("Test Eq true Not (Test Eq true Or Test Eq true)")
|
139
|
+
assert !sample("Test Eq false Not (Test Eq false Or Test Eq false)")
|
140
|
+
|
141
|
+
assert sample("Test Eq true Not (Test Eq false And Test Eq false)")
|
142
|
+
assert sample("Test Eq true Not (Test Eq true And Test Eq false)")
|
143
|
+
assert sample("Test Eq true Not (Test Eq false And Test Eq true)")
|
144
|
+
assert !sample("Test Eq true Not (Test Eq true And Test Eq true)")
|
145
|
+
assert !sample("Test Eq false Not (Test Eq false And Test Eq false)")
|
146
|
+
|
147
|
+
assert sample("Test Eq true Not (Test Eq false Or Test Eq false) And (Test Eq true Or Test Eq false)")
|
148
|
+
assert sample("Test Eq true Not (Test Eq false Or Test Eq false) And (Test Eq false Or Test Eq true)")
|
149
|
+
assert sample("Test Eq true Not (Test Eq false Or Test Eq false) And (Test Eq true Or Test Eq true)")
|
99
150
|
assert !sample("Test Eq true Not (Test Eq false Or Test Eq false) And (Test Eq false Or Test Eq false)")
|
151
|
+
assert !sample("Test Eq true Not (Test Eq false Or Test Eq true) And (Test Eq true Or Test Eq false)")
|
152
|
+
assert !sample("Test Eq true Not (Test Eq true Or Test Eq false) And (Test Eq true Or Test Eq false)")
|
153
|
+
assert !sample("Test Eq false Not (Test Eq false Or Test Eq false) And (Test Eq true Or Test Eq false)")
|
100
154
|
end
|
101
155
|
|
102
156
|
def test_unary_nots
|
@@ -109,17 +163,14 @@ class EvaluatorTest < Test::Unit::TestCase
|
|
109
163
|
|
110
164
|
def test_unary_double_nots
|
111
165
|
assert sample("Not (Not(Not Test Eq true))")
|
166
|
+
assert !sample("Not (Not(Not Test Eq false))")
|
167
|
+
|
168
|
+
assert sample("Test Eq true Not (Not Test Eq true)")
|
169
|
+
assert !sample("Test Eq true Not (Not Test Eq false)")
|
170
|
+
assert !sample("Test Eq false Not (Not Test Eq true)")
|
112
171
|
end
|
113
172
|
|
114
173
|
def test_examples
|
115
|
-
# This one is based on a real life example that had problems.
|
116
|
-
#
|
117
|
-
# CurrentPrice Bt 130000.00,180000.00 And PropertySubType Eq 'Single Family Residence' And
|
118
|
-
# SchoolDistrict Eq 'Byron Center','Grandville','Jenison' And MlsStatus Eq 'Active' And
|
119
|
-
# BathsTotal Bt 1.50,9999.00 And BedsTotal Bt 3,99 And PropertyType Eq 'A'
|
120
|
-
# Not "Garage"."Garage2" Eq 'No' And "Pool"."OutdoorAbove" Eq true
|
121
|
-
# And "Pool"."OutdoorInground" Eq true Not "Substructure"."Michigan Basement" Eq true
|
122
|
-
|
123
174
|
assert !sample("Test Eq false And Test Eq true And " \
|
124
175
|
"Test Eq false And Test Eq true And " \
|
125
176
|
"Test Eq true And Test Eq true And Test Eq true " \
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sparkql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wade McEwen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-08-
|
11
|
+
date: 2025-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: georuby
|