You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ai...@apache.org on 2018/06/25 18:41:31 UTC

hive git commit: HIVE-19948: HiveCli is not splitting the command by semicolon properly if quotes are inside the string (Aihua Xu, reviewed by Sahil Takiar)

Repository: hive
Updated Branches:
  refs/heads/master f2c4f3193 -> f37c5de6c


HIVE-19948: HiveCli is not splitting the command by semicolon properly if quotes are inside the string (Aihua Xu, reviewed by Sahil Takiar)


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

Branch: refs/heads/master
Commit: f37c5de6c32b9395d1b34fa3c02ed06d1bfbf6eb
Parents: f2c4f31
Author: Aihua Xu <ai...@apache.org>
Authored: Wed Jun 20 09:01:10 2018 -0700
Committer: Aihua Xu <ai...@apache.org>
Committed: Mon Jun 25 11:39:55 2018 -0700

----------------------------------------------------------------------
 .../org/apache/hadoop/hive/cli/CliDriver.java   | 61 ++++++++++++--------
 .../hadoop/hive/cli/TestCliDriverMethods.java   | 23 ++++++++
 2 files changed, 59 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/f37c5de6/cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java
----------------------------------------------------------------------
diff --git a/cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java b/cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java
index 68741f6..806663d 100644
--- a/cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java
+++ b/cli/src/java/org/apache/hadoop/hive/cli/CliDriver.java
@@ -416,44 +416,55 @@ public class CliDriver {
     }
   }
 
+  /**
+   * Split the line by semicolon by ignoring the ones in the single/double quotes.
+   *
+   */
   public static List<String> splitSemiColon(String line) {
-    boolean insideSingleQuote = false;
-    boolean insideDoubleQuote = false;
+    boolean inQuotes = false;
     boolean escape = false;
-    int beginIndex = 0;
+
     List<String> ret = new ArrayList<>();
+
+    char quoteChar = '"';
+    int beginIndex = 0;
     for (int index = 0; index < line.length(); index++) {
-      if (line.charAt(index) == '\'') {
-        // take a look to see if it is escaped
-        if (!escape) {
-          // flip the boolean variable
-          insideSingleQuote = !insideSingleQuote;
-        }
-      } else if (line.charAt(index) == '\"') {
-        // take a look to see if it is escaped
-        if (!escape) {
-          // flip the boolean variable
-          insideDoubleQuote = !insideDoubleQuote;
-        }
-      } else if (line.charAt(index) == ';') {
-        if (insideSingleQuote || insideDoubleQuote) {
-          // do not split
-        } else {
-          // split, do not include ; itself
+      char c = line.charAt(index);
+      switch (c) {
+      case ';':
+        if (!inQuotes) {
           ret.add(line.substring(beginIndex, index));
           beginIndex = index + 1;
         }
-      } else {
-        // nothing to do
+        break;
+      case '"':
+      case '\'':
+        if (!escape) {
+          if (!inQuotes) {
+            quoteChar = c;
+            inQuotes = !inQuotes;
+          } else {
+            if (c == quoteChar) {
+              inQuotes = !inQuotes;
+            }
+          }
+        }
+        break;
+      default:
+        break;
       }
-      // set the escape
+
       if (escape) {
         escape = false;
-      } else if (line.charAt(index) == '\\') {
+      } else if (c == '\\') {
         escape = true;
       }
     }
-    ret.add(line.substring(beginIndex));
+
+    if (beginIndex < line.length()) {
+      ret.add(line.substring(beginIndex));
+    }
+
     return ret;
   }
 

http://git-wip-us.apache.org/repos/asf/hive/blob/f37c5de6/cli/src/test/org/apache/hadoop/hive/cli/TestCliDriverMethods.java
----------------------------------------------------------------------
diff --git a/cli/src/test/org/apache/hadoop/hive/cli/TestCliDriverMethods.java b/cli/src/test/org/apache/hadoop/hive/cli/TestCliDriverMethods.java
index c06ec3e..8f8f04e 100644
--- a/cli/src/test/org/apache/hadoop/hive/cli/TestCliDriverMethods.java
+++ b/cli/src/test/org/apache/hadoop/hive/cli/TestCliDriverMethods.java
@@ -53,6 +53,7 @@ import org.apache.hadoop.hive.metastore.api.FieldSchema;
 import org.apache.hadoop.hive.metastore.api.Schema;
 import org.apache.hadoop.hive.ql.IDriver;
 import org.apache.hadoop.hive.ql.processors.CommandProcessorResponse;
+import org.junit.Test;
 
 
 // Cannot call class TestCliDriver since that's the name of the generated
@@ -353,6 +354,28 @@ public class TestCliDriverMethods extends TestCase {
     }
   }
 
+  @Test
+  public void testCommandSplits() {
+    // Test double quote in the string
+    String cmd1 = "insert into escape1 partition (ds='1', part='\"') values (\"!\")";
+    assertEquals(cmd1, CliDriver.splitSemiColon(cmd1).get(0));
+    assertEquals(cmd1, CliDriver.splitSemiColon(cmd1 + ";").get(0));
+
+    // Test escape
+    String cmd2 = "insert into escape1 partition (ds='1', part='\"\\'') values (\"!\")";
+    assertEquals(cmd2, CliDriver.splitSemiColon(cmd2).get(0));
+    assertEquals(cmd2, CliDriver.splitSemiColon(cmd2 + ";").get(0));
+
+    // Test multiple commands
+    List<String> results = CliDriver.splitSemiColon(cmd1 + ";" + cmd2);
+    assertEquals(cmd1, results.get(0));
+    assertEquals(cmd2, results.get(1));
+
+    results = CliDriver.splitSemiColon(cmd1 + ";" + cmd2 + ";");
+    assertEquals(cmd1, results.get(0));
+    assertEquals(cmd2, results.get(1));
+  }
+
   private static void setEnv(String key, String value) throws Exception {
     Class[] classes = Collections.class.getDeclaredClasses();
     Map<String, String> env = System.getenv();