From: Peter Rabbitson Date: Wed, 21 May 2014 08:46:16 +0000 (+0200) Subject: Fix the binop leg of the parser to correctly consider only a single LHS node X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=08e1636016045f0f3881f5af287dcfd482845fe9;p=scpubgit%2FQ-Branch.git Fix the binop leg of the parser to correctly consider only a single LHS node Work gracefully around malformed "no lhs" cases as well --- diff --git a/Changes b/Changes index 0320ef6..4461299 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,8 @@ Revision history for SQL::Abstract + - Fix parsing of binary ops to correctly take up only a single LHS + element, instead of gobbling up the entire parse-to-date + revision 1.77 2014-01-17 ---------------------------- - Reintroduce { -not => undef } column operator (regression from 1.75) diff --git a/lib/SQL/Abstract/Tree.pm b/lib/SQL/Abstract/Tree.pm index c6faef9..d60e236 100644 --- a/lib/SQL/Abstract/Tree.pm +++ b/lib/SQL/Abstract/Tree.pm @@ -419,7 +419,7 @@ sub _recurse_parse { @right = $self->_recurse_parse($tokens, PARSE_IN_EXPR); } - @left = [$op => [ @left, @right ]]; + push @left, [$op => [ (@left ? pop @left : ''), @right ]]; } # unary op keywords diff --git a/t/11parser.t b/t/11parser.t index 3c60c95..5ce1a80 100644 --- a/t/11parser.t +++ b/t/11parser.t @@ -533,6 +533,50 @@ is_deeply($sqlat->parse( "SELECT [screen].[id], [screen].[name], [screen].[secti ] ], 'real life statement 1 parsed correctly'); +is_deeply($sqlat->parse("CASE WHEN FOO() > BAR()"), [ + [ + "-MISC", + [ + [ + "-LITERAL", + [ + "CASE" + ] + ], + [ + "-LITERAL", + [ + "WHEN" + ] + ] + ] + ], + [ + ">", + [ + [ + "FOO", + [ + [ + "-PAREN", + [] + ] + ] + ], + [ + "BAR", + [ + [ + "-PAREN", + [] + ] + ] + ] + ] + ] +]); + + is_deeply($sqlat->parse("SELECT x, y FROM foo WHERE x IN (?, ?, ?, ?)"), [ [ "SELECT", diff --git a/t/14roundtrippin.t b/t/14roundtrippin.t index 9dc581e..dba9225 100644 --- a/t/14roundtrippin.t +++ b/t/14roundtrippin.t @@ -26,6 +26,8 @@ my @sql = ( "SELECT * FROM foo WHERE foo.a @@ to_tsquery('word')", "SELECT * FROM foo ORDER BY name + ?, [me].[id]", "SELECT foo AS bar FROM baz ORDER BY x + ? DESC, baz.g", + # deliberate batshit insanity + "SELECT foo FROM bar WHERE > 12", ); # FIXME FIXME FIXME