Really fix mysql CURRENT_TIMESTAMP handling (solves RT#65844)
Peter Rabbitson [Wed, 25 Jan 2012 10:47:33 +0000 (11:47 +0100)]
Changes
lib/SQL/Translator/Parser/MySQL.pm
t/02mysql-parser.t

diff --git a/Changes b/Changes
index c26fd16..22dbeba 100644 (file)
--- a/Changes
+++ b/Changes
@@ -17,6 +17,7 @@
   fix by not adding the ON DELETE/UPDATE clause at all
 * Changed dependency on Digest::SHA1 to the core-bundled Digest::SHA (RT#67989)
 * Support for double quoted and bit strings as default values in MySQL parser
+* Proper handling of CURRENT_TIMESTAMP default values in MySQL parser (RT#65844)
 * Check in MySQL parser to avoid trying to parse a table defined twice in the same
   file as indices (and probably other things) get messed up
 * Workaround for some MySQL quirks on primary key definitions
index e1c8da2..bab8dd8 100644 (file)
@@ -509,7 +509,7 @@ on_delete : /on delete/i reference_option
     { $item[2] }
 
 on_update :
-    /on update/i 'CURRENT_TIMESTAMP'
+    /on update/i CURRENT_TIMESTAMP
     { $item[2] }
     |
     /on update/i reference_option
@@ -579,9 +579,9 @@ not_null     : /not/i /null/i
 unsigned     : /unsigned/i { $return = 0 }
 
 default_val :
-    /default/i 'CURRENT_TIMESTAMP'
+    /default/i CURRENT_TIMESTAMP
     {
-        $return =  \$item[2];
+        $return =  $item[2];
     }
     |
     /default/i string
@@ -783,9 +783,10 @@ VALUE : /[-+]?\.?\d+(?:[eE]\d+)?/
     | /NULL/
     { 'NULL' }
 
-CURRENT_TIMESTAMP : /current_timestamp(\(\))?/i
-    | /now\(\)/i
-    { 'CURRENT_TIMESTAMP' }
+# always a scalar-ref, so that it is treated as a function and not quoted by consumers
+CURRENT_TIMESTAMP :
+      /current_timestamp(\(\))?/i { \'CURRENT_TIMESTAMP' }
+    | /now\(\)/i { \'CURRENT_TIMESTAMP' }
 
 END_OF_GRAMMAR
 
index 81ddb63..45321cc 100644 (file)
@@ -12,7 +12,7 @@ use Test::SQL::Translator qw(maybe_plan);
 use FindBin qw/$Bin/;
 
 BEGIN {
-    maybe_plan(343, "SQL::Translator::Parser::MySQL");
+    maybe_plan(346, "SQL::Translator::Parser::MySQL");
     SQL::Translator::Parser::MySQL->import('parse');
 }
 
@@ -521,7 +521,8 @@ BEGIN {
             DELIMITER ;
             CREATE TABLE one (
               `op` varchar(255) character set latin1 collate latin1_bin default NULL,
-              `last_modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+              `last_modified` timestamp NOT NULL default Current_Timestamp on update CURRENT_TIMESTAMP,
+              `created_at` datetime NOT NULL Default CURRENT_TIMESTAMP(),
             ) TYPE=INNODB DEFAULT CHARSET=latin1;
 
             /*!50001 CREATE ALGORITHM=UNDEFINED */
@@ -612,7 +613,7 @@ BEGIN {
     is( $table1->name, 'one', 'Found "one" table' );
 
     my @fields = $table1->get_fields;
-    is(scalar @fields, 2, 'Right number of fields (2) on table one');
+    is(scalar @fields, 3, 'Right number of fields (3) on table one');
     my $tableTypeFound = 0;
     my $charsetFound = 0;
     for my $t1_option_ref ( $table1->options ) {
@@ -643,7 +644,16 @@ BEGIN {
       \'CURRENT_TIMESTAMP',
       'Field has right default value'
     );
-    is( $t1f2->extra('on update'), 'CURRENT_TIMESTAMP', 'Field has right on update qualifier' );
+    is_deeply( $t1f2->extra('on update'), \'CURRENT_TIMESTAMP', 'Field has right on update qualifier' );
+
+    my $t1f3 = shift @fields;
+    is( $t1f3->data_type, 'datetime', 'Field is a datetime' );
+    ok( !$t1f3->is_nullable, 'Field is not nullable' );
+    is_deeply(
+      $t1f3->default_value,
+      \'CURRENT_TIMESTAMP',
+      'Field has right default value'
+    );
 
     my @views = $schema->get_views;
     is( scalar @views, 3, 'Right number of views (3)' );