5 use List::Util qw(sum);
11 # WHERE condition - equal
15 q/SELECT foo FROM bar WHERE a = 1/,
16 q/SELECT foo FROM bar WHERE a=1/,
17 q/SELECT foo FROM bar WHERE (a = 1)/,
18 q/SELECT foo FROM bar WHERE (a=1)/,
19 q/SELECT foo FROM bar WHERE ( a = 1 )/,
44 q/SELECT foo FROM bar WHERE ((a = 1))/,
45 q/SELECT foo FROM bar WHERE ( (a = 1) )/,
46 q/SELECT foo FROM bar WHERE ( ( a = 1 ) )/,
52 q/SELECT foo FROM bar WHERE a = 1 AND b = 1/,
53 q/SELECT foo FROM bar WHERE (a = 1) AND (b = 1)/,
54 q/SELECT foo FROM bar WHERE ((a = 1) AND (b = 1))/,
55 q/SELECT foo FROM bar WHERE (a = 1 AND b = 1)/,
56 q/SELECT foo FROM bar WHERE ((a = 1 AND b = 1))/,
57 q/SELECT foo FROM bar WHERE (((a = 1) AND (b = 1)))/,
103 q/SELECT foo FROM bar WHERE a = 1 AND b = 1 AND c = 1/,
104 q/SELECT foo FROM bar WHERE (a = 1 AND b = 1) AND c = 1/,
105 q/SELECT foo FROM bar WHERE a = 1 AND (b = 1 AND c = 1)/,
106 q/SELECT foo FROM bar WHERE ((((a = 1))) AND (b = 1 AND c = 1))/,
112 q/SELECT foo FROM bar WHERE a = 1 OR b = 1 OR c = 1/,
113 q/SELECT foo FROM bar WHERE (a = 1 OR b = 1) OR c = 1/,
114 q/SELECT foo FROM bar WHERE a = 1 OR (b = 1 OR c = 1)/,
115 q/SELECT foo FROM bar WHERE a = 1 OR ((b = 1 OR (c = 1)))/,
121 q/SELECT foo FROM bar WHERE (a = 1) AND (b = 1 OR c = 1 OR d = 1) AND (e = 1 AND f = 1)/,
122 q/SELECT foo FROM bar WHERE a = 1 AND (b = 1 OR c = 1 OR d = 1) AND e = 1 AND (f = 1)/,
123 q/SELECT foo FROM bar WHERE ( ((a = 1) AND ( b = 1 OR (c = 1 OR d = 1) )) AND ((e = 1)) AND f = 1) /,
127 # WHERE condition - different
131 q/SELECT foo FROM bar WHERE a = 1/,
132 q/SELECT quux FROM bar WHERE a = 1/,
133 q/SELECT foo FROM quux WHERE a = 1/,
134 q/FOOBAR foo FROM bar WHERE a = 1/,
136 q/SELECT foo FROM bar WHERE a = 2/,
137 q/SELECT foo FROM bar WHERE a < 1/,
138 q/SELECT foo FROM bar WHERE b = 1/,
139 q/SELECT foo FROM bar WHERE (c = 1)/,
140 q/SELECT foo FROM bar WHERE (d = 1)/,
142 q/SELECT foo FROM bar WHERE a = 1 AND quux/,
143 q/SELECT foo FROM bar WHERE a = 1 GROUP BY foo/,
144 q/SELECT foo FROM bar WHERE a = 1 ORDER BY foo/,
145 q/SELECT foo FROM bar WHERE a = 1 LIMIT 1/,
146 q/SELECT foo FROM bar WHERE a = 1 OFFSET 1/,
147 q/SELECT foo FROM bar JOIN quux WHERE a = 1/,
148 q/SELECT foo FROM bar JOIN quux ON a = 1 WHERE a = 1/,
154 q/SELECT foo FROM bar WHERE a = 1 AND b = 1/,
155 q/SELECT quux FROM bar WHERE a = 1 AND b = 1/,
156 q/SELECT foo FROM quux WHERE a = 1 AND b = 1/,
157 q/FOOBAR foo FROM bar WHERE a = 1 AND b = 1/,
159 q/SELECT foo FROM bar WHERE a = 2 AND b = 1/,
160 q/SELECT foo FROM bar WHERE a = 3 AND (b = 1)/,
161 q/SELECT foo FROM bar WHERE (a = 4) AND b = 1/,
162 q/SELECT foo FROM bar WHERE (a = 5) AND (b = 1)/,
163 q/SELECT foo FROM bar WHERE ((a = 6) AND (b = 1))/,
164 q/SELECT foo FROM bar WHERE ((a = 7) AND (b = 1))/,
166 q/SELECT foo FROM bar WHERE a = 1 AND b = 2/,
167 q/SELECT foo FROM bar WHERE a = 1 AND (b = 3)/,
168 q/SELECT foo FROM bar WHERE (a = 1) AND b = 4/,
169 q/SELECT foo FROM bar WHERE (a = 1) AND (b = 5)/,
170 q/SELECT foo FROM bar WHERE ((a = 1) AND (b = 6))/,
171 q/SELECT foo FROM bar WHERE ((a = 1) AND (b = 7))/,
173 q/SELECT foo FROM bar WHERE a < 1 AND b = 1/,
174 q/SELECT foo FROM bar WHERE b = 1 AND b = 1/,
175 q/SELECT foo FROM bar WHERE (c = 1) AND b = 1/,
176 q/SELECT foo FROM bar WHERE (d = 1) AND b = 1/,
178 q/SELECT foo FROM bar WHERE a = 1 AND b = 1 AND quux/,
179 q/SELECT foo FROM bar WHERE a = 1 AND b = 1 GROUP BY foo/,
180 q/SELECT foo FROM bar WHERE a = 1 AND b = 1 ORDER BY foo/,
181 q/SELECT foo FROM bar WHERE a = 1 AND b = 1 LIMIT 1/,
182 q/SELECT foo FROM bar WHERE a = 1 AND b = 1 OFFSET 1/,
183 q/SELECT foo FROM bar JOIN quux WHERE a = 1 AND b = 1/,
184 q/SELECT foo FROM bar JOIN quux ON a = 1 WHERE a = 1 AND b = 1/,
190 q/SELECT foo FROM bar WHERE a = 1 AND b = 1 OR c = 1/,
191 q/SELECT foo FROM bar WHERE (a = 1 AND b = 1) OR c = 1/,
192 q/SELECT foo FROM bar WHERE a = 1 AND (b = 1 OR c = 1)/,
198 q/SELECT foo FROM bar WHERE a = 1 OR b = 1 AND c = 1/,
199 q/SELECT foo FROM bar WHERE (a = 1 OR b = 1) AND c = 1/,
200 q/SELECT foo FROM bar WHERE a = 1 OR (b = 1 AND c = 1)/,
206 q/SELECT foo FROM bar WHERE ( completion_date BETWEEN ? AND ? AND status = ? )/,
207 q/SELECT foo FROM bar WHERE ( (completion_date BETWEEN ? AND ?) AND status = ? )/,
211 # JOIN condition - equal
215 q/SELECT foo FROM bar JOIN baz ON a = 1 WHERE x = 1/,
216 q/SELECT foo FROM bar JOIN baz ON a=1 WHERE x = 1/,
217 q/SELECT foo FROM bar JOIN baz ON (a = 1) WHERE x = 1/,
218 q/SELECT foo FROM bar JOIN baz ON (a=1) WHERE x = 1/,
219 q/SELECT foo FROM bar JOIN baz ON ( a = 1 ) WHERE x = 1/,
256 q/SELECT foo FROM bar JOIN baz ON ((a = 1)) WHERE x = 1/,
257 q/SELECT foo FROM bar JOIN baz ON ( (a = 1) ) WHERE x = 1/,
258 q/SELECT foo FROM bar JOIN baz ON ( ( a = 1 ) ) WHERE x = 1/,
264 q/SELECT foo FROM bar JOIN baz ON a = 1 AND b = 1 WHERE x = 1/,
265 q/SELECT foo FROM bar JOIN baz ON (a = 1) AND (b = 1) WHERE x = 1/,
266 q/SELECT foo FROM bar JOIN baz ON ((a = 1) AND (b = 1)) WHERE x = 1/,
267 q/SELECT foo FROM bar JOIN baz ON (a = 1 AND b = 1) WHERE x = 1/,
268 q/SELECT foo FROM bar JOIN baz ON ((a = 1 AND b = 1)) WHERE x = 1/,
269 q/SELECT foo FROM bar JOIN baz ON (((a = 1) AND (b = 1))) WHERE x = 1/,
329 # JOIN condition - different
333 q/SELECT foo FROM bar JOIN quux ON a = 1 WHERE quuux/,
334 q/SELECT quux FROM bar JOIN quux ON a = 1 WHERE quuux/,
335 q/SELECT foo FROM quux JOIN quux ON a = 1 WHERE quuux/,
336 q/FOOBAR foo FROM bar JOIN quux ON a = 1 WHERE quuux/,
338 q/SELECT foo FROM bar JOIN quux ON a = 2 WHERE quuux/,
339 q/SELECT foo FROM bar JOIN quux ON a < 1 WHERE quuux/,
340 q/SELECT foo FROM bar JOIN quux ON b = 1 WHERE quuux/,
341 q/SELECT foo FROM bar JOIN quux ON (c = 1) WHERE quuux/,
342 q/SELECT foo FROM bar JOIN quux ON (d = 1) WHERE quuux/,
344 q/SELECT foo FROM bar JOIN quux ON a = 1 AND quuux/,
345 q/SELECT foo FROM bar JOIN quux ON a = 1 GROUP BY foo/,
346 q/SELECT foo FROM bar JOIN quux ON a = 1 ORDER BY foo/,
347 q/SELECT foo FROM bar JOIN quux ON a = 1 LIMIT 1/,
348 q/SELECT foo FROM bar JOIN quux ON a = 1 OFFSET 1/,
349 q/SELECT foo FROM bar JOIN quux ON a = 1 JOIN quuux/,
350 q/SELECT foo FROM bar JOIN quux ON a = 1 JOIN quuux ON a = 1/,
356 q/SELECT foo FROM bar JOIN quux ON a = 1 AND b = 1 WHERE quuux/,
357 q/SELECT quux FROM bar JOIN quux ON a = 1 AND b = 1 WHERE quuux/,
358 q/SELECT foo FROM quux JOIN quux ON a = 1 AND b = 1 WHERE quuux/,
359 q/FOOBAR foo FROM bar JOIN quux ON a = 1 AND b = 1 WHERE quuux/,
361 q/SELECT foo FROM bar JOIN quux ON a = 2 AND b = 1 WHERE quuux/,
362 q/SELECT foo FROM bar JOIN quux ON a = 3 AND (b = 1) WHERE quuux/,
363 q/SELECT foo FROM bar JOIN quux ON (a = 4) AND b = 1 WHERE quuux/,
364 q/SELECT foo FROM bar JOIN quux ON (a = 5) AND (b = 1) WHERE quuux/,
365 q/SELECT foo FROM bar JOIN quux ON ((a = 6) AND (b = 1)) WHERE quuux/,
366 q/SELECT foo FROM bar JOIN quux ON ((a = 7) AND (b = 1)) WHERE quuux/,
368 q/SELECT foo FROM bar JOIN quux ON a = 1 AND b = 2 WHERE quuux/,
369 q/SELECT foo FROM bar JOIN quux ON a = 1 AND (b = 3) WHERE quuux/,
370 q/SELECT foo FROM bar JOIN quux ON (a = 1) AND b = 4 WHERE quuux/,
371 q/SELECT foo FROM bar JOIN quux ON (a = 1) AND (b = 5) WHERE quuux/,
372 q/SELECT foo FROM bar JOIN quux ON ((a = 1) AND (b = 6)) WHERE quuux/,
373 q/SELECT foo FROM bar JOIN quux ON ((a = 1) AND (b = 7)) WHERE quuux/,
375 q/SELECT foo FROM bar JOIN quux ON a < 1 AND b = 1 WHERE quuux/,
376 q/SELECT foo FROM bar JOIN quux ON b = 1 AND b = 1 WHERE quuux/,
377 q/SELECT foo FROM bar JOIN quux ON (c = 1) AND b = 1 WHERE quuux/,
378 q/SELECT foo FROM bar JOIN quux ON (d = 1) AND b = 1 WHERE quuux/,
380 q/SELECT foo FROM bar JOIN quux ON a = 1 AND b = 1 AND quuux/,
381 q/SELECT foo FROM bar JOIN quux ON a = 1 AND b = 1 GROUP BY foo/,
382 q/SELECT foo FROM bar JOIN quux ON a = 1 AND b = 1 ORDER BY foo/,
383 q/SELECT foo FROM bar JOIN quux ON a = 1 AND b = 1 LIMIT 1/,
384 q/SELECT foo FROM bar JOIN quux ON a = 1 AND b = 1 OFFSET 1/,
385 q/SELECT foo FROM bar JOIN quux JOIN quuux ON a = 1 AND b = 1/,
386 q/SELECT foo FROM bar JOIN quux ON a = 1 JOIN quuux ON a = 1 AND b = 1/,
390 # DISTINCT ON (...) not confused with JOIN ON (...)
394 q/SELECT DISTINCT ON (foo, quux) foo, quux FROM bar WHERE a = 1/,
395 q/SELECT DISTINCT ON (foo, quux) foo, quux FROM bar WHERE a=1/,
396 q/SELECT DISTINCT ON (foo, quux) foo, quux FROM bar WHERE (a = 1)/,
397 q/SELECT DISTINCT ON (foo, quux) foo, quux FROM bar WHERE (a=1)/,
398 q/SELECT DISTINCT ON (foo, quux) foo, quux FROM bar WHERE ( a = 1 )/,
400 SELECT DISTINCT ON (foo, quux)
409 SELECT DISTINCT ON (foo, quux)
418 SELECT DISTINCT ON (foo, quux)
426 q/SELECT DISTINCT ON (foo, quux) foo, quux FROM bar WHERE ((a = 1))/,
427 q/SELECT DISTINCT ON (foo, quux) foo, quux FROM bar WHERE ( (a = 1) )/,
428 q/SELECT DISTINCT ON (foo, quux) foo, quux FROM bar WHERE ( ( a = 1 ) )/,
436 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1) AS foo WHERE a = 1/,
437 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1) AS foo WHERE (a = 1)/,
438 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1)) AS foo WHERE a = 1/,
439 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1)) AS foo WHERE (a = 1)/,
445 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND c = 1) AS foo WHERE a = 1/,
446 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND (c = 1)) AS foo WHERE a = 1/,
447 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND c = 1) AS foo WHERE a = 1/,
448 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND (c = 1)) AS foo WHERE a = 1/,
449 q/SELECT * FROM (SELECT * FROM bar WHERE ((b = 1) AND (c = 1))) AS foo WHERE a = 1/,
451 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND c = 1) AS foo WHERE (a = 1)/,
452 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND (c = 1)) AS foo WHERE (a = 1)/,
453 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND c = 1) AS foo WHERE (a = 1)/,
454 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND (c = 1)) AS foo WHERE (a = 1)/,
455 q/SELECT * FROM (SELECT * FROM bar WHERE ((b = 1) AND (c = 1))) AS foo WHERE (a = 1)/,
459 # subselects - different
463 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1) AS foo WHERE a = 1/,
464 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1) AS foo WHERE a = 2/,
465 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1) AS foo WHERE (a = 3)/,
466 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1)) AS foo WHERE a = 4/,
467 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1)) AS foo WHERE (a = 5)/,
468 q/SELECT * FROM (SELECT * FROM bar WHERE b = 2) AS foo WHERE a = 1/,
469 q/SELECT * FROM (SELECT * FROM bar WHERE b = 3) AS foo WHERE (a = 1)/,
470 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 4)) AS foo WHERE a = 1/,
471 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 5)) AS foo WHERE (a = 1)/,
477 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND c = 1) AS foo WHERE a = 1/,
478 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND c = 2) AS foo WHERE a = 1/,
479 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND (c = 3)) AS foo WHERE a = 1/,
480 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND (c = 4)) AS foo WHERE a = 1/,
481 q/SELECT * FROM (SELECT * FROM bar WHERE ((b = 1) AND (c = 5))) AS foo WHERE a = 1/,
483 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND c = 6) AS foo WHERE (a = 1)/,
484 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND c = 7) AS foo WHERE (a = 1)/,
485 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND (c = 8)) AS foo WHERE (a = 1)/,
486 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND (c = 9)) AS foo WHERE (a = 1)/,
487 q/SELECT * FROM (SELECT * FROM bar WHERE ((b = 1) AND (c = 10))) AS foo WHERE (a = 1)/,
489 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND c = 1) AS foo WHERE a = 2/,
490 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND c = 2) AS foo WHERE a = 2/,
491 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND (c = 3)) AS foo WHERE a = 2/,
492 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND (c = 4)) AS foo WHERE a = 2/,
493 q/SELECT * FROM (SELECT * FROM bar WHERE ((b = 1) AND (c = 5))) AS foo WHERE a = 2/,
495 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND c = 6) AS foo WHERE (a = 2)/,
496 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND c = 7) AS foo WHERE (a = 2)/,
497 q/SELECT * FROM (SELECT * FROM bar WHERE b = 1 AND (c = 8)) AS foo WHERE (a = 2)/,
498 q/SELECT * FROM (SELECT * FROM bar WHERE (b = 1) AND (c = 9)) AS foo WHERE (a = 2)/,
499 q/SELECT * FROM (SELECT * FROM bar WHERE ((b = 1) AND (c = 10))) AS foo WHERE (a = 2)/,
585 { foo => 42, bar => 1 },
586 { foo => 42, bar => 1 },
587 { foo => '42', bar => 1 },
591 # blessed object - equal
595 bless(\(local $_ = 42), 'Life::Universe::Everything'),
596 bless(\(local $_ = 42), 'Life::Universe::Everything'),
602 bless([42], 'Life::Universe::Everything'),
603 bless([42], 'Life::Universe::Everything'),
609 bless({ answer => 42 }, 'Life::Universe::Everything'),
610 bless({ answer => 42 }, 'Life::Universe::Everything'),
614 # complex data structure - equal
618 [42, { foo => 'bar', quux => [1, 2, \3, { quux => [4, 5] } ] }, 8 ],
619 [42, { foo => 'bar', quux => [1, 2, \3, { quux => [4, 5] } ] }, 8 ],
634 # scalarref - different
644 # arrayref - different
654 # hashref - different
675 # complex data structure - different
679 [42, { foo => 'bar', quux => [1, 2, \3, { quux => [4, 5] } ] }, 8 ],
680 [43, { foo => 'bar', quux => [1, 2, \3, { quux => [4, 5] } ] }, 8 ],
681 [42, { foo => 'baz', quux => [1, 2, \3, { quux => [4, 5] } ] }, 8 ],
682 [42, { bar => 'bar', quux => [1, 2, \3, { quux => [4, 5] } ] }, 8 ],
683 [42, { foo => 'bar', quuux => [1, 2, \3, { quux => [4, 5] } ] }, 8 ],
684 [42, { foo => 'bar', quux => [0, 1, 2, \3, { quux => [4, 5] } ] }, 8 ],
685 [42, { foo => 'bar', quux => [1, 2, 3, { quux => [4, 5] } ] }, 8 ],
686 [42, { foo => 'bar', quux => [1, 2, \4, { quux => [4, 5] } ] }, 8 ],
687 [42, { foo => 'bar', quux => [1, 2, \3, { quuux => [4, 5] } ] }, 8 ],
688 [42, { foo => 'bar', quux => [1, 2, \3, { quux => [4, 5, 6] } ] }, 8 ],
689 [42, { foo => 'bar', quux => [1, 2, \3, { quux => 4 } ] }, 8 ],
690 [42, { foo => 'bar', quux => [1, 2, \3, { quux => [4, 5], quuux => 1 } ] }, 8 ],
691 [42, { foo => 'bar', quux => [1, 2, \3, { quux => [4, 5] } ] }, 8, 9 ],
698 map { $_ * ($_ - 1) / 2 }
699 map { scalar @{$_->{statements}} }
703 map { $_ * ($_ - 1) / 2 }
704 map { scalar @{$_->{bindvals}} }
709 use_ok('SQL::Abstract::Test', import => [qw(
710 eq_sql_bind eq_sql eq_bind is_same_sql_bind
713 for my $test (@sql_tests) {
714 my $statements = $test->{statements};
715 while (@$statements) {
716 my $sql1 = shift @$statements;
717 foreach my $sql2 (@$statements) {
718 my $equal = eq_sql($sql1, $sql2);
720 local $TODO = $test->{todo} if $test->{todo};
722 if ($test->{equal}) {
723 ok($equal, "equal SQL expressions should have been considered equal");
725 ok(!$equal, "different SQL expressions should have been considered not equal");
728 if ($equal ^ $test->{equal}) {
737 for my $test (@bind_tests) {
738 my $bindvals = $test->{bindvals};
740 my $bind1 = shift @$bindvals;
741 foreach my $bind2 (@$bindvals) {
742 my $equal = eq_bind($bind1, $bind2);
743 if ($test->{equal}) {
744 ok($equal, "equal bind values considered equal");
746 ok(!$equal, "different bind values considered not equal");
749 if ($equal ^ $test->{equal}) {
750 diag("bind1: " . Dumper($bind1));
751 diag("bind2: " . Dumper($bind2));
758 "SELECT * FROM foo WHERE id = ?", [42],
759 "SELECT * FROM foo WHERE (id = ?)", [42],
761 "eq_sql_bind considers equal SQL expressions and bind values equal"
766 "SELECT * FROM foo WHERE id = ?", [42],
767 "SELECT * FROM foo WHERE (id = ?)", [0],
769 "eq_sql_bind considers equal SQL expressions and different bind values different"
773 "SELECT * FROM foo WHERE id = ?", [42],
774 "SELECT * FROM bar WHERE (id = ?)", [42],
776 "eq_sql_bind considers different SQL expressions and equal bind values different"