DB2.pm the first
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Parser / PostgreSQL.pm
index 47736c3..14ceff1 100644 (file)
@@ -1,7 +1,7 @@
 package SQL::Translator::Parser::PostgreSQL;
 
 # -------------------------------------------------------------------
-# $Id: PostgreSQL.pm,v 1.39 2004-08-11 22:00:39 kycl4rk Exp $
+# $Id: PostgreSQL.pm,v 1.43 2004-10-23 20:18:44 cmungall Exp $
 # -------------------------------------------------------------------
 # Copyright (C) 2002-4 SQLFairy Authors
 #
@@ -108,7 +108,7 @@ View table:
 
 use strict;
 use vars qw[ $DEBUG $VERSION $GRAMMAR @EXPORT_OK ];
-$VERSION = sprintf "%d.%02d", q$Revision: 1.39 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.43 $ =~ /(\d+)\.(\d+)/;
 $DEBUG   = 0 unless defined $DEBUG;
 
 use Data::Dumper;
@@ -139,10 +139,12 @@ $GRAMMAR = q!
 startrule : statement(s) eofile { \%tables }
 
 eofile : /^\Z/
+   
 
 statement : create
   | comment_on_table
   | comment_on_column
+  | comment_on_other
   | comment
   | alter
   | grant
@@ -273,14 +275,55 @@ comment_on_column : /comment/i /on/i /column/i column_name /is/i comment_phrase
     {
         my $table_name = $item[4]->{'table'};
         my $field_name = $item[4]->{'field'};
-        push @{ $tables{ $table_name }{'fields'}{ $field_name }{'comments'} }, 
-            $item{'comment_phrase'};
+        if ($tables{ $table_name }{'fields'}{ $field_name } ) {
+          push @{ $tables{ $table_name }{'fields'}{ $field_name }{'comments'} }, 
+              $item{'comment_phrase'};
+        }
+        else {
+           die "No such column as $table_name.$field_name";
+        }
+    }
+
+comment_on_other : /comment/i /on/i /\w+/ /\w+/ /is/i comment_phrase ';'
+    {
+        push(@table_comments, $item{'comment_phrase'});
     }
 
+# [added by cjm 20041019]
+# [TODO: other comment-on types]
+# for now we just have a general mechanism for handling other
+# kinds of comments than table/column; I'm not sure of the best
+# way to incorporate these into the datamodel
+#
+# this is the exhaustive list of types of comment:
+#COMMENT ON DATABASE my_database IS 'Development Database';
+#COMMENT ON INDEX my_index IS 'Enforces uniqueness on employee id';
+#COMMENT ON RULE my_rule IS 'Logs UPDATES of employee records';
+#COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys';
+#COMMENT ON TABLE my_table IS 'Employee Information';
+#COMMENT ON TYPE my_type IS 'Complex Number support';
+#COMMENT ON VIEW my_view IS 'View of departmental costs';
+#COMMENT ON COLUMN my_table.my_field IS 'Employee ID number';
+#COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for R.I.';
+#
+# this is tested by test 08
+
 column_name : NAME '.' NAME
     { $return = { table => $item[1], field => $item[3] } }
 
-comment_phrase : /'.*?'|NULL/ 
+comment_phrase : /null/i
+    { $return = 'NULL' }
+
+comment_phrase : /'/ comment_phrase_unquoted(s) /'/
+    { my $phrase = join(' ', @{ $item[2] });
+      $return = $phrase}
+
+# [cjm TODO: double-single quotes in a comment_phrase]
+comment_phrase_unquoted : /[^\']*/
+    { $return = $item[1] }
+
+
+xxxcomment_phrase : /'.*?'|NULL/ 
     { 
         my $val = $item[1] || '';
         $val =~ s/^'|'$//g;
@@ -431,6 +474,11 @@ pg_data_type :
             };
         }
     |
+    /interval/i
+        {
+            $return = { type => 'interval' };
+        }
+    |
     /(integer|int4?)/i # interval must come before this
         { 
             $return = {
@@ -498,7 +546,12 @@ pg_data_type :
             $return = { type => 'bytea' };
         }
     |
-    /(timestamptz|timestamp)/i
+    /(timestamptz|timestamp)( with time zone)?/i
+        { 
+            $return = { type => 'timestamp' };
+        }
+    |
+    /(timestamptz|timestamp)( without time zone)?/i
         { 
             $return = { type => 'timestamp' };
         }
@@ -511,7 +564,7 @@ pg_data_type :
             };
         }
     |
-    /(bit|box|cidr|circle|date|inet|interval|line|lseg|macaddr|money|numeric|decimal|path|point|polygon|timetz|time|varchar)/i
+    /(bit|box|cidr|circle|date|inet|line|lseg|macaddr|money|numeric|decimal|path|point|polygon|timetz|time|varchar)/i
         { 
             $return = { type => $item[1] };
         }
@@ -871,7 +924,7 @@ sub parse {
 
     my $schema = $translator->schema;
     my @tables = sort { 
-        $result->{ $a }->{'order'} <=> $result->{ $b }->{'order'}
+        ( $result->{ $a }{'order'} || 0 ) <=> ( $result->{ $b }{'order'} || 0 )
     } keys %{ $result };
 
     for my $table_name ( @tables ) {
@@ -883,9 +936,9 @@ sub parse {
         $table->comments( $tdata->{'comments'} );
 
         my @fields = sort { 
-            $tdata->{'fields'}->{ $a }->{'order'} 
+            $tdata->{'fields'}{ $a }{'order'} 
             <=>
-            $tdata->{'fields'}->{ $b }->{'order'}
+            $tdata->{'fields'}{ $b }{'order'}
         } keys %{ $tdata->{'fields'} };
 
         for my $fname ( @fields ) {