Ver código fonte

HUE-2224 [beeswax] Query editor does not properly split statements

Ashu Pachauri 11 anos atrás
pai
commit
adf679f
2 arquivos alterados com 44 adições e 15 exclusões
  1. 34 14
      apps/beeswax/src/beeswax/design.py
  2. 10 1
      apps/beeswax/src/beeswax/tests.py

+ 34 - 14
apps/beeswax/src/beeswax/design.py

@@ -21,6 +21,7 @@ The HQLdesign class can (de)serialize a design to/from a QueryDict.
 
 import json
 import logging
+import os
 import re
 import urlparse
 
@@ -184,26 +185,45 @@ class HQLdesign(object):
 
 def split_statements(hql):
   """
-  Just check if the semicolon is between two non escaped quotes,
-  meaning it is inside a string or a real separator.
+  Split statments at semicolons ignoring the ones inside
+  quotes and comments. The comment symbols that come
+  inside quotes should be ignored.
   """
+
   statements = []
   current = ''
+  prev = ''
   between_quotes = None
-
-  for c in hql:
-    current += c
-    if c in ('"', "'"):
-      if between_quotes == c:
-        between_quotes = None
-      elif between_quotes is None:
-        between_quotes = c
-    elif c == ';':
-      if between_quotes is None:
-        statements.append(current)
-        current = ''
+  is_comment = None
+
+  lines = hql.splitlines()
+
+  for line in lines:
+    for c in line:
+      current += c
+      if c in ('"', "'") and is_comment is None:
+        if between_quotes == c:
+          between_quotes = None
+        elif between_quotes is None:
+          between_quotes = c
+      elif c == '-' and prev == '-' and between_quotes is None and is_comment is None:
+        is_comment = True
+      elif c == ';':
+        if between_quotes is None and is_comment is None:
+          current = current.strip()
+          # Strip off the trailing semicolon
+          current = current[:-1]
+          if len(current) > 1:
+            statements.append(current)
+          current = ''
+      prev = c
+    is_comment = None
+    prev = os.linesep
+    if current != '':
+      current += os.linesep
 
   if current and current != ';':
+    current = current.strip()
     statements.append(current)
 
   return statements

+ 10 - 1
apps/beeswax/src/beeswax/tests.py

@@ -1732,12 +1732,21 @@ def test_search_log_line():
 
 
 def test_split_statements():
-  assert_equal([''], hql_query(";;;").statements)
+  assert_equal([], hql_query(";;;").statements)
   assert_equal(["select * where id == '10'"], hql_query("select * where id == '10'").statements)
   assert_equal(["select * where id == '10'"], hql_query("select * where id == '10';").statements)
   assert_equal(['select', "select * where id == '10;' limit 100"], hql_query("select; select * where id == '10;' limit 100;").statements)
   assert_equal(['select', "select * where id == \"10;\" limit 100"], hql_query("select; select * where id == \"10;\" limit 100;").statements)
   assert_equal(['select', "select * where id == '\"10;\"\"\"' limit 100"], hql_query("select; select * where id == '\"10;\"\"\"' limit 100;").statements)
+
+  query_with_comments = """--First query;
+select concat('--', name)  -- The '--' in quotes is not a comment
+where id = '10';
+-- Second query
+select * where id = '10';"""
+  assert_equal(["--First query;\nselect concat(\'--\', name)  -- The \'--\' in quotes is not a comment\nwhere id = \'10\'",
+"-- Second query\nselect * where id = \'10\'"], hql_query(query_with_comments).statements)
+
   query = """CREATE DATABASE IF NOT EXISTS functional;
 DROP TABLE IF EXISTS functional.alltypes;
 CREATE EXTERNAL TABLE IF NOT EXISTS functional.alltypes (