You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by sp...@apache.org on 2017/03/23 17:41:04 UTC
hive git commit: HIVE-14606: Beeline fails if quoted string ends with
\\ (Sahil Takiar, reviewed by Sergio Pena)
Repository: hive
Updated Branches:
refs/heads/master 60795505b -> 4812486a1
HIVE-14606: Beeline fails if quoted string ends with \\ (Sahil Takiar, reviewed by Sergio Pena)
Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/4812486a
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/4812486a
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/4812486a
Branch: refs/heads/master
Commit: 4812486a13a73002f94b69d02e25ca076a7ac157
Parents: 6079550
Author: Sahil Takiar <ta...@gmail.com>
Authored: Thu Mar 23 12:40:31 2017 -0500
Committer: Sergio Pena <se...@cloudera.com>
Committed: Thu Mar 23 12:40:58 2017 -0500
----------------------------------------------------------------------
.../java/org/apache/hive/beeline/Commands.java | 31 +++++++++++++++-----
.../hive/beeline/TestBeeLineWithArgs.java | 13 ++++++++
2 files changed, 36 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hive/blob/4812486a/beeline/src/java/org/apache/hive/beeline/Commands.java
----------------------------------------------------------------------
diff --git a/beeline/src/java/org/apache/hive/beeline/Commands.java b/beeline/src/java/org/apache/hive/beeline/Commands.java
index 99ee82c..2578728 100644
--- a/beeline/src/java/org/apache/hive/beeline/Commands.java
+++ b/beeline/src/java/org/apache/hive/beeline/Commands.java
@@ -1221,46 +1221,61 @@ public class Commands {
if (entireLineAsCommand) {
cmdList.add(line);
} else {
- StringBuffer command = new StringBuffer();
+ StringBuilder command = new StringBuilder();
+ // Marker to track if there is starting double quote without an ending double quote
boolean hasUnterminatedDoubleQuote = false;
- boolean hasUntermindatedSingleQuote = false;
+ // Marker to track if there is starting single quote without an ending double quote
+ boolean hasUnterminatedSingleQuote = false;
+
+ // Index of the last seen semicolon in the given line
int lastSemiColonIndex = 0;
char[] lineChars = line.toCharArray();
+ // Marker to track if the previous character was an escape character
boolean wasPrevEscape = false;
+
int index = 0;
+
+ // Iterate through the line and invoke the addCmdPart method whenever a semicolon is seen that is not inside a
+ // quoted string
for (; index < lineChars.length; index++) {
switch (lineChars[index]) {
case '\'':
+ // If a single quote is seen and the index is not inside a double quoted string and the previous character
+ // was not an escape, then update the hasUnterminatedSingleQuote flag
if (!hasUnterminatedDoubleQuote && !wasPrevEscape) {
- hasUntermindatedSingleQuote = !hasUntermindatedSingleQuote;
+ hasUnterminatedSingleQuote = !hasUnterminatedSingleQuote;
}
wasPrevEscape = false;
break;
case '\"':
- if (!hasUntermindatedSingleQuote && !wasPrevEscape) {
+ // If a double quote is seen and the index is not inside a single quoted string and the previous character
+ // was not an escape, then update the hasUnterminatedDoubleQuote flag
+ if (!hasUnterminatedSingleQuote && !wasPrevEscape) {
hasUnterminatedDoubleQuote = !hasUnterminatedDoubleQuote;
}
wasPrevEscape = false;
break;
case ';':
- if (!hasUnterminatedDoubleQuote && !hasUntermindatedSingleQuote) {
+ // If a semicolon is seen, and the line isn't inside a quoted string, then treat
+ // line[lastSemiColonIndex] to line[index] as a single command
+ if (!hasUnterminatedDoubleQuote && !hasUnterminatedSingleQuote) {
addCmdPart(cmdList, command, line.substring(lastSemiColonIndex, index));
lastSemiColonIndex = index + 1;
}
wasPrevEscape = false;
break;
case '\\':
- wasPrevEscape = true;
+ wasPrevEscape = !wasPrevEscape;
break;
default:
wasPrevEscape = false;
break;
}
}
- // if the line doesn't end with a ; or if the line is empty, add the cmd part
+ // If the line doesn't end with a ; or if the line is empty, add the cmd part
if (lastSemiColonIndex != index || lineChars.length == 0) {
addCmdPart(cmdList, command, line.substring(lastSemiColonIndex, index));
}
@@ -1272,7 +1287,7 @@ public class Commands {
* Given a cmdpart (e.g. if a command spans multiple lines), add to the current command, and if
* applicable add that command to the {@link List} of commands
*/
- private void addCmdPart(List<String> cmdList, StringBuffer command, String cmdpart) {
+ private void addCmdPart(List<String> cmdList, StringBuilder command, String cmdpart) {
if (cmdpart.endsWith("\\")) {
command.append(cmdpart.substring(0, cmdpart.length() - 1)).append(";");
return;
http://git-wip-us.apache.org/repos/asf/hive/blob/4812486a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java
----------------------------------------------------------------------
diff --git a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java
index 650c4b7..75f46ec 100644
--- a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java
+++ b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java
@@ -1069,4 +1069,17 @@ public class TestBeeLineWithArgs {
this.shouldMatch = shouldMatch;
}
}
+
+ /**
+ * Test that Beeline can handle \\ characters within a string literal. Either at the beginning, middle, or end of the
+ * literal.
+ */
+ @Test
+ public void testBackslashInLiteral() throws Throwable {
+ String SCRIPT_TEXT = "select 'hello\\\\', '\\\\hello', 'hel\\\\lo', '\\\\' as literal;";
+ final String EXPECTED_PATTERN = "hello\\\\\t\\\\hello\thel\\\\lo\t\\\\";
+ List<String> argList = getBaseArgs(miniHS2.getBaseJdbcURL());
+ argList.add("--outputformat=tsv2");
+ testScriptFile(SCRIPT_TEXT, argList, EXPECTED_PATTERN, true);
+ }
}