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"); }
