Sort hash keys so that the SQL produced is stable
[dbsrgits/SQL-Abstract-2.0-ish.git] / t / compat / ast / 01.t
CommitLineData
d70ca130 1use strict;
2use warnings;
3
03f6671a 4use FindBin;
5use lib "$FindBin::Bin/../../lib";
6use SQLADumperSort;
7
1c51edc4 8use SQL::Abstract::Compat;
d70ca130 9
00f4d23e 10use Test::More tests => 12;
d70ca130 11use Test::Differences;
12
1c51edc4 13ok(my $visitor = SQL::Abstract::Compat->new);
d70ca130 14
00f4d23e 15
c6039348 16my $foo_id = { -type => 'name', args => [qw/foo/] };
17my $bar_id = { -type => 'name', args => [qw/bar/] };
18
00f4d23e 19my $foo_eq_1 = field_op_value($foo_id, '==', 1);
20my $bar_eq_str = field_op_value($bar_id, '==', 'some str');
d70ca130 21
22eq_or_diff
37716782 23 $visitor->recurse_where({ foo => 1 }),
d70ca130 24 $foo_eq_1,
25 "Single value hash";
26
27
d70ca130 28
29eq_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
40eq_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
52eq_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
64eq_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
81eq_or_diff
37716782 82 $visitor->recurse_where({ foo => { '!=' => 'bar' } }),
00f4d23e 83 field_op_value($foo_id, '!=', 'bar'),
c6039348 84 "foo => { '!=' => 'bar' }";
85
86eq_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 97eq_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
109eq_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
121eq_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 131my $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 142eq_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
169eq_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
185eq_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
221sub 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
246sub upper { expr(UPPER => @_) }
247
248sub expr {
249 my ($op, @args) = @_;
250
251 return {
252 -type => 'expr',
253 op => $op,
254 args => [@args]
255 };
256}
257
258sub 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
268sub mk_value {
269 return { -type => 'value', value => $_[0] }
270}