use Test::More;
+use Data::Dumper;
+$Data::Dumper::Terse = 1;
+$Data::Dumper::Sortkeys = 1;
my @sql_tests = (
# WHERE condition - equal
]
},
{
+ equal => 1,
+ statements => [
+ q/SELECT foo FROM bar WHERE (a) AND (b = 2)/,
+ q/SELECT foo FROM bar WHERE (a AND b = 2)/,
+ q/SELECT foo FROM bar WHERE (a AND (b = 2))/,
+ q/SELECT foo FROM bar WHERE a AND (b = 2)/,
+ ]
+ },
+ {
+ equal => 1,
+ statements => [
+ q/SELECT foo FROM bar WHERE ((NOT a) AND b = 2)/,
+ q/SELECT foo FROM bar WHERE (NOT a) AND (b = 2)/,
+ q/SELECT foo FROM bar WHERE (NOT (a)) AND b = 2/,
+ ],
+ },
+ {
+ equal => 0,
+ statements => [
+ q/SELECT foo FROM bar WHERE NOT a AND (b = 2)/,
+ q/SELECT foo FROM bar WHERE (NOT a) AND (b = 2)/,
+ ]
+ },
+ {
equal => 0,
parenthesis_significant => 1,
statements => [
},
{
equal => 0,
+ parenthesis_significant => 1,
+ statements => [
+ q/SELECT foo FROM bar WHERE a IN (1,2,3)/,
+ q/SELECT foo FROM bar WHERE a IN (1,3,2)/,
+ q/SELECT foo FROM bar WHERE a IN ((1,2,3))/,
+ ]
+ },
+ {
+ equal => 0,
statements => [
# BETWEEN with/without parenthesis around itself/RHS is a sticky business
# if I made a mistake here, simply rewrite the special BETWEEN handling in
]
},
+ # IS NULL (special LHS-only op)
+ {
+ equal => 1,
+ statements => [
+ q/WHERE a IS NOT NULL AND b IS NULL/,
+ q/WHERE (a IS NOT NULL) AND b IS NULL/,
+ q/WHERE a IS NOT NULL AND (b IS NULL)/,
+ q/WHERE (a IS NOT NULL) AND ((b IS NULL))/,
+ ],
+ },
+
# JOIN condition - equal
{
equal => 1,
{
equal => 0,
statements => [
+ q/DELETE FROM cd WHERE ( cdid IN ( SELECT me.cdid FROM (SELECT * FROM cd me WHERE ( year != ? ) GROUP BY me.cdid) me WHERE ( year != ? ) ) )/,
+ q/DELETE FROM cd WHERE ( cdid IN ( SELECT me.cdid FROM cd me WHERE ( year != ? ) GROUP BY me.cdid ) )/,
+ ],
+ },
+ {
+ equal => 0,
+ statements => [
q/SELECT * FROM (SELECT * FROM bar WHERE b = 1) AS foo WHERE a = 1/,
q/SELECT * FROM (SELECT * FROM bar WHERE b = 1) AS foo WHERE a = 2/,
q/SELECT * FROM (SELECT * FROM bar WHERE b = 1) AS foo WHERE (a = 3)/,
q/SELECT * FROM (SELECT * FROM bar WHERE ((b = 1) AND (c = 10))) AS foo WHERE (a = 2)/,
]
},
+
+ # list permutations
+ {
+ equal => 0,
+ statements => [
+ 'SELECT a,b,c FROM foo',
+ 'SELECT a,c,b FROM foo',
+ 'SELECT b,a,c FROM foo',
+ 'SELECT b,c,a FROM foo',
+ 'SELECT c,a,b FROM foo',
+ 'SELECT c,b,a FROM foo',
+ ],
+ },
+ {
+ equal => 0,
+ statements => [
+ 'SELECT * FROM foo WHERE a IN (1,2,3)',
+ 'SELECT * FROM foo WHERE a IN (1,3,2)',
+ 'SELECT * FROM foo WHERE a IN (2,1,3)',
+ 'SELECT * FROM foo WHERE a IN (2,3,1)',
+ 'SELECT * FROM foo WHERE a IN (3,1,2)',
+ 'SELECT * FROM foo WHERE a IN (3,2,1)',
+ ]
+ },
+
+ # list consistency
+ {
+ equal => 0,
+ statements => [
+ 'SELECT a,b FROM foo',
+ 'SELECT a,,b FROM foo',
+ 'SELECT a,b, FROM foo',
+ 'SELECT ,a,b, FROM foo',
+ 'SELECT ,a,,b, FROM foo',
+ ],
+ },
+
+ # misc func
+ {
+ equal => 0,
+ statements => [
+ 'SELECT count(*) FROM foo',
+ 'SELECT count(*) AS bar FROM foo',
+ 'SELECT count(*) AS "bar" FROM foo',
+ 'SELECT count(a) FROM foo',
+ 'SELECT count(1) FROM foo',
+ ]
+ },
+ {
+ equal => 1,
+ statements => [
+ 'SELECT foo() bar FROM baz',
+ 'SELECT foo ( )bar FROM baz',
+ 'SELECT foo (())bar FROM baz',
+ 'SELECT foo(( ) ) bar FROM baz',
+ ]
+ },
+ {
+ equal => 0,
+ statements => [
+ 'SELECT foo() FROM bar',
+ 'SELECT foo FROM bar',
+ 'SELECT foo FROM bar ()',
+ ]
+ },
+ {
+ equal => 0,
+ statements => [
+ 'SELECT COUNT * FROM foo',
+ 'SELECT COUNT( * ) FROM foo',
+ ]
+ },
+ # single ? of unknown funcs do not unroll unless
+ # explicitly allowed (e.g. Like)
+ {
+ equal => 0,
+ statements => [
+ 'SELECT foo FROM bar WHERE bar > foo ?',
+ 'SELECT foo FROM bar WHERE bar > foo( ? )',
+ ]
+ },
+ {
+ equal => 1,
+ statements => [
+ 'SELECT foo FROM bar WHERE bar LIKE ?',
+ 'SELECT foo FROM bar WHERE bar LiKe (?)',
+ 'SELECT foo FROM bar WHERE bar lIkE( (?))',
+ ]
+ },
+ # test multival
+ {
+ equal => 0,
+ statements => [
+ 'SELECT foo FROM bar WHERE foo IN (?, ?)',
+ 'SELECT foo FROM bar WHERE foo IN ?, ?',
+ ]
+ },
+ # math
+ {
+ equal => 0,
+ statements => [
+ 'SELECT * FROM foo WHERE 1 = ( a > b)',
+ 'SELECT * FROM foo WHERE 1 = a > b',
+ 'SELECT * FROM foo WHERE (1 = a) > b',
+ ]
+ },
+ {
+ equal => 1,
+ statements => [
+ 'SELECT * FROM foo WHERE bar = baz(buzz)',
+ 'SELECT * FROM foo WHERE bar = (baz( buzz ))',
+ ]
+ },
+ # oddballs
+ {
+ equal => 1,
+ statements => [
+ 'WHERE ( foo GLOB ? )',
+ 'WHERE foo GLOB ?',
+ ],
+ },
+ {
+ equal => 1,
+ statements => [
+ 'SELECT FIRST ? SKIP ? [me].[id], [me].[owner]
+ FROM [books] [me]
+ WHERE ( ( (EXISTS (
+ SELECT FIRST ? SKIP ? [owner].[id]
+ FROM [owners] [owner]
+ WHERE ( [books].[owner] = [owner].[id] )
+ )) AND [source] = ? ) )',
+ 'SELECT FIRST ? SKIP ? [me].[id], [me].[owner]
+ FROM [books] [me]
+ WHERE ( ( EXISTS (
+ SELECT FIRST ? SKIP ? [owner].[id]
+ FROM [owners] [owner]
+ WHERE ( [books].[owner] = [owner].[id] )
+ ) AND [source] = ? ) )',
+ ],
+ },
);
my @bind_tests = (
map { scalar @{$_->{bindvals}} }
@bind_tests
) +
- 3;
+ 9;
use_ok('SQL::Abstract::Test', import => [qw(
eq_sql_bind eq_sql eq_bind is_same_sql_bind
}
if ($equal ^ $test->{equal}) {
- diag("sql1: $sql1");
- diag("sql2: $sql2");
+ my ($ast1, $ast2) = map { SQL::Abstract::Test::parse ($_) } ($sql1, $sql2);
+ $_ = Dumper $_ for ($ast1, $ast2);
+
+ diag "sql1: $sql1";
+ diag "sql2: $sql2";
+ note $SQL::Abstract::Test::sql_differ;
+ note "ast1: $ast1";
+ note "ast2: $ast2";
}
}
}
),
"eq_sql_bind considers different SQL expressions and equal bind values different"
);
+
+# test diag string
+ok (! eq_sql (
+ 'SELECT owner_name FROM books me WHERE ( source = ? )',
+ 'SELECT owner_name FROM books me WHERE ( sUOrce = ? )',
+));
+like(
+ $SQL::Abstract::Test::sql_differ,
+ qr/\Q[ source ] != [ sUOrce ]/,
+ 'expected debug of literal diff',
+);
+
+ok (! eq_sql (
+ 'SELECT owner_name FROM books me ORDER BY owner_name',
+ 'SELECT owner_name FROM books me GROUP BY owner_name',
+));
+like(
+ $SQL::Abstract::Test::sql_differ,
+ qr/\QOP [ORDER BY] != [GROUP BY]/,
+ 'expected debug of op diff',
+);
+
+ok (! eq_sql (
+ 'SELECT owner_name FROM books WHERE ( source = ? )',
+ 'SELECT owner_name FROM books'
+));
+
+like(
+ $SQL::Abstract::Test::sql_differ,
+ qr|\Q[WHERE source = ?] != [N/A]|,
+ 'expected debug of missing branch',
+);
+