From: Peter Rabbitson Date: Tue, 4 Jun 2013 16:08:25 +0000 (+0200) Subject: Change parser to not eagerly slurp RHS expressions it doesn't recognize X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=6f30911f8a77b8f2b466f9ecaa9d6d5c2b788c3a;p=scpubgit%2FQ-Branch.git Change parser to not eagerly slurp RHS expressions it doesn't recognize --- diff --git a/Changes b/Changes index ca58b59..c178f5b 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,7 @@ Revision history for SQL::Abstract - Fix insufficient parenthesis unroll during operator comparison - 'ORDER BY foo' and 'ORDER BY foo ASC' are now considered equal by default (with a switch to reenable old behavior when necessary) + - Change parser to not eagerly slurp RHS expressions it doesn't recognize revision 1.73 2012-07-10 ---------------------------- diff --git a/lib/SQL/Abstract/Tree.pm b/lib/SQL/Abstract/Tree.pm index 8e743a6..c3e1555 100644 --- a/lib/SQL/Abstract/Tree.pm +++ b/lib/SQL/Abstract/Tree.pm @@ -447,13 +447,16 @@ sub _recurse_parse { } # we're now in "unknown token" land - start eating tokens until - # we see something familiar + # we see something familiar, OR in the case of RHS (binop) stop + # after the first token else { my @lits = [ -LITERAL => [$token] ]; - while (@$tokens and $tokens->[0] !~ $all_std_keywords_re) { - push @lits, [ -LITERAL => [ shift @$tokens ] ]; - } + unless ( $state == PARSE_RHS ) { + while (@$tokens and $tokens->[0] !~ $all_std_keywords_re) { + push @lits, [ -LITERAL => [ shift @$tokens ] ]; + } + } if (@left == 1) { unshift @lits, pop @left; @@ -465,10 +468,13 @@ sub _recurse_parse { } if (@$tokens) { - # asc/desc + + # deal with post-fix operators (asc/desc) if ($tokens->[0] =~ $asc_desc_re) { @left = [ ('-' . uc (shift @$tokens)) => [ @left ] ]; } + + return @left if $state == PARSE_RHS and $left[-1][0] eq '-LITERAL'; } } } diff --git a/t/11parser.t b/t/11parser.t index 202e5fa..8e1ee05 100644 --- a/t/11parser.t +++ b/t/11parser.t @@ -800,8 +800,13 @@ is_deeply($sqlat->parse('SELECT foo FROM bar ORDER BY x + ? DESC, oomph, y - ? D ] ], 'Crazy ORDER BY parsed correctly'); - -is_deeply($sqlat->parse("SELECT * * FROM (SELECT *, FROM foobar baz buzz) foo bar WHERE NOT NOT NOT EXISTS (SELECT 'cr,ap') AND foo.a = ? and not (foo.b LIKE 'station') and x = y and a = b and GROUP BY , ORDER BY x x1 x2 y asc, max(y) desc x z desc"), [ +is_deeply( $sqlat->parse("META SELECT * * FROM (SELECT *, FROM foobar baz buzz) foo bar WHERE NOT NOT NOT EXISTS (SELECT 'cr,ap') AND foo.a = ? STUFF and not (foo.b LIKE 'station') and x = y and a = b and GROUP BY , ORDER BY x x1 x2 y asc, max(y) desc x z desc"), [ + [ + "-LITERAL", + [ + "META" + ] + ], [ "SELECT", [ @@ -952,10 +957,21 @@ is_deeply($sqlat->parse("SELECT * * FROM (SELECT *, FROM foobar baz buzz) foo ba ] ], [ - "-PLACEHOLDER", + "-MISC", [ - "?" - ] + [ + "-PLACEHOLDER", + [ + "?" + ] + ], + [ + "-LITERAL", + [ + "STUFF" + ] + ] + ], ] ] ], @@ -1086,25 +1102,30 @@ is_deeply($sqlat->parse("SELECT * * FROM (SELECT *, FROM foobar baz buzz) foo ba "-MISC", [ [ - "-DESC", + "-MISC", [ [ - "-PAREN", + "-DESC", [ [ - "-LITERAL", + "-PAREN", [ - "y" + [ + "-LITERAL", + [ + "y" + ] + ] ] ] ] - ] - ] - ], - [ - "-LITERAL", - [ - "x" + ], + [ + "-LITERAL", + [ + "x" + ] + ], ] ], [