SQL-Translator

 view release on metacpan or  search on metacpan

lib/SQL/Translator/Parser/PostgreSQL.pm  view on Meta::CPAN

            expression => $item{__PATTERN2__},
            using      => $item{'using_method(?)'}[0],
            include    => $item{'include_convering(?)'}[0],
            where      => $item{'where_paren_predicate(?)'}[0],
        }
    }
    |
    /foreign key/i '(' NAME(s /,/) ')' /references/i table_id parens_word_list(?) match_type(?) key_action(s?)
    {
        my ( $on_delete, $on_update );
        for my $action ( @{ $item[9] || [] } ) {
            $on_delete = $action->{'action'} if $action->{'type'} eq 'delete';
            $on_update = $action->{'action'} if $action->{'type'} eq 'update';
        }

        $return              =  {
            supertype        => 'constraint',
            type             => 'foreign_key',
            fields           => $item[3],
            reference_table  => $item[6]->{'table_name'},
            reference_fields => $item[7][0],
            match_type       => $item[8][0],
            on_delete     => $on_delete || '',
            on_update     => $on_update || '',
        }
    }

deferrable : not(?) /deferrable/i
    {
        $return = ( $item[1] =~ /not/i ) ? 0 : 1;
    }

deferred : /initially/i /(deferred|immediate)/i { $item[2] }

match_type : /match/i /partial|full|simple/i { $item[2] }

key_action : key_delete
    |
    key_update

key_delete : /on delete/i key_mutation
    {
        $return = {
            type   => 'delete',
            action => $item[2],
        };
    }

key_update : /on update/i key_mutation
    {
        $return = {
            type   => 'update',
            action => $item[2],
        };
    }

key_mutation : /no action/i { $return = 'no_action' }
    |
    /restrict/i { $return = 'restrict' }
    |
    /cascade/i { $return = 'cascade' }
    |
    /set null/i { $return = 'set null' }
    |
    /set default/i { $return = 'set default' }

alter : alter_table table_id add_column field ';'
    {
        my $field_def = $item[4];
        $tables{ $item[2]->{'table_name'} }{'fields'}{ $field_def->{'name'} } = {
            %$field_def, order => $field_order++
        };
        1;
    }

alter : alter_table table_id ADD table_constraint ';'
    {
        my $table_name = $item[2]->{'table_name'};
        my $constraint = $item[4];
        push @{ $tables{ $table_name }{'constraints'} }, $constraint;
        1;
    }

alter : alter_table table_id drop_column NAME restrict_or_cascade(?) ';'
    {
        $tables{ $item[2]->{'table_name'} }{'fields'}{ $item[4] }{'drop'} = 1;
        1;
    }

alter : alter_table table_id alter_column NAME alter_default_val ';'
    {
        $tables{ $item[2]->{'table_name'} }{'fields'}{ $item[4] }{'default'} =
            $item[5]->{'value'};
        1;
    }

#
# These will just parse for now but won't affect the structure. - ky
#
alter : alter_table table_id /rename/i /to/i NAME ';'
    { 1 }

alter : alter_table table_id alter_column NAME SET /statistics/i INTEGER ';'
    { 1 }

alter : alter_table table_id alter_column NAME SET /storage/i storage_type ';'
    { 1 }

alter : alter_table table_id rename_column NAME /to/i NAME ';'
    { 1 }

alter : alter_table table_id DROP /constraint/i NAME restrict_or_cascade ';'
    { 1 }

alter : alter_table table_id /owner/i /to/i NAME ';'
    { 1 }

alter : alter_sequence NAME /owned/i /by/i column_name ';'
    { 1 }

storage_type : /(plain|external|extended|main)/i

temporary : /temp(orary)?\b/i
  {
    1;
  }

or_replace : /or replace/i

alter_default_val : SET default_val
    {
        $return = { value => $item[2]->{'value'} }
    }
    | DROP DEFAULT
    {
        $return = { value => undef }
    }

#
# This is a little tricky to get right, at least WRT to making the
# tests pass.  The problem is that the constraints are stored just as
# a list (no name access), and the tests expect the constraints in a
# particular order.  I'm going to leave the rule but disable the code
# for now. - ky
#
alter : alter_table table_id alter_column NAME alter_nullable ';'
    {
#        my $table_name  = $item[2]->{'table_name'};
#        my $field_name  = $item[4];
#        my $is_nullable = $item[5]->{'is_nullable'};
#
#        $tables{ $table_name }{'fields'}{ $field_name }{'is_nullable'} =
#            $is_nullable;
#
#        if ( $is_nullable ) {
#            1;
#            push @{ $tables{ $table_name }{'constraints'} }, {
#                type   => 'not_null',
#                fields => [ $field_name ],
#            };
#        }
#        else {
#            for my $i (
#                0 .. $#{ $tables{ $table_name }{'constraints'} || [] }
#            ) {
#                my $c = $tables{ $table_name }{'constraints'}[ $i ] or next;
#                my $fields = join( '', @{ $c->{'fields'} || [] } ) or next;
#                if ( $c->{'type'} eq 'not_null' && $fields eq $field_name ) {
#                    delete $tables{ $table_name }{'constraints'}[ $i ];
#                    last;
#                }
#            }
#        }

        1;
    }

alter_nullable : SET not_null
    {
        $return = { is_nullable => 0 }
    }
    | DROP not_null
    {
        $return = { is_nullable => 1 }
    }

not_null : /not/i /null/i

not : /not/i

add_column : ADD COLUMN(?)

alter_table : ALTER TABLE ONLY(?)

alter_sequence : ALTER SEQUENCE

drop_column : DROP COLUMN(?)

alter_column : ALTER COLUMN(?)

rename_column : /rename/i COLUMN(?)

restrict_or_cascade : /restrict/i |
    /cascade/i

# Handle functions that can be called
select : SELECT select_function ';'
    { 1 }

# Read the setval function but don't do anything with it because this parser
# isn't handling sequences
select_function : schema_qualification(?) /setval/i '(' VALUE /,/ VALUE /,/ /(true|false)/i ')'
    { 1 }

# Skipping all COPY commands
copy : COPY WORD /[^;]+/ ';' { 1 }
    { 1 }

# The "\." allows reading in from STDIN but this isn't needed for schema
# creation, so it is skipped.
readin_symbol : '\.'
    {1}

#
# End basically useless stuff. - ky
#

create_table : CREATE TABLE

create_index : CREATE /index/i

default_val  : DEFAULT DEFAULT_VALUE ( '::' data_type )(?)
    {
        my $val =  $item[2];
        $val =~ s/^\((\d+)\)\z/$1/; # for example (0)::smallint
        $return =  {
            supertype => 'constraint',
            type      => 'default',
            value     => $val,
        }
    }
    | /null/i
    {
        $return =  {
            supertype => 'constraint',
            type      => 'default',
            value     => 'NULL',
        }
    }

DEFAULT_VALUE : VALUE
    | /\w+\(.*\)/
    | /\w+/
    | /\(\d+\)/

name_with_opt_paren : NAME parens_value_list(s?)
    { $item[2][0] ? "$item[1]($item[2][0][0])" : $item[1] }

unique : /unique/i { 1 }

key : /key/i | /index/i

table_option : /inherits/i '(' NAME(s /,/) ')'
    {



( run in 0.603 second using v1.01-cache-2.11-cpan-97f6503c9c8 )