Permalink
Browse files

Fix LogParser test. Work on QueryParser.

git-svn-id: http://maatkit.googlecode.com/svn/trunk@2982 dfb901c2-3250-0410-b216-0b33211c9131
  • Loading branch information...
1 parent 29d0337 commit 6b2651e53926c0c8ef829d1ca4ef16d503e828ea daniel.nichter@percona.com committed Feb 4, 2009
Showing with 79 additions and 108 deletions.
  1. +35 −81 common/QueryParser.pm
  2. +2 −2 common/t/LogParser.t
  3. +42 −25 common/t/QueryParser.t
View
116 common/QueryParser.pm
@@ -34,90 +34,45 @@ sub new {
bless {}, $class;
}
-sub get_table_ref {
+sub get_tables {
my ( $self, $query ) = @_;
return unless $query;
- my $table_ref;
-
- if ( $query =~ m/FROM\s+(.+?)\b(?:WHERE|ORDER|LIMIT|HAVING)+.+/is ) {
- $table_ref = $1;
- }
- elsif ( $query =~ m/FROM\s+(.+?);?$/is ) {
- # This handles queries like "SELECT COUNT(id) FROM table;"
- chomp($table_ref = $1);
- }
-
- MKDEBUG && _d($table_ref ? "table ref: $table_ref"
- : "Failed to parse table ref");
-
- return $table_ref;
+ my @tables = ();
+ my $callback = sub {
+ my ( $tbls ) = @_;
+ # Remove [AS] foo aliases
+ $tbls =~ s/($ident)\s+(?:as\s+\w+|\w+)/$1/gi;
+ push @tables, $tbls =~ m/($ident)/g;
+ };
+ $self->_get_table_refs($query, $callback);
+ return @tables;
}
-sub parse_table_aliases {
- my ( $self, $table_ref ) = @_;
- my $table_aliases = {};
- return $table_aliases if !defined $table_ref || !$table_ref;
- my @tables;
-
- $table_ref =~ s/\n/ /g;
- $table_ref =~ s/`//g; # Graves break database discovery
-
- if( $table_ref =~ m/ (:?straight_)?join /i ) {
- $table_ref =~ s/ join /,/ig;
- 1 while ($table_ref =~ s/ (?:inner|outer|cross|left|right|natural),/,/ig);
- $table_ref =~ s/ using\s*\(.+?\)//ig;
- $table_ref =~ s/ on \([\w\s=.,]+\),?/,/ig;
- $table_ref =~ s/ on [\w\s=.]+,?/,/ig;
- $table_ref =~ s/ straight_join /,/ig;
- }
-
- @tables = split /,/, $table_ref;
-
- my @alias_patterns = (
- qr/\s*(\S+)\s+AS\s+(\S+)\s*/i,
- qr/^\s*(\S+)\s+(\S+)\s*$/,
- qr/^\s*(\S+)+\s*$/, # Not an alias but we save it anyway to be complete
- );
-
- TABLE:
- foreach my $table ( @tables ) {
- my ( $db_tbl, $alias );
-
- # Ignore "tables" that are really subqueries.
- if ( $table =~ m/\(\s*SELECT\s+/i ) {
- MKDEBUG && _d("Ignoring subquery table: $table");
- next TABLE;
- }
-
- ALIAS_PATTERN:
- foreach my $alias_pattern ( @alias_patterns ) {
- if ( ( $db_tbl, $alias ) = $table =~ m/$alias_pattern/ ) {
- MKDEBUG && _d("$table matches $alias_pattern");
- last ALIAS_PATTERN;
- }
- }
-
- if ( defined $db_tbl && $db_tbl ) {
- my ( $db, $tbl ) = $db_tbl =~ m/^(?:(\S+)\.)?(\S+)/;
-
- $table_aliases->{$alias || $tbl} = $tbl;
- $table_aliases->{DATABASE}->{$tbl} = $db if defined $db && $db;
- }
- elsif ( MKDEBUG ) {
- _d("Failed to parse table alias for $table");
- }
- }
-
- MKDEBUG && _d('table aliases: ' . Dumper($table_aliases));
-
- return $table_aliases;
+sub get_table_aliases {
+ my ( $self, $query ) = @_;
+ return unless $query;
+ my $aliases = {};
+ my $save_alias = sub {
+ my ( $db_tbl, $alias ) = @_;
+ my ( $db, $tbl ) = $db_tbl =~ m/^(?:(\S+)\.)?(\S+)/;
+ $aliases->{$alias || $tbl} = $tbl;
+ $aliases->{DATABASE}->{$tbl} = $db if $db;
+ return 1;
+ };
+ my $callback = sub {
+ my ( $tbls ) = @_;
+ $tbls =~ s/($ident)(?:\s+(?:as\s+(\w+)|(\w+))*)*/$save_alias->($1,$2)/gie;
+ };
+ $self->_get_table_refs($query, $callback);
+ return $aliases;
}
-
+
# Returns an array of tables to which the query refers.
# XXX If you change this code, also change QueryRewriter::distill().
-sub get_tables {
- my ( $self, $query ) = @_;
- my @tables;
+sub _get_table_refs {
+ my ( $self, $query, $callback ) = @_;
+ return unless $query;
+ return unless $callback;
foreach my $tbls (
$query =~ m{
\b(?:FROM|JOIN|UPDATE|INTO) # Words that precede table names
@@ -129,11 +84,10 @@ sub get_tables {
)
}xgio)
{
- # Remove [AS] foo aliases
- $tbls =~ s/($ident)\s+(?:as\s+\w+|\w+)/$1/gi;
- push @tables, $tbls =~ m/($ident)/g;
+ MKDEBUG && _d("table ref: $tbls");
+ $callback->($tbls);
}
- return @tables;
+ return;
}
sub _d {
View
4 common/t/LogParser.t
@@ -1435,12 +1435,12 @@ my $callback1 = sub {
my ( $event ) = @_;
return 0 if $i >= 5;
$event->{foo} = ++$i;
- return 1;
+ return $event;
};
my $callback2 = sub {
my ( $event ) = @_;
push @e, $event;
- return 1;
+ return $event;
};
@e = ();
View
67 common/t/QueryParser.t
@@ -3,7 +3,7 @@
use strict;
use warnings FATAL => 'all';
-use Test::More tests => 37;
+use Test::More tests => 29;
use English qw(-no_match_vars);
require '../QueryRewriter.pm';
@@ -15,17 +15,11 @@ my $qp = new QueryParser;
isa_ok($qp, 'QueryParser');
sub test_query {
- my ( $query, $expected_ref, $expected_aliases, $tables, $msg ) = @_;
- my $tr = $qp->get_table_ref($query);
- is(
- $tr,
- $expected_ref,
- "get_table_ref: $msg"
- );
+ my ( $query, $aliases, $tables, $msg ) = @_;
is_deeply(
- $qp->parse_table_aliases($tr),
- $expected_aliases,
- "parse_table_aliases: $msg",
+ $qp->get_table_aliases($query),
+ $aliases,
+ "get_table_aliases: $msg",
);
is_deeply(
[$qp->get_tables($query)],
@@ -35,9 +29,39 @@ sub test_query {
return;
}
+my @table_refs;
+my $save_tbl_refs = sub {
+ my ( $tbl_ref ) = @_;
+ push @table_refs, $tbl_ref;
+ return;
+};
+
+@table_refs = ();
+$qp->_get_table_refs('SELECT * FROM tbl AS tbl_alias WHERE id = 1', $save_tbl_refs);
+is(
+ $table_refs[0],
+ 'tbl AS tbl_alias',
+ 'get tbl ref with one AS alias'
+);
+
+@table_refs = ();
+$qp->_get_table_refs('SELECT * FROM tbl tbl_alias WHERE id = 1', $save_tbl_refs);
+is(
+ $table_refs[0],
+ 'tbl tbl_alias',
+ 'get tbl ref with one implicit alias'
+);
+
+@table_refs = ();
+$qp->_get_table_refs('SELECT * FROM t1 AS a, t2 WHERE id = 1', $save_tbl_refs);
+is(
+ $table_refs[0],
+ 't1 AS a, t2',
+ 'get tbl ref with one AS alias and another non-aliased tbl'
+);
+
test_query(
'SELECT * FROM tbl WHERE id = 1',
- 'tbl ',
{
'tbl' => 'tbl',
},
@@ -47,7 +71,6 @@ test_query(
test_query(
'SELECT * FROM tbl1, tbl2 WHERE id = 1',
- 'tbl1, tbl2 ',
{
'tbl1' => 'tbl1',
'tbl2' => 'tbl2',
@@ -58,7 +81,6 @@ test_query(
test_query(
'SELECT * FROM tbl AS tbl_alias WHERE id = 1',
- 'tbl AS tbl_alias ',
{
'tbl_alias' => 'tbl',
},
@@ -68,7 +90,6 @@ test_query(
test_query(
'SELECT * FROM tbl tbl_alias WHERE id = 1',
- 'tbl tbl_alias ',
{
'tbl_alias' => 'tbl',
},
@@ -78,7 +99,6 @@ test_query(
test_query(
'SELECT * FROM tbl1 AS a1, tbl2 a2 WHERE id = 1',
- 'tbl1 AS a1, tbl2 a2 ',
{
'a1' => 'tbl1',
'a2' => 'tbl2',
@@ -89,7 +109,6 @@ test_query(
test_query(
'SELECT * FROM tbl1 AS a1 LEFT JOIN tbl2 as a2 ON a1.id = a2.id',
- 'tbl1 AS a1 LEFT JOIN tbl2 as a2 ON a1.id = a2.id',
{
'a1' => 'tbl1',
'a2' => 'tbl2',
@@ -100,7 +119,6 @@ test_query(
test_query(
'SELECT * FROM db.tbl1 AS a1 WHERE id = 1',
- 'db.tbl1 AS a1 ',
{
'a1' => 'tbl1',
'DATABASE' => {
@@ -113,8 +131,8 @@ test_query(
test_query(
q{SELECT a FROM store_orders_line_items JOIN store_orders},
- 'store_orders_line_items JOIN store_orders',
- { store_orders_line_items => 'store_orders_line_items',
+ {
+ store_orders_line_items => 'store_orders_line_items',
store_orders => 'store_orders',
},
[qw(store_orders_line_items store_orders)],
@@ -126,7 +144,6 @@ test_query(
# #############################################################################
test_query(
'select n.column1 = a.column1, n.word3 = a.word3 from db2.tuningdetail_21_265507 n inner join db1.gonzo a using(gonzo)',
- 'db2.tuningdetail_21_265507 n inner join db1.gonzo a using(gonzo)',
{
'n' => 'tuningdetail_21_265507',
'a' => 'gonzo',
@@ -142,7 +159,6 @@ test_query(
# #############################################################################
test_query(
'select 12_13_foo from (select 12foo from 123_bar) as 123baz',
- '(select 12foo from 123_bar) as 123baz',
{
'123_bar' => '123_bar',
},
@@ -158,8 +174,8 @@ test_query(
. q{APLTRACT_GARDENPLANT_ID = ABU.ID AND GC.MATCHING_POT = 0 AND GC.PERFORM_DIG=1}
. q{ AND ABU.DIG = 6 AND ( ((SOIL-COST) > -80.0}
. q{ AND BUGS < 60.0 AND (SOIL-COST) < 200.0) AND POTS < 10.0 )},
- 'GARDEN_CLUPL PL, GARDENJOB GC, APLTRACT_GARDENPLANT ABU ',
- { PL => 'GARDEN_CLUPL',
+ {
+ PL => 'GARDEN_CLUPL',
GC => 'GARDENJOB',
ABU => 'APLTRACT_GARDENPLANT',
},
@@ -201,7 +217,8 @@ is_deeply(
is_deeply(
[ $qp->get_tables(
- 'replace into checksum.checksum select `last_update`, `foo` from foo.foo')],
+ 'replace into checksum.checksum select `last_update`, `foo` from foo.foo')
+ ],
[qw(checksum.checksum foo.foo)],
'gets tables with reserved words');

0 comments on commit 6b2651e

Please sign in to comment.