Fix for 823431: pt-query-advisor hangs on big queries

This was caused by a regex backtracking itself to a halt. The solution
was to add a positive lookahead that searches for the floating but mandatory
substrings that the regex needs; if those exist, then eventually it will
match, but if they don't, it'll fail quickly.
This commit is contained in:
Brian Fraser
2012-10-31 06:48:54 -03:00
parent 64fe380986
commit dce8db5be1
3 changed files with 28 additions and 2 deletions

View File

@@ -4490,6 +4490,7 @@ sub parse_insert {
} }
if ( my @into = ($query =~ m/ if ( my @into = ($query =~ m/
(?=VALUE|SE(?:T|LECT)) # Avoid a backtracking explosion
(?:INTO\s+)? # INTO, optional (?:INTO\s+)? # INTO, optional
(.+?)\s+ # table ref (.+?)\s+ # table ref
(\([^\)]+\)\s+)? # column list, optional (\([^\)]+\)\s+)? # column list, optional

View File

@@ -371,6 +371,7 @@ sub parse_insert {
# Parse INTO clause. Literal "INTO" is optional. # Parse INTO clause. Literal "INTO" is optional.
if ( my @into = ($query =~ m/ if ( my @into = ($query =~ m/
(?=VALUE|SE(?:T|LECT)) # Avoid a backtracking explosion
(?:INTO\s+)? # INTO, optional (?:INTO\s+)? # INTO, optional
(.+?)\s+ # table ref (.+?)\s+ # table ref
(\([^\)]+\)\s+)? # column list, optional (\([^\)]+\)\s+)? # column list, optional

View File

@@ -9,7 +9,9 @@ BEGIN {
use strict; use strict;
use warnings FATAL => 'all'; use warnings FATAL => 'all';
use English qw(-no_match_vars); use English qw(-no_match_vars);
use Test::More tests => 2; use Test::More;
use File::Spec;
use PerconaTest; use PerconaTest;
shift @INC; # These two shifts are required for tools that use base and shift @INC; # These two shifts are required for tools that use base and
@@ -39,7 +41,29 @@ like(
"Parse genlog" "Parse genlog"
); );
# #############################################################################
# pt-query-advisor hangs on big queries
# https://bugs.launchpad.net/percona-toolkit/+bug/823431
# #############################################################################
my $exit_status;
$output = output(
sub { $exit_status = pt_query_advisor::main(@args,
File::Spec->catfile($sample, "bug_823431.log"))
});
ok(
!$exit_status,
"Bug 823431: pqa doesn't hang on a big query"
);
like(
$output,
qr/COL.002/,
"Bug 823431: pqa doesn't hang on a big query and finds the correct rule"
);
# ############################################################################# # #############################################################################
# Done. # Done.
# ############################################################################# # #############################################################################
exit; done_testing;