[KYUUBI #6221] Fix parameter replacement issue caused by incorrect sql split
# 🔍 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 🔖
- [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 ⚰️
#### Behavior With This Pull Request 🎉
#### 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 <tatian@ebay.com>
Signed-off-by: Cheng Pan <chengpan@apache.org>
(cherry picked from commit 612dd7ac45)
Signed-off-by: Cheng Pan <chengpan@apache.org>
This commit is contained in:
parent
01f7dc07f9
commit
676f111a25
@ -106,25 +106,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;
|
||||
}
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user