DRILL-4486: Fix expression serialization escaping

Closes #412


Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/80316f3f
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/80316f3f
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/80316f3f

Branch: refs/heads/master
Commit: 80316f3f8bef866720f99e609fe758ec8e0c4612
Parents: 79b5e3b
Author: Steven Phillips <[email protected]>
Authored: Fri Mar 4 20:29:26 2016 -0800
Committer: Jason Altekruse <[email protected]>
Committed: Mon Mar 7 19:43:43 2016 -0800

----------------------------------------------------------------------
 .../common/expression/ExpressionStringBuilder.java     | 13 ++++++++++---
 .../drill/common/expression/parser/TreeTest.java       | 12 ++++++++++++
 2 files changed, 22 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/drill/blob/80316f3f/logical/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
----------------------------------------------------------------------
diff --git 
a/logical/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
 
b/logical/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
index c29b9b0..85547bc 100644
--- 
a/logical/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
+++ 
b/logical/src/main/java/org/apache/drill/common/expression/ExpressionStringBuilder.java
@@ -56,6 +56,13 @@ public class ExpressionStringBuilder extends 
AbstractExprVisitor<Void, StringBui
     expr.accept(INSTANCE, sb);
   }
 
+  public static String escapeSingleQuote(String input) {
+    return input.replaceAll("(['\\\\])", "\\\\$1");
+  }
+
+  public static String escapeBackTick(String input) {
+    return input.replaceAll("([`\\\\])", "\\\\$1");
+  }
 
   @Override
   public Void visitFunctionCall(FunctionCall call, StringBuilder sb) throws 
RuntimeException {
@@ -119,14 +126,14 @@ public class ExpressionStringBuilder extends 
AbstractExprVisitor<Void, StringBui
       throw new IllegalStateException("Drill doesn't currently support top 
level arrays");
     }
     sb.append('`');
-    sb.append(seg.getNameSegment().getPath());
+    sb.append(escapeBackTick(seg.getNameSegment().getPath()));
     sb.append('`');
 
     while ( (seg = seg.getChild()) != null) {
       if (seg.isNamed()) {
         sb.append('.');
         sb.append('`');
-        sb.append(seg.getNameSegment().getPath());
+        sb.append(escapeBackTick(seg.getNameSegment().getPath()));
         sb.append('`');
       } else {
         sb.append('[');
@@ -224,7 +231,7 @@ public class ExpressionStringBuilder extends 
AbstractExprVisitor<Void, StringBui
   @Override
   public Void visitQuotedStringConstant(QuotedString e, StringBuilder sb) 
throws RuntimeException {
     sb.append("'");
-    sb.append(e.value);
+    sb.append(escapeSingleQuote(e.value));
     sb.append("'");
     return null;
   }

http://git-wip-us.apache.org/repos/asf/drill/blob/80316f3f/logical/src/test/java/org/apache/drill/common/expression/parser/TreeTest.java
----------------------------------------------------------------------
diff --git 
a/logical/src/test/java/org/apache/drill/common/expression/parser/TreeTest.java 
b/logical/src/test/java/org/apache/drill/common/expression/parser/TreeTest.java
index c8f6219..fe13537 100644
--- 
a/logical/src/test/java/org/apache/drill/common/expression/parser/TreeTest.java
+++ 
b/logical/src/test/java/org/apache/drill/common/expression/parser/TreeTest.java
@@ -32,6 +32,18 @@ public class TreeTest extends DrillTest {
   private static final org.slf4j.Logger logger = 
org.slf4j.LoggerFactory.getLogger(TreeTest.class);
 
   @Test
+  public void escapeStringLiteral() throws Exception {
+    String expr = "func(`identifier`, '\\\\d+', 0, 'fjds')";
+    testExpressionParsing(expr);
+  }
+
+  @Test
+  public void escapeQuotedIdentifier() throws Exception {
+    String expr = "`a\\\\b` + `c'd`";
+    testExpressionParsing(expr);
+  }
+
+  @Test
   public void testIfWithCase() throws Exception{
     testExpressionParsing("if ($F1) then case when (_MAP.R_NAME = 'AFRICA') 
then 2 else 4 end else if(4==3) then 1 else if(x==3) then 7 else (if(2==1) then 
6 else 4 end) end");
   }

Reply via email to