Selaa lähdekoodia

HUE-1332 [beeswax] Smarter escaping of semicolon

Simple algorithm, not the most elegant implementation
Romain Rigaux 12 vuotta sitten
vanhempi
commit
3dfb2c7
2 muutettua tiedostoa jossa 41 lisäystä ja 1 poistoa
  1. 30 1
      apps/beeswax/src/beeswax/design.py
  2. 11 0
      apps/beeswax/src/beeswax/tests.py

+ 30 - 1
apps/beeswax/src/beeswax/design.py

@@ -168,7 +168,36 @@ class HQLdesign(object):
   @property
   def statements(self):
     hql_query = _strip_trailing_semicolon(self.hql_query)
-    return [statement.strip() for statement in hql_query.split(';')]
+    return [_strip_trailing_semicolon(statement.strip()) for statement in split_statements(hql_query)]
+
+
+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.
+  """
+  statements = []
+  current = ''
+  prev = ''
+  between_quotes = None
+
+  for c in hql:
+    current += c
+    if c in ('"', "'") and prev != '\\':
+      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 = ''
+    prev = c
+
+  if current and current != ';':
+    statements.append(current)
+
+  return statements
 
 
 def normalize_form_dict(form, attr_list):

+ 11 - 0
apps/beeswax/src/beeswax/tests.py

@@ -1507,6 +1507,17 @@ def test_search_log_line():
   assert_false(search_log_line('ql.Driver', 'FAILED: Parse Error', logs))
 
 
+def test_split_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)
+  assert_equal(['select', "select * where id == '\"10;\"\"\"' limit 100"], hql_query("select; select * where id == '\"10;\"\"\"' limit 100;").statements)
+
+
+
 class MockDbms:
 
   def __init__(self, client, server_type):