This is an automated email from the ASF dual-hosted git repository.
mbudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new dc77792fef [CALCITE-7468] The SPLIT_PART implementation is incorrect
for regex patterns
dc77792fef is described below
commit dc77792feffd5028bf2e77f0ae8539f7f0f24c1b
Author: Mihai Budiu <[email protected]>
AuthorDate: Mon Apr 13 17:49:00 2026 -0700
[CALCITE-7468] The SPLIT_PART implementation is incorrect for regex patterns
Signed-off-by: Mihai Budiu <[email protected]>
---
babel/src/test/resources/sql/postgresql.iq | 37 +++++++++++++++++++++-
.../org/apache/calcite/runtime/SqlFunctions.java | 13 +++++---
.../org/apache/calcite/test/SqlFunctionsTest.java | 11 ++++---
3 files changed, 52 insertions(+), 9 deletions(-)
diff --git a/babel/src/test/resources/sql/postgresql.iq
b/babel/src/test/resources/sql/postgresql.iq
index ef9edb7b53..af230bd21b 100644
--- a/babel/src/test/resources/sql/postgresql.iq
+++ b/babel/src/test/resources/sql/postgresql.iq
@@ -60,7 +60,7 @@ EXPR$0
false
!ok
-#Test string function split_part
+#Test string function split_part, validated on Postgres
select split_part('abc~@~def~@~ghi', '~@~', 2);
EXPR$0
def
@@ -71,6 +71,41 @@ EXPR$0
ghi
!ok
+select split_part('abc.def', '.', 1);
+EXPR$0
+abc
+!ok
+
+select split_part('abc.def', '', 1);
+EXPR$0
+abc.def
+!ok
+
+select split_part('abc.def', '', 2);
+EXPR$0
+
+!ok
+
+select split_part(NULL, '.', 1);
+EXPR$0
+null
+!ok
+
+select split_part(NULL, NULL, NULL);
+EXPR$0
+null
+!ok
+
+select split_part('abc.abc', '.', NULL);
+EXPR$0
+null
+!ok
+
+select split_part('abc', NULL, 1);
+EXPR$0
+null
+!ok
+
# Test string_to_array function
select string_to_array('a,b,c', ',', 'd');
EXPR$0
diff --git a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
index 0d1db4f855..cc6b56520d 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -1004,11 +1004,18 @@ public static List<String> split(String s, String
delimiter) {
/** SQL {@code SPLIT_PART(string, string, int)} function. */
public static String splitPart(String s, String delimiter, int n) {
- if (Strings.isNullOrEmpty(s) || Strings.isNullOrEmpty(delimiter)) {
+ // Function is strict, so arguments cannot be null
+ if (s.isEmpty()) {
return "";
}
- String[] parts = s.split(delimiter, -1);
+
+ String[] parts;
+ if (delimiter.isEmpty()) {
+ parts = new String[] { s };
+ } else {
+ parts = s.split(Pattern.quote(delimiter), -1);
+ }
int partCount = parts.length;
if (n < 0) {
@@ -1022,8 +1029,6 @@ public static String splitPart(String s, String
delimiter, int n) {
return parts[n - 1];
}
-
-
/** SQL {@code SPLIT(string)} function. */
public static List<String> split(String s) {
return split(s, ",");
diff --git a/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
index 4c5f6cc2b7..9c7f4b4a21 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
@@ -1085,14 +1085,17 @@ private void checkCeil(int x, int y, int result) {
assertThat(SqlFunctions.splitPart("abc,,ghi", ",", 2), is(""));
assertThat(SqlFunctions.splitPart("", ",", 1), is(""));
- assertThat(SqlFunctions.splitPart("abc", "", 1), is(""));
-
- assertThat(SqlFunctions.splitPart(null, ",", 1), is(""));
- assertThat(SqlFunctions.splitPart("abc,def", null, 1), is(""));
+ // Tested on Postgres 17: empty delimiter
+ assertThat(SqlFunctions.splitPart("abc", "", 1), is("abc"));
+ assertThat(SqlFunctions.splitPart("abc", "", 2), is(""));
assertThat(SqlFunctions.splitPart("abc,def", ",", 0), is(""));
assertThat(SqlFunctions.splitPart("abc,def", ",", 3), is(""));
assertThat(SqlFunctions.splitPart("abc,def", ",", -3), is(""));
+
+ // Test case for https://issues.apache.org/jira/browse/CALCITE-7468
+ // The SPLIT_PART implementation is incorrect for regex patterns
+ assertThat(SqlFunctions.splitPart("abc.def", ".", 1), is("abc"));
}
@Test void testByteString() {