Commit | Line | Data |
d70ca130 |
1 | use strict; |
2 | use warnings; |
3 | |
03f6671a |
4 | use FindBin; |
5 | use lib "$FindBin::Bin/../../lib"; |
6 | use SQLADumperSort; |
7 | |
1c51edc4 |
8 | use SQL::Abstract::Compat; |
d70ca130 |
9 | |
00f4d23e |
10 | use Test::More tests => 12; |
d70ca130 |
11 | use Test::Differences; |
12 | |
1c51edc4 |
13 | ok(my $visitor = SQL::Abstract::Compat->new); |
d70ca130 |
14 | |
00f4d23e |
15 | |
c6039348 |
16 | my $foo_id = { -type => 'name', args => [qw/foo/] }; |
17 | my $bar_id = { -type => 'name', args => [qw/bar/] }; |
18 | |
00f4d23e |
19 | my $foo_eq_1 = field_op_value($foo_id, '==', 1); |
20 | my $bar_eq_str = field_op_value($bar_id, '==', 'some str'); |
d70ca130 |
21 | |
22 | eq_or_diff |
37716782 |
23 | $visitor->recurse_where({ foo => 1 }), |
d70ca130 |
24 | $foo_eq_1, |
25 | "Single value hash"; |
26 | |
27 | |
d70ca130 |
28 | |
29 | eq_or_diff |
37716782 |
30 | $visitor->recurse_where({ foo => 1, bar => 'some str' }), |
d70ca130 |
31 | { -type => 'expr', |
32 | op => 'and', |
33 | args => [ |
34 | $bar_eq_str, |
35 | $foo_eq_1, |
36 | ] |
37 | }, |
38 | "two keys in hash"; |
39 | |
40 | eq_or_diff |
37716782 |
41 | $visitor->recurse_where({ -or => { foo => 1, bar => 'some str' } }), |
d70ca130 |
42 | { -type => 'expr', |
43 | op => 'or', |
44 | args => [ |
45 | $bar_eq_str, |
46 | $foo_eq_1, |
47 | ] |
48 | }, |
49 | "-or key in hash"; |
50 | |
51 | |
52 | eq_or_diff |
37716782 |
53 | $visitor->recurse_where([ -and => { foo => 1, bar => 'some str' } ]), |
d70ca130 |
54 | { -type => 'expr', |
55 | op => 'and', |
56 | args => [ |
57 | $bar_eq_str, |
58 | $foo_eq_1, |
59 | ] |
60 | }, |
61 | "-and as first element of array"; |
62 | |
63 | |
64 | eq_or_diff |
37716782 |
65 | $visitor->recurse_where([ -and => { foo => 1, bar => 'some str' }, { foo => 1} ]), |
d70ca130 |
66 | { -type => 'expr', |
67 | op => 'or', |
68 | args => [ |
69 | { -type => 'expr', |
70 | op => 'and', |
71 | args => [ |
72 | $bar_eq_str, |
73 | $foo_eq_1, |
74 | ] |
75 | }, |
76 | $foo_eq_1, |
77 | ] |
78 | }, |
c6039348 |
79 | "-and as first element of array + hash"; |
80 | |
81 | eq_or_diff |
37716782 |
82 | $visitor->recurse_where({ foo => { '!=' => 'bar' } }), |
00f4d23e |
83 | field_op_value($foo_id, '!=', 'bar'), |
c6039348 |
84 | "foo => { '!=' => 'bar' }"; |
85 | |
86 | eq_or_diff |
37716782 |
87 | $visitor->recurse_where({ foo => [ 1, 'bar' ] }), |
c6039348 |
88 | { -type => 'expr', |
89 | op => 'or', |
90 | args => [ |
91 | $foo_eq_1, |
00f4d23e |
92 | field_op_value($foo_id, '==', 'bar'), |
c6039348 |
93 | ], |
94 | }, |
95 | "foo => [ 1, 'bar' ]"; |
96 | |
2e828b0b |
97 | eq_or_diff |
37716782 |
98 | $visitor->recurse_where({ foo => { -in => [ 1, 'bar' ] } }), |
2e828b0b |
99 | { -type => 'expr', |
100 | op => 'in', |
101 | args => [ |
102 | $foo_id, |
103 | { -type => 'value', value => 1 }, |
104 | { -type => 'value', value => 'bar' }, |
105 | ] |
106 | }, |
107 | "foo => { -in => [ 1, 'bar' ] }"; |
108 | |
109 | eq_or_diff |
37716782 |
110 | $visitor->recurse_where({ foo => { -not_in => [ 1, 'bar' ] } }), |
2e828b0b |
111 | { -type => 'expr', |
112 | op => 'not_in', |
113 | args => [ |
114 | $foo_id, |
115 | { -type => 'value', value => 1 }, |
116 | { -type => 'value', value => 'bar' }, |
117 | ] |
118 | }, |
119 | "foo => { -not_in => [ 1, 'bar' ] }"; |
120 | |
121 | eq_or_diff |
37716782 |
122 | $visitor->recurse_where({ foo => { -in => [ ] } }), |
2e828b0b |
123 | { -type => 'expr', |
124 | op => 'in', |
125 | args => [ |
126 | $foo_id, |
127 | ] |
128 | }, |
129 | "foo => { -in => [ ] }"; |
130 | |
00f4d23e |
131 | my $worker_eq = sub { |
132 | return { |
133 | -type => 'expr', |
134 | op => '==', |
135 | args => [ |
136 | { -type => 'name', args => ['worker'] }, |
137 | { -type => 'value', value => $_[0] }, |
138 | ], |
139 | } |
140 | }; |
03f6671a |
141 | |
00f4d23e |
142 | eq_or_diff |
37716782 |
143 | $visitor->recurse_where( { |
00f4d23e |
144 | requestor => 'inna', |
145 | worker => ['nwiger', 'rcwe', 'sfz'], |
146 | status => { '!=', 'completed' } |
147 | } ), |
148 | { -type => 'expr', |
149 | op => 'and', |
150 | args => [ |
03f6671a |
151 | field_op_value(qw/requestor == inna/), |
00f4d23e |
152 | field_op_value(qw/status != completed/), |
153 | { -type => 'expr', |
154 | op => 'or', |
155 | args => [ |
156 | field_op_value(qw/worker == nwiger/), |
157 | field_op_value(qw/worker == rcwe/), |
158 | field_op_value(qw/worker == sfz/), |
159 | ] |
160 | }, |
00f4d23e |
161 | ] |
162 | }, |
03f6671a |
163 | "complex expr 1"; |
00f4d23e |
164 | |
165 | |
03f6671a |
166 | =for comment |
167 | $visitor->convert('UPPER'); |
168 | |
169 | eq_or_diff |
170 | $visitor->select_ast( |
171 | 'test', '*', [ { ticket => [11, 12, 13] } ] |
172 | ), |
173 | { -type => 'select', |
174 | columns => [ { -type => 'name', args => ['*'] } ], |
175 | tablespec => { -type => 'name', args => ['test'] }, |
176 | where => |
177 | { -type => 'expr', op => 'or', args => [ |
178 | field_op_value( upper(mk_name('ticket')), '==', upper(mk_value(11))), |
179 | field_op_value( upper(mk_name('ticket')), '==', upper(mk_value(12))), |
180 | field_op_value( upper(mk_name('ticket')), '==', upper(mk_value(13))), |
181 | ] } |
182 | }, |
183 | "Complex AST with convert('UPPER')"; |
184 | |
185 | eq_or_diff |
186 | $visitor->select_ast( |
187 | 'test', '*', [ { ticket => [11, 12, 13], |
188 | hostname => { in => ['ntf', 'avd', 'bvd', '123'] } }, |
189 | #{ tack => { between => [qw/tick tock/] } }, |
190 | #{ a => [qw/b c d/], |
191 | # e => { '!=', [qw(f g)] }, |
192 | # q => { 'not in', [14..20] } |
193 | #} |
194 | ] |
195 | ), |
196 | { -type => 'select', |
197 | columns => [ { -type => 'name', args => ['*'] } ], |
198 | tablespec => { -type => 'name', args => ['test'] }, |
199 | where => |
200 | { -type => 'expr', op => 'or', args => [ |
201 | { -type => 'expr', op => 'and', args => [ |
202 | field_op_value( upper(mk_name('hostname')), |
203 | in => [ |
204 | upper(mk_value('nft')), |
205 | upper(mk_value('avd')), |
206 | upper(mk_value('bvd')), |
207 | upper(mk_value('123')), |
208 | ] |
209 | ), |
210 | { -type => 'expr', op => 'or', args => [ |
211 | field_op_value( upper(mk_name('ticket')), '==', upper(mk_value(11))), |
212 | field_op_value( upper(mk_name('ticket')), '==', upper(mk_value(12))), |
213 | field_op_value( upper(mk_name('ticket')), '==', upper(mk_value(13))), |
214 | ] } |
215 | ] } |
216 | ] } |
217 | }, |
218 | "Complex AST with convert('UPPER')"; |
219 | =cut |
00f4d23e |
220 | |
221 | sub field_op_value { |
222 | my ($field, $op, $value) = @_; |
223 | |
224 | $field = ref $field eq 'HASH' |
225 | ? $field |
226 | : ref $field eq 'ARRAY' |
227 | ? { -type => 'name', args => $field } |
228 | : { -type => 'name', args => [$field] }; |
229 | |
03f6671a |
230 | my @value = ref $value eq 'HASH' |
231 | ? $value |
232 | : ref $value eq 'ARRAY' |
233 | ? @$value |
234 | : { -type => 'value', value => $value }; |
00f4d23e |
235 | |
236 | return { |
237 | -type => 'expr', |
238 | op => $op, |
239 | args => [ |
240 | $field, |
03f6671a |
241 | @value |
00f4d23e |
242 | ] |
243 | }; |
244 | } |
03f6671a |
245 | |
246 | sub upper { expr(UPPER => @_) } |
247 | |
248 | sub expr { |
249 | my ($op, @args) = @_; |
250 | |
251 | return { |
252 | -type => 'expr', |
253 | op => $op, |
254 | args => [@args] |
255 | }; |
256 | } |
257 | |
258 | sub mk_name { |
259 | my ($field) = @_; |
260 | $field = ref $field eq 'HASH' |
261 | ? $field |
262 | : ref $field eq 'ARRAY' |
263 | ? { -type => 'name', args => $field } |
264 | : { -type => 'name', args => [$field] }; |
265 | return $field; |
266 | } |
267 | |
268 | sub mk_value { |
269 | return { -type => 'value', value => $_[0] } |
270 | } |