Make resulting SQL work on MySQL
Peter Rabbitson [Mon, 8 Nov 2010 03:04:01 +0000 (04:04 +0100)]
Changes
lib/SQL/Abstract/Tree.pm
t/14roundtrippin.t
t/15placeholders.t
t/dbic/bulk-insert.t

diff --git a/Changes b/Changes
index 4ae8f69..ffdfcf0 100644 (file)
--- a/Changes
+++ b/Changes
@@ -8,6 +8,7 @@ Revision history for SQL::Abstract
     - Add "squash_repeats" option to fix it such that repeated SQL gets ellided
       except for placeholders
     - Fix missing doc (RT#62587)
+    - Format functions in MySQL-friendly manner foo( ... ) vs foo ( ... )
 
 revision 1.69  2010-10-22
 ----------------------------
index 1c3a82f..a8894f2 100644 (file)
@@ -488,7 +488,7 @@ sub _unparse {
     return $self->fill_in_placeholder($bindargs);
   }
   elsif ($car eq 'PAREN') {
-    return sprintf ('(%s)',
+    return sprintf ('( %s )',
       join (' ', map { $self->_unparse($_, $bindargs, $depth + 2) } @{$cdr} )
         .
       ($self->_is_key($cdr)
@@ -505,7 +505,15 @@ sub _unparse {
   }
   else {
     my ($l, $r) = @{$self->pad_keyword($car, $depth)};
-    return sprintf "$l%s %s$r", $self->format_keyword($car), $self->_unparse($cdr, $bindargs, $depth);
+
+    return sprintf "$l%s%s%s$r",
+      $self->format_keyword($car),
+      ( ref $cdr eq 'ARRAY' and ref $cdr->[0] eq 'ARRAY' and $cdr->[0][0] and $cdr->[0][0] eq 'PAREN' )
+        ? ''    # mysql--
+        : ' '
+      ,
+      $self->_unparse($cdr, $bindargs, $depth),
+    ;
   }
 }
 
index ebbca33..6279a76 100644 (file)
@@ -10,14 +10,20 @@ my @sql = (
   "INSERT INTO artist DEFAULT VALUES",
   "INSERT INTO artist VALUES ()",
   "SELECT a, b, c FROM foo WHERE foo.a =1 and foo.b LIKE 'station'",
-  "SELECT * FROM (SELECT * FROM foobar) WHERE foo.a =1 and foo.b LIKE 'station'",
+  "SELECT COUNT( * ) FROM foo",
+  "SELECT * FROM (SELECT * FROM foobar) WHERE foo.a = 1 and foo.b LIKE 'station'",
   "SELECT * FROM lolz WHERE ( foo.a =1 ) and foo.b LIKE 'station'",
   "SELECT [screen].[id], [screen].[name], [screen].[section_id], [screen].[xtype] FROM [users_roles] [me] JOIN [roles] [role] ON [role].[id] = [me].[role_id] JOIN [roles_permissions] [role_permissions] ON [role_permissions].[role_id] = [role].[id] JOIN [permissions] [permission] ON [permission].[id] = [role_permissions].[permission_id] JOIN [permissionscreens] [permission_screens] ON [permission_screens].[permission_id] = [permission].[id] JOIN [screens] [screen] ON [screen].[id] = [permission_screens].[screen_id] WHERE ( [me].[user_id] = ? ) GROUP BY [screen].[id], [screen].[name], [screen].[section_id], [screen].[xtype]",
 );
 
 for (@sql) {
-  is_same_sql($_, $sqlat->format($_), 'roundtrip works');
+  # Needs whitespace preservation in the AST to work, pending
+  #local $SQL::Abstract::Test::mysql_functions = 1;
+  is_same_sql ($sqlat->format($_), $_, sprintf 'roundtrip works (%s...)', substr $_, 0, 20);
 }
 
+# delete this test when mysql_functions gets implemented
+my $sql = 'SELECT COUNT( * ) FROM foo';
+is($sqlat->format($sql), $sql, 'Roundtripping to mysql-compatible paren. syntax');
 
 done_testing;
index a82b668..f124e03 100644 (file)
@@ -34,7 +34,7 @@ use SQL::Abstract::Tree;
    });
 
    is $sqlat->format('SELECT ? as x, ? as y FROM Foo WHERE t > ? and z IN (?, ?, ?) ', [qw/frew ribasushi 2008-12-12 1 2 3/]),
-   q[SELECT 'frew' as x, 'ribasushi' as y FROM Foo WHERE t > '2008-12-12' AND z IN ('1', '2', '3')], 'Complex placeholders work';
+   q[SELECT 'frew' as x, 'ribasushi' as y FROM Foo WHERE t > '2008-12-12' AND z IN ( '1', '2', '3' )], 'Complex placeholders work';
 }
 
 done_testing;
index 47f4660..f445ef1 100644 (file)
@@ -19,7 +19,7 @@ $pp->debugfh($fh);
 $pp->query_start('INSERT INTO self_ref_alias (alias, self_ref) VALUES ( ?, ? )', qw('__BULK_INSERT__' '1'));
 is(
    $cap,
-   qq{INSERT INTO self_ref_alias (alias, self_ref) VALUES (?, ?) : '__BULK_INSERT__', '1'\n},
+   qq{INSERT INTO self_ref_alias( alias, self_ref ) VALUES( ?, ? ) : '__BULK_INSERT__', '1'\n},
    'SQL Logged'
 );