diff --git a/lib/TableParser.pm b/lib/TableParser.pm index 994d1e6b..37834f38 100644 --- a/lib/TableParser.pm +++ b/lib/TableParser.pm @@ -129,9 +129,15 @@ sub parse { my ( $self, $ddl, $opts ) = @_; return unless $ddl; - if ( $ddl !~ m/CREATE (?:TEMPORARY )?TABLE `/ ) { - die "Cannot parse table definition; is ANSI quoting " - . "enabled or SQL_QUOTE_SHOW_CREATE disabled?"; + # If ANSI_QUOTES is enabled, we can't parse. But we can translate ANSI_QUOTES + # into legacy quoting with backticks. The rules are: an identifier is + # surrounded with the quote characters, and embedded quote characters are + # doubled. + if ( $ddl =~ m/CREATE (?:TEMPORARY )?TABLE "/ ) { + $ddl = $self->ansi_to_legacy($ddl); + } + elsif ( $ddl !~ m/CREATE (?:TEMPORARY )?TABLE `/ ) { + die "TableParser doesn't handle CREATE TABLE without quoting."; } my ($name) = $ddl =~ m/CREATE (?:TEMPORARY )?TABLE\s+(`.+?`)/; @@ -535,6 +541,28 @@ sub get_table_status { return @tables; } +# Translates ANSI quoting around SHOW CREATE TABLE (specifically this query's +# output, not an arbitrary query) into legacy backtick-quoting. +# DOESNT WORK: my $ansi_quote_re = qr/"(?:(?!(?get_create_table($dbh, 'sakila', 'actor'); + if ( $ddl =~ m/TABLE "actor"/ ) { # It's ANSI quoting, compensate + $ddl = $tp->ansi_to_legacy($ddl); + $ddl = "$ddl ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8"; + } ok( no_diff( "$ddl\n", @@ -54,7 +58,7 @@ SKIP: { $ddl = $tp->get_create_table($dbh, qw(test t)); like( $ddl, - qr/`a b`\s+/, + qr/[`"]a b[`"]\s+/, "Does not compress spaces (bug 932442)" ); }; @@ -64,11 +68,6 @@ eval { }; like($EVAL_ERROR, qr/quoting/, 'No quoting'); -eval { - $tp->parse( load_file('t/lib/samples/ansi_quotes.sql') ); -}; -like($EVAL_ERROR, qr/quoting/, 'ANSI quoting'); - $tbl = $tp->parse( load_file('t/lib/samples/t1.sql') ); is_deeply( $tbl, @@ -146,6 +145,21 @@ is_deeply( 'Indexes with prefixes parse OK (fixes issue 1)' ); +is( + $tp->ansi_to_legacy( load_file('t/lib/samples/ansi.quoting.sql') ), + q{CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL, + `b``c` int(11) DEFAULT NULL, + `d"e` int(11) DEFAULT NULL, + `f +g` int(11) DEFAULT NULL, + `h\` int(11) DEFAULT NULL, + `i\"` int(11) DEFAULT NULL +) +}, + 'ANSI quotes (with all kinds of dumb things) get translated correctly' +); + $tbl = $tp->parse( load_file('t/lib/samples/sakila.film.sql') ); is_deeply( $tbl, diff --git a/t/lib/samples/ansi.quoting.sql b/t/lib/samples/ansi.quoting.sql new file mode 100644 index 00000000..b94e3316 --- /dev/null +++ b/t/lib/samples/ansi.quoting.sql @@ -0,0 +1,9 @@ +CREATE TABLE "t" ( + "a" int(11) DEFAULT NULL, + "b`c" int(11) DEFAULT NULL, + "d""e" int(11) DEFAULT NULL, + "f +g" int(11) DEFAULT NULL, + "h\" int(11) DEFAULT NULL, + "i\""" int(11) DEFAULT NULL +)