=cut
use strict;
+use warnings;
-use vars qw[ $DEBUG $VERSION $GRAMMAR @EXPORT_OK ];
-$VERSION = '1.59';
+our $VERSION = '1.59';
+
+our $DEBUG;
$DEBUG = 0 unless defined $DEBUG;
use Data::Dumper;
-use Parse::RecDescent;
-use Exporter;
-use base qw(Exporter);
-
-@EXPORT_OK = qw(parse);
+use SQL::Translator::Utils qw/ddl_parser_instance/;
-$::RD_ERRORS = 1;
-$::RD_WARN = 1;
-$::RD_HINT = 1;
+use base qw(Exporter);
+our @EXPORT_OK = qw(parse);
-$GRAMMAR = q{
+our $GRAMMAR = <<'END_OF_GRAMMAR';
{
my ( %tables, @table_comments, $table_order, %procedures, $proc_order, %views, $view_order );
| exec
| /^\Z/ | { _err ($thisline, $text) }
-use : /use/i WORD GO
+use : /use/i NAME GO
{ @table_comments = () }
-setuser : /setuser/i NAME GO
+setuser : /setuser/i USERNAME GO
if : /if/i object_not_null begin if_command end GO
| create_index
| create_constraint
-object_not_null : /object_id/i '(' ident ')' /is not null/i
+object_not_null : /object_id/i '(' SQSTRING ')' /is not null/i
field_not_null : /where/i field_name /is \s+ not \s+ null/ix
disable_constraints : if_exists(?) /alter/i /table/i ident /nocheck/i /constraint/i /all/i END_STATEMENT
-# this is for the normal case
+# this is for the normal case
create_constraint : /create/i constraint END_STATEMENT
{
@table_comments = ();
| foreign_key_constraint
| unique_constraint
-field_name : WORD
- { $return = $item[1] }
- | LQUOTE WORD RQUOTE
- { $return = $item[2] }
+field_name : NAME
-index_name : WORD
- { $return = $item[1] }
- | LQUOTE WORD RQUOTE
- { $return = $item[2] }
+index_name : NAME
-table_name : WORD
- { $return = $item[1] }
- | LQUOTE WORD RQUOTE
- { $return = $item[2] }
+table_name : NAME
data_type : WORD field_size(?)
{
default_val : /default/i /null/i
{ $return = 'null' }
- | /default/i /'[^']*'/
- { $item[2]=~ s/'//g; $return = $item[2] }
+ | /default/i SQSTRING
+ { $return = $item[2] }
| /default/i WORD
{ $return = $item[2] }
parens_field_list : '(' field_name(s /,/) ')'
{ $item[2] }
-ident : QUOTE WORD '.' WORD QUOTE | LQUOTE WORD '.' WORD RQUOTE
- { $return = { owner => $item[2], name => $item[4] } }
- | LQUOTE WORD RQUOTE '.' LQUOTE WORD RQUOTE
- { $return = { owner => $item[2], name => $item[6] } }
- | LQUOTE WORD RQUOTE
- { $return = { name => $item[2] } }
- | WORD '.' WORD
+ident : NAME '.' NAME
{ $return = { owner => $item[1], name => $item[3] } }
- | WORD
+ | NAME
{ $return = { name => $item[1] } }
END_STATEMENT : ';'
GO : /^go/i
-NAME : QUOTE(?) /\w+/ QUOTE(?)
- { $item[2] }
+USERNAME : WORD
+ | SQSTRING
+
+NAME : WORD
+ | DQSTRING
+ | BQSTRING
WORD : /[\w#]+/
COMMA : ','
-QUOTE : /'/
+SQSTRING : "'" /(?:[^']|'')*/ "'"
+ { ($return = $item[2]) =~ s/''/'/g }
-LQUOTE : '['
+DQSTRING : '"' /(?:[^"]|"")+/ '"'
+ { ($return = $item[2]) =~ s/""/"/g }
-RQUOTE : ']'
+BQSTRING : '[' /(?:[^]]|]])+/ ']'
+ { ($return = $item[2]) =~ s/]]/]/g; }
-};
+END_OF_GRAMMAR
sub parse {
my ( $translator, $data ) = @_;
- my $parser = Parse::RecDescent->new($GRAMMAR);
+
+ # Enable warnings within the Parse::RecDescent module.
+ local $::RD_ERRORS = 1 unless defined $::RD_ERRORS; # Make sure the parser dies when it encounters an error
+ local $::RD_WARN = 1 unless defined $::RD_WARN; # Enable warnings. This will warn on unused rules &c.
+ local $::RD_HINT = 1 unless defined $::RD_HINT; # Give out hints to help fix problems.
local $::RD_TRACE = $translator->trace ? 1 : undef;
local $DEBUG = $translator->debug;
- unless (defined $parser) {
- return $translator->error("Error instantiating Parse::RecDescent ".
- "instance: Bad grammer");
- }
+ my $parser = ddl_parser_instance('SQLServer');
my $result = $parser->startrule($data);
return $translator->error( "Parse failed." ) unless defined $result;