Permalink
Browse files

Permit tables to be enclosed in parens (issue 781)

git-svn-id: http://maatkit.googlecode.com/svn/trunk@5443 dfb901c2-3250-0410-b216-0b33211c9131
  • Loading branch information...
1 parent 5f8c87d commit f36bab8ce745d37272ee166e58a1c17c74f712fa baron.schwartz committed Jan 9, 2010
Showing with 25 additions and 11 deletions.
  1. +11 −0 common/QueryParser.pm
  2. +0 −9 common/QueryRewriter.pm
  3. +13 −1 common/t/QueryParser.t
  4. +1 −1 common/t/QueryRewriter.t
View
@@ -31,6 +31,7 @@ our $tbl_ident = qr/(?:`[^`]+`|\w+)(?:\.(?:`[^`]+`|\w+))?/;
our $tbl_regex = qr{
\b(?:FROM|JOIN|(?<!KEY\s)UPDATE|INTO) # Words that precede table names
\b\s*
+ \(? # Optional paren around tables
# Capture the identifier and any number of comma-join identifiers that
# follow it, optionally with aliases with or without the AS keyword
($tbl_ident
@@ -111,6 +112,16 @@ sub get_tables {
my @tables;
foreach my $tbls ( $query =~ m/$tbl_regex/gio ) {
MKDEBUG && _d('Match tables:', $tbls);
+
+ # Some queries coming from certain ORM systems will have superfluous
+ # parens around table names, like SELECT * FROM (`mytable`); We match
+ # these so the table names can be extracted more simply with regexes. But
+ # in case of subqueries, this can cause us to match SELECT as a table
+ # name, for example, in SELECT * FROM (SELECT ....) AS X; It's possible
+ # that SELECT is really a table name, but so unlikely that we just skip
+ # this case.
+ next if $tbls =~ m/\ASELECT\b/i;
+
foreach my $tbl ( split(',', $tbls) ) {
# Remove implicit or explicit (AS) alias.
$tbl =~ s/\s*($tbl_ident)(\s+.*)?/$1/gio;
View
@@ -296,15 +296,6 @@ sub _distill_tables {
sub distill {
my ( $self, $query, %args ) = @_;
- # This one to take care of "FROM (`TABLE`)" like queries
- if ( $query =~ m/(FROM|^INSERT INTO|^UPDATE) \(`(.*)`\)/i ) {
- my $q_start = $`;
- my $q_end = $';
- my $matched = $&;
- $matched =~ s/(\(|\))//ig;
- $query = "$q_start$matched$q_end";
- }
-
if ( $args{generic} ) {
# Do a generic distillation which returns the first two words
# of a simple "cmd arg" query, like memcached and HTTP stuff.
View
@@ -9,7 +9,7 @@ BEGIN {
use strict;
use warnings FATAL => 'all';
-use Test::More tests => 127;
+use Test::More tests => 129;
use English qw(-no_match_vars);
use QueryRewriter;
@@ -838,6 +838,18 @@ is_deeply(
'Get tables from special case multi-line query'
);
+is_deeply(
+ [$qp->get_tables('select * from (`mytable`)')],
+ [qw(`mytable`)],
+ 'Get tables when there are parens around table name (issue 781)',
+);
+
+is_deeply(
+ [$qp->get_tables('select * from (select * from mytable) t')],
+ [qw(mytable)],
+ 'Does not consider subquery SELECT as a table (issue 781)',
+);
+
# #############################################################################
# Done.
# #############################################################################
View
@@ -1041,4 +1041,4 @@ is(
);
exit;
-
+

0 comments on commit f36bab8

Please sign in to comment.