[KYUUBI #7109] Ignore the ? in backticks

### Why are the changes needed?
We will split the sql by `?` when we use `KyuubiPreparedStatement`. But there exist corner case when ? exist in backticks.
For example, below sql contains `?`, but we shouldn't split it by `?`.
```sql
SELECT `(ds|hr)?+.+` FROM sales
```
More details can find at https://hive.apache.org/docs/latest/languagemanual-select_27362043/#regex-column-specification

Hive upstream fix - HIVE-29060

### How was this patch tested?

UT.

### Was this patch authored or co-authored using generative AI tooling?

NO.

Closes #7125 from ruanwenjun/dev_wenjun_fix7109.

Closes #7109

7140980fd [ruanwenjun] [KYUUBI #7109] Ignore the ? in backticks

Lead-authored-by: Wenjun Ruan <wenjun@apache.org>
Co-authored-by: ruanwenjun <zyb@wenjuns-MacBook-Pro-2.local>
Signed-off-by: Cheng Pan <chengpan@apache.org>
This commit is contained in:
Wenjun Ruan 2025-07-07 20:56:36 +08:00 committed by Cheng Pan
parent e98ad7bf32
commit 4e40f9457d
No known key found for this signature in database
GPG Key ID: 8001952629BCC75D
2 changed files with 22 additions and 4 deletions

View File

@ -124,6 +124,7 @@ public class Utils {
boolean inSingleQuote = false; boolean inSingleQuote = false;
boolean inDoubleQuote = false; boolean inDoubleQuote = false;
boolean inComment = false; boolean inComment = false;
boolean inBackticks = false;
int off = 0; int off = 0;
boolean skip = false; boolean skip = false;
@ -148,8 +149,13 @@ public class Utils {
inDoubleQuote = !inDoubleQuote; inDoubleQuote = !inDoubleQuote;
} }
break; break;
case '-': case '`':
if (!inSingleQuote && !inDoubleQuote) { if (!inSingleQuote && !inDoubleQuote) {
inBackticks = !inBackticks;
}
break;
case '-':
if (!inSingleQuote && !inDoubleQuote && !inBackticks) {
if (i < sql.length() - 1 && sql.charAt(i + 1) == '-') { if (i < sql.length() - 1 && sql.charAt(i + 1) == '-') {
inComment = true; inComment = true;
} }
@ -161,7 +167,7 @@ public class Utils {
} }
break; break;
case '?': case '?':
if (!inSingleQuote && !inDoubleQuote) { if (!inSingleQuote && !inDoubleQuote && !inBackticks) {
parts.add(sql.substring(off, i)); parts.add(sql.substring(off, i));
off = i + 1; off = i + 1;
} }
@ -191,7 +197,7 @@ public class Utils {
} }
public static JdbcConnectionParams parseURL(String uri) public static JdbcConnectionParams parseURL(String uri)
throws JdbcUriParseException, SQLException, ZooKeeperHiveClientException { throws JdbcUriParseException, ZooKeeperHiveClientException {
return parseURL(uri, new Properties()); return parseURL(uri, new Properties());
} }
@ -215,7 +221,7 @@ public class Utils {
* jdbc:hive2://server:10001/db;user=foo;password=bar?hive.server2.transport.mode=http;hive.server2.thrift.http.path=hs2 * jdbc:hive2://server:10001/db;user=foo;password=bar?hive.server2.transport.mode=http;hive.server2.thrift.http.path=hs2
*/ */
public static JdbcConnectionParams parseURL(String uri, Properties info) public static JdbcConnectionParams parseURL(String uri, Properties info)
throws JdbcUriParseException, SQLException, ZooKeeperHiveClientException { throws JdbcUriParseException, ZooKeeperHiveClientException {
JdbcConnectionParams connParams = extractURLComponents(uri, info); JdbcConnectionParams connParams = extractURLComponents(uri, info);
if (ZooKeeperHiveClientHelper.isZkDynamicDiscoveryMode(connParams.getSessionVars())) { if (ZooKeeperHiveClientHelper.isZkDynamicDiscoveryMode(connParams.getSessionVars())) {
configureConnParamsFromZooKeeper(connParams); configureConnParamsFromZooKeeper(connParams);

View File

@ -197,5 +197,17 @@ public class UtilsTest {
assertEquals("--comments\n" + "select --? \n", splitSql.get(0)); assertEquals("--comments\n" + "select --? \n", splitSql.get(0));
assertEquals(" from ", splitSql.get(1)); assertEquals(" from ", splitSql.get(1));
assertEquals("", splitSql.get(2)); assertEquals("", splitSql.get(2));
String inIdentifierQuoted =
"SELECT "
+ "regexp_replace(col2, '\\n|\\r|\\t', '') as col2, "
+ "`(col2|col2)?+.+` "
+ "FROM ?";
splitSql = Utils.splitSqlStatement(inIdentifierQuoted);
assertEquals(2, splitSql.size());
assertEquals(
"SELECT regexp_replace(col2, '\\n|\\r|\\t', '') as col2, `(col2|col2)?+.+` FROM ",
splitSql.get(0));
assertEquals("", splitSql.get(1));
} }
} }