Fix the binop leg of the parser to correctly consider only a single LHS node
Peter Rabbitson [Wed, 21 May 2014 08:46:16 +0000 (10:46 +0200)]
Work gracefully around malformed "no lhs" cases as well

Changes
lib/SQL/Abstract/Tree.pm
t/11parser.t
t/14roundtrippin.t

diff --git a/Changes b/Changes
index 0320ef6..4461299 100644 (file)
--- 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)
index c6faef9..d60e236 100644 (file)
@@ -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
index 3c60c95..5ce1a80 100644 (file)
@@ -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",
index 9dc581e..dba9225 100644 (file)
@@ -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