This is an automated email from the ASF dual-hosted git repository.

chengpan pushed a commit to branch branch-1.8
in repository https://gitbox.apache.org/repos/asf/kyuubi.git


The following commit(s) were added to refs/heads/branch-1.8 by this push:
     new dd1bf08be [KYUUBI #6221] Fix parameter replacement issue caused by 
incorrect sql split
dd1bf08be is described below

commit dd1bf08beb94b592db23584b75fbf7e117025a67
Author: tatian <[email protected]>
AuthorDate: Fri Mar 29 10:33:04 2024 +0800

    [KYUUBI #6221] Fix parameter replacement issue caused by incorrect sql split
    
    # :mag: Description
    ## Issue References ๐Ÿ”—
    
    This pull request fixes #6221
    
    ## Describe Your Solution ๐Ÿ”ง
    
    Fix the static function that split the sql by parameter placeholder '?', 
add the handling of cases when the placeholder is within the double quote or 
comment.
    
    ## Types of changes :bookmark:
    
    - [x] Bugfix (non-breaking change which fixes an issue)
    - [ ] New feature (non-breaking change which adds functionality)
    - [ ] Breaking change (fix or feature that would cause existing 
functionality to change)
    
    ## Test Plan ๐Ÿงช
    
    #### Behavior Without This Pull Request :coffin:
    
    #### Behavior With This Pull Request :tada:
    
    #### Related Unit Tests
    org.apache.kyuubi.jdbc.hive.UtilsTest.testSplitSqlStatement
    
    ---
    
    # Checklist ๐Ÿ“
    
    - [ ] This patch was not authored or co-authored using [Generative 
Tooling](https://www.apache.org/legal/generative-tooling.html)
    
    **Be nice. Be informative.**
    
    Closes #6222 from TakawaAkirayo/fix_sql_split_issue.
    
    Closes #6221
    
    a501c38ea [tatian] [KYUUBI #6221] Let UT cover another case
    3b9714569 [tatian] [KYUUBI #6221] Fix parameter replacement issue caused by 
incorrect sql split
    
    Authored-by: tatian <[email protected]>
    Signed-off-by: Cheng Pan <[email protected]>
    (cherry picked from commit 612dd7ac450324db94589b2a161fb1324bc552f4)
    Signed-off-by: Cheng Pan <[email protected]>
---
 .../java/org/apache/kyuubi/jdbc/hive/Utils.java    | 30 +++++++++++--
 .../org/apache/kyuubi/jdbc/hive/UtilsTest.java     | 50 ++++++++++++++++++++--
 2 files changed, 72 insertions(+), 8 deletions(-)

diff --git 
a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/Utils.java 
b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/Utils.java
index 65ad0c41b..d5a829189 100644
--- a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/Utils.java
+++ b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/Utils.java
@@ -99,25 +99,47 @@ public class Utils {
    */
   static List<String> splitSqlStatement(String sql) {
     List<String> parts = new ArrayList<>();
-    int apCount = 0;
+    boolean inSingleQuote = false;
+    boolean inDoubleQuote = false;
+    boolean inComment = false;
     int off = 0;
     boolean skip = false;
 
     for (int i = 0; i < sql.length(); i++) {
       char c = sql.charAt(i);
+      if (inComment) {
+        inComment = (c != '\n');
+        continue;
+      }
       if (skip) {
         skip = false;
         continue;
       }
       switch (c) {
         case '\'':
-          apCount++;
+          if (!inDoubleQuote) {
+            inSingleQuote = !inSingleQuote;
+          }
+          break;
+        case '\"':
+          if (!inSingleQuote) {
+            inDoubleQuote = !inDoubleQuote;
+          }
+          break;
+        case '-':
+          if (!inSingleQuote && !inDoubleQuote) {
+            if (i < sql.length() - 1 && sql.charAt(i + 1) == '-') {
+              inComment = true;
+            }
+          }
           break;
         case '\\':
-          skip = true;
+          if (!inSingleQuote && !inDoubleQuote) {
+            skip = true;
+          }
           break;
         case '?':
-          if ((apCount & 1) == 0) {
+          if (!inSingleQuote && !inDoubleQuote) {
             parts.add(sql.substring(off, i));
             off = i + 1;
           }
diff --git 
a/kyuubi-hive-jdbc/src/test/java/org/apache/kyuubi/jdbc/hive/UtilsTest.java 
b/kyuubi-hive-jdbc/src/test/java/org/apache/kyuubi/jdbc/hive/UtilsTest.java
index fc4a55d9f..87f1a78de 100644
--- a/kyuubi-hive-jdbc/src/test/java/org/apache/kyuubi/jdbc/hive/UtilsTest.java
+++ b/kyuubi-hive-jdbc/src/test/java/org/apache/kyuubi/jdbc/hive/UtilsTest.java
@@ -25,10 +25,7 @@ import com.google.common.collect.ImmutableMap;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Properties;
+import java.util.*;
 import java.util.regex.Pattern;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -156,4 +153,49 @@ public class UtilsTest {
     Pattern pattern = Pattern.compile("^\\d+\\.\\d+\\.\\d+.*");
     assert pattern.matcher(Utils.getVersion()).matches();
   }
+
+  @Test
+  public void testSplitSqlStatement() {
+    String simpleSql = "select 1 from ? where a = ?";
+    List<String> splitSql = Utils.splitSqlStatement(simpleSql);
+    assertEquals(3, splitSql.size());
+    assertEquals("select 1 from ", splitSql.get(0));
+    assertEquals(" where a = ", splitSql.get(1));
+    assertEquals("", splitSql.get(2));
+
+    String placeHolderWithinSingleQuote = "select '?' from ? where a = ?";
+    splitSql = Utils.splitSqlStatement(placeHolderWithinSingleQuote);
+    assertEquals(3, splitSql.size());
+    assertEquals("select '?' from ", splitSql.get(0));
+    assertEquals(" where a = ", splitSql.get(1));
+    assertEquals("", splitSql.get(2));
+
+    String escapePlaceHolder = "select \\? from ? where a = ?";
+    splitSql = Utils.splitSqlStatement(escapePlaceHolder);
+    assertEquals(3, splitSql.size());
+    assertEquals("select \\? from ", splitSql.get(0));
+    assertEquals(" where a = ", splitSql.get(1));
+    assertEquals("", splitSql.get(2));
+
+    String inQuoteLikeRegexFunction =
+        "select "
+            + "regexp_extract(field_a, \"[a-zA-Z]+?\", 0) as extracted_a,"
+            + "regexp_extract(field_b, '[a-zA-Z]+?', 0) as extracted_b"
+            + " from ?";
+    splitSql = Utils.splitSqlStatement(inQuoteLikeRegexFunction);
+    assertEquals(2, splitSql.size());
+    assertEquals(
+        "select "
+            + "regexp_extract(field_a, \"[a-zA-Z]+?\", 0) as extracted_a,"
+            + "regexp_extract(field_b, '[a-zA-Z]+?', 0) as extracted_b from ",
+        splitSql.get(0));
+    assertEquals("", splitSql.get(1));
+
+    String inCommentBlock = "--comments\n" + "select --? \n" + "? from ?";
+    splitSql = Utils.splitSqlStatement(inCommentBlock);
+    assertEquals(3, splitSql.size());
+    assertEquals("--comments\n" + "select --? \n", splitSql.get(0));
+    assertEquals(" from ", splitSql.get(1));
+    assertEquals("", splitSql.get(2));
+  }
 }

Reply via email to