use strict;
use warnings;
-our $VERSION = '1.59';
+our $VERSION = '1.62';
our $DEBUG;
$DEBUG = 0 unless defined $DEBUG;
set : /set/i /[^;]*/ ';'
-revoke : /revoke/i WORD(s /,/) /on/i TABLE(?) table_id /from/i name_with_opt_quotes(s /,/) ';'
+revoke : /revoke/i WORD(s /,/) /on/i TABLE(?) table_id /from/i NAME(s /,/) ';'
{
my $table_info = $item{'table_id'};
my $schema_name = $table_info->{'schema_name'};
}
}
-revoke : /revoke/i WORD(s /,/) /on/i SCHEMA(?) schema_name /from/i name_with_opt_quotes(s /,/) ';'
+revoke : /revoke/i WORD(s /,/) /on/i SCHEMA(?) schema_name /from/i NAME(s /,/) ';'
{ 1 }
-grant : /grant/i WORD(s /,/) /on/i TABLE(?) table_id /to/i name_with_opt_quotes(s /,/) ';'
+grant : /grant/i WORD(s /,/) /on/i TABLE(?) table_id /to/i NAME(s /,/) ';'
{
my $table_info = $item{'table_id'};
my $schema_name = $table_info->{'schema_name'};
}
}
-grant : /grant/i WORD(s /,/) /on/i SCHEMA(?) schema_name /to/i name_with_opt_quotes(s /,/) ';'
+grant : /grant/i WORD(s /,/) /on/i SCHEMA(?) schema_name /to/i NAME(s /,/) ';'
{ 1 }
drop : /drop/i /[^;]*/ ';'
supertype => $item{'unique'}[0] ? 'constraint' : 'index',
type => $item{'unique'}[0] ? 'unique' : 'normal',
fields => $item[9],
- method => $item{'using_method'}[0],
+ method => $item{'using_method(?)'}[0],
+ where => $item{'where_predicate(?)'}[0],
}
;
}
}
}
-trigger_name : name_with_opt_quotes
+trigger_name : NAME
trigger_scope : /FOR/i /EACH/i /(ROW|STATEMENT)/i { $return = lc $1 }
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;
- $return = $val;
- }
+ | SQSTRING
field : field_comment(s?) field_name data_type field_meta(s?) field_comment(s?)
{
}
}
-constraint_name : /constraint/i name_with_opt_quotes { $item[2] }
+constraint_name : /constraint/i NAME { $item[2] }
column_constraint_type : /not null/i { $return = { type => 'not_null' } }
|
}
}
-table_id : schema_qualification(?) name_with_opt_quotes {
+table_id : schema_qualification(?) NAME {
$return = { schema_name => $item[1][0], table_name => $item[2] }
}
-view_id : schema_qualification(?) name_with_opt_quotes {
+view_id : schema_qualification(?) NAME {
$return = { schema_name => $item[1][0], view_name => $item[2] }
}
view_target_spec :
-schema_qualification : name_with_opt_quotes '.'
-
-schema_name : name_with_opt_quotes
+schema_qualification : NAME '.'
-field_name : name_with_opt_quotes
+schema_name : NAME
-name_with_opt_quotes : double_quote(?) NAME double_quote(?) { $item[2] }
+field_name : NAME
double_quote: /"/
-index_name : name_with_opt_quotes
+index_name : NAME
+array_indicator : '[' ']'
+ { $return = $item[1].$item[2] }
-data_type : pg_data_type parens_value_list(?)
+data_type : pg_data_type parens_value_list(?) array_indicator(?)
{
my $data_type = $item[1];
+ $data_type->{type} .= $item[3][0] if $item[3][0];
+
#
# We can deduce some sizes from the data type's name.
#
- if ( my $size = $item[2][0] ) {
- $data_type->{'size'} = $size;
+ if ( my @size = @{$item[2]} ) {
+ $data_type->{'size'} = (@size == 1 ? $size[0] : \@size);
}
$return = $data_type;
$return = { type => 'bytea' };
}
|
- /(timestamptz|timestamp)(?:\(\d\))?( with(?:out)? time zone)?/i
+ / ( timestamp (?:tz)? ) (?: \( \d \) )? ( \s with (?:out)? \s time \s zone )? /ix
{
$return = { type => 'timestamp' . ($2||'') };
}
|
+ / ( time (?:tz)? ) (?: \( \d \) )? ( \s with (?:out)? \s time \s zone )? /ix
+ {
+ $return = { type => 'time' . ($2||'') };
+ }
+ |
/text/i
{
$return = {
};
}
|
- /(bit|box|cidr|circle|date|inet|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|varchar|json|hstore|uuid)/i
{
$return = { type => $item[1] };
}
{ $item[2] }
-parens_word_list : '(' name_with_opt_quotes(s /,/) ')'
+parens_word_list : '(' NAME(s /,/) ')'
{ $item[2] }
field_size : '(' num_range ')' { $item{'num_range'} }
}
}
-table_constraint_type : /primary key/i '(' name_with_opt_quotes(s /,/) ')'
+table_constraint_type : /primary key/i '(' NAME(s /,/) ')'
{
$return = {
type => 'primary_key',
}
}
|
- /unique/i '(' name_with_opt_quotes(s /,/) ')'
+ /unique/i '(' NAME(s /,/) ')'
{
$return = {
type => 'unique',
}
}
|
- /foreign key/i '(' name_with_opt_quotes(s /,/) ')' /references/i table_id parens_word_list(?) match_type(?) key_action(s?)
+ /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] || [] } ) {
create_index : CREATE /index/i
-default_val : DEFAULT /(\d+|'[^']*'|\w+\(.*\))|\w+/ ( '::' data_type )(?)
+default_val : DEFAULT DEFAULT_VALUE ( '::' data_type )(?)
{
- my $val = defined $item[2] ? $item[2] : '';
- $val =~ s/^'|'$//g;
+ my $val = $item[2];
+ $val =~ s/^\((\d+)\)\z/$1/; # for example (0)::smallint
$return = {
supertype => 'constraint',
type => 'default',
}
}
+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] }
key : /key/i | /index/i
-table_option : /inherits/i '(' name_with_opt_quotes(s /,/) ')'
+table_option : /inherits/i '(' NAME(s /,/) ')'
{
$return = { type => 'inherits', table_name => $item[3] }
}
SET : /set/i
-NAME : "`" /\w+/ "`"
- { $item[2] }
+NAME : DQSTRING
| /\w+/
- { $item[1] }
- | /[\$\w]+/
- { $item[1] }
-
-VALUE : /[-+]?\.?\d+(?:[eE]\d+)?/
- { $item[1] }
- | /'.*?'/ # XXX doesn't handle embedded quotes
- { $item[1] }
+
+DQSTRING : '"' <skip: ''> /((?:[^"]|"")+)/ '"'
+ { ($return = $item[3]) =~ s/""/"/g; }
+
+SQSTRING : "'" <skip: ''> /((?:[^']|'')*)/ "'"
+ { ($return = $item[3]) =~ s/''/'/g }
+
+DOLLARSTRING : /\$[^\$]*\$/ <skip: ''> /.*?(?=\Q$item[1]\E)/s "$item[1]"
+ { $return = $item[3]; }
+
+VALUE : /[-+]?\d*\.?\d+(?:[eE]\d+)?/
+ | SQSTRING
+ | DOLLARSTRING
| /null/i
{ 'NULL' }
}
for my $idata ( @{ $tdata->{'indices'} || [] } ) {
+ my @options = ();
+ push @options, { using => $idata->{'method'} } if $idata->{method};
+ push @options, { where => $idata->{'where'} } if $idata->{where};
my $index = $table->add_index(
- name => $idata->{'name'},
- type => uc $idata->{'type'},
- fields => $idata->{'fields'},
+ name => $idata->{'name'},
+ type => uc $idata->{'type'},
+ fields => $idata->{'fields'},
+ options => \@options
) or die $table->error . ' ' . $table->name;
}