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 78957058c3 [CALCITE-6923] REGEXP_REPLACE_PG_...: backward references 
behave differently than in postgres
78957058c3 is described below

commit 78957058c3dbb67bfc1cfc1b53b5bfa171d2eeb6
Author: Ulrich Kramer <[email protected]>
AuthorDate: Mon Apr 7 10:12:01 2025 +0200

    [CALCITE-6923] REGEXP_REPLACE_PG_...: backward references behave 
differently than in postgres
---
 babel/src/test/resources/sql/big-query.iq                    | 10 ++++++++++
 babel/src/test/resources/sql/postgresql.iq                   |  5 +++++
 .../main/java/org/apache/calcite/runtime/SqlFunctions.java   | 12 +++++++++---
 .../test/java/org/apache/calcite/test/SqlFunctionsTest.java  |  7 +++++++
 .../main/java/org/apache/calcite/test/SqlOperatorTest.java   |  4 ++++
 5 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/babel/src/test/resources/sql/big-query.iq 
b/babel/src/test/resources/sql/big-query.iq
index 888f61afdd..e587d50267 100755
--- a/babel/src/test/resources/sql/big-query.iq
+++ b/babel/src/test/resources/sql/big-query.iq
@@ -1458,6 +1458,16 @@ SELECT REGEXP_REPLACE("1=00--20=0", "(-)", "#");
 
 !ok
 
+SELECT REGEXP_REPLACE("# Heading", "^# ([a-zA-Z0-9\\s]+$)", "<h1>\\1</h1>");
++------------------+
+| EXPR$0           |
++------------------+
+| <h1>Heading</h1> |
++------------------+
+(1 row)
+
+!ok
+
 #####################################################################
 # REGEXP_SUBSTR(value, regexp[, position[, occurrence]])
 #
diff --git a/babel/src/test/resources/sql/postgresql.iq 
b/babel/src/test/resources/sql/postgresql.iq
index 7cea0ab532..383dbfad1c 100644
--- a/babel/src/test/resources/sql/postgresql.iq
+++ b/babel/src/test/resources/sql/postgresql.iq
@@ -1257,4 +1257,9 @@ X
 X def GHI
 !ok
 
+SELECT regexp_replace('ABC def GHI', '([a-z]+).*', '\1', 'i') AS x;
+X
+ABC
+!ok
+
 # End postgresql.iq
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 7609a6a38b..3367a9a77f 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -749,20 +749,25 @@ public String regexpReplace(String s, String regex, 
String replacement,
 
     /** SQL {@code REGEXP_REPLACE} function for PostgreSQL with 3 arguments. */
     public String regexpReplacePg(String s, String regex, String replacement) {
-      return regexpReplace(s, regex, replacement, 1, 1, null);
+      return regexpReplaceNonDollarIndexed(s, regex, replacement, 1, 1, null);
     }
 
     /** SQL {@code REGEXP_REPLACE} function for PostgreSQL with 4 arguments. */
     public String regexpReplacePg(String s, String regex, String replacement, 
String matchType) {
       // Translate g flag to occurrence
       final int occurrence = matchType.contains("g") ? 0 : 1;
-      return regexpReplace(s, regex, replacement, 1, occurrence, matchType);
+      return regexpReplaceNonDollarIndexed(s, regex, replacement, 1, 
occurrence, matchType);
     }
 
     /** SQL {@code REGEXP_REPLACE} function with 3 arguments with
      * {@code \\} based indexing for capturing groups. */
     public String regexpReplaceNonDollarIndexed(String s, String regex,
         String replacement) {
+      return regexpReplaceNonDollarIndexed(s, regex, replacement, 1, 0, null);
+    }
+
+    private String regexpReplaceNonDollarIndexed(String s, String regex,
+        String replacement, int pos, int occurrence, @Nullable String 
matchType) {
       // Modify double-backslash capturing group indices in replacement 
argument,
       // retrieved from cache when available.
       String indexedReplacement;
@@ -776,9 +781,10 @@ public String regexpReplaceNonDollarIndexed(String s, 
String regex,
       }
 
       // Call generic regexp replace method with modified replacement pattern
-      return regexpReplace(s, regex, indexedReplacement, 1, 0, null);
+      return regexpReplace(s, regex, indexedReplacement, pos, occurrence, 
matchType);
     }
 
+
     private static int makeRegexpFlags(String stringFlags) {
       int flags = 0;
       for (int i = 0; i < stringFlags.length(); ++i) {
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 13f5a88744..d68d4b2988 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
@@ -616,6 +616,13 @@ static <E> List<E> list() {
       assertThat(e.getMessage(),
           is("Invalid input for REGEXP_REPLACE: 'WWW'"));
     }
+
+    assertThat(f.regexpReplacePg("abc", "a(.*)c", "x\\1x", "i"),
+        is("xbx"));
+    assertThat(f.regexpReplace("abc", "a(.*)c", "x$1x"),
+        is("xbx"));
+    assertThat(f.regexpReplace("abc", "a(.*)c", "x\\1x"),
+        is("x1x"));
   }
 
   @Test void testReplaceNonDollarIndexedString() {
diff --git a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java 
b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
index b02a4d5d35..d04a35e3ac 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -6400,6 +6400,8 @@ private static void checkIf(SqlOperatorFixture f) {
         "VARCHAR NOT NULL");
   }
 
+
+
   @Test void testRegexpReplace4Func() {
     final SqlOperatorFixture f0 = fixture();
     final Consumer<SqlOperatorFixture> consumer = f -> {
@@ -6502,6 +6504,8 @@ private static void checkIf(SqlOperatorFixture f) {
         "VARCHAR NOT NULL");
     f.checkString("regexp_replace('abc\t\ndef\t\nghi', '\\w+', '+')", 
"+\t\ndef\t\nghi",
         "VARCHAR NOT NULL");
+    f.checkString("regexp_replace('abc', 'a(.*)c', 'x\\1x')", "xbx",
+        "VARCHAR NOT NULL");
 
     f.checkQuery("select regexp_replace('a b c', 'b', 'X')");
   }

Reply via email to