diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java
index db57e5affed..689ecc1ecf6 100644
--- a/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java
+++ b/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java
@@ -129,6 +129,9 @@ public HiveSqlDialect(Context context) {
case TRIM:
RelToSqlConverterUtil.unparseHiveTrim(writer, call, leftPrec, rightPrec);
break;
+ case RLIKE:
+ RelToSqlConverterUtil.unparseRegexp(writer, call, leftPrec, rightPrec);
+ break;
default:
super.unparseCall(writer, call, leftPrec, rightPrec);
}
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
index 947223b682a..2479a92ba24 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
@@ -705,11 +705,10 @@ static RelDataType deriveTypeSplit(SqlOperatorBinding operatorBinding,
public static final SqlFunction REGEXP_SUBSTR = REGEXP_EXTRACT.withName("REGEXP_SUBSTR");
/** The "REGEXP(value, regexp)" function, equivalent to {@link #RLIKE}. */
- @LibraryOperator(libraries = {SPARK})
+ @LibraryOperator(libraries = {SPARK, HIVE})
public static final SqlFunction REGEXP =
- SqlBasicFunction.create("REGEXP", ReturnTypes.BOOLEAN_NULLABLE,
- OperandTypes.STRING_STRING,
- SqlFunctionCategory.STRING);
+ SqlBasicFunction.create("REGEXP", SqlKind.RLIKE, ReturnTypes.BOOLEAN_NULLABLE,
+ OperandTypes.STRING_STRING);
/** The "REGEXP_LIKE(value, regexp)" function, equivalent to {@link #RLIKE}. */
@LibraryOperator(libraries = {SPARK, MYSQL, POSTGRESQL, ORACLE})
diff --git a/core/src/main/java/org/apache/calcite/util/RelToSqlConverterUtil.java b/core/src/main/java/org/apache/calcite/util/RelToSqlConverterUtil.java
index ddb37e8dac3..975bfc8505b 100644
--- a/core/src/main/java/org/apache/calcite/util/RelToSqlConverterUtil.java
+++ b/core/src/main/java/org/apache/calcite/util/RelToSqlConverterUtil.java
@@ -445,4 +445,19 @@ public ClickHouseSqlArrayTypeNameSpec(SqlTypeNameSpec elementTypeName,
writer.endList(frame);
}
}
+
+ /**
+ * Unparses REGEXP function calls by converting from function call format
+ * (e.g., REGEXP(column, pattern)) to infix operator format (e.g., column REGEXP pattern).
+ */
+ public static void unparseRegexp(SqlWriter writer, SqlCall call, int leftPrec, int rightPrec) {
+ if ("REGEXP".equals(call.getOperator().getName())) {
+ final SqlWriter.Frame frame = writer.startList(SqlWriter.FrameTypeEnum.SIMPLE, "(", ")");
+ call.operand(0).unparse(writer, leftPrec, rightPrec);
+ writer.sep("REGEXP", true);
+ call.operand(1).unparse(writer, leftPrec, rightPrec);
+ writer.endList(frame);
+ }
+ }
+
}
diff --git a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
index a98f7fd1f8f..7f9f10e5578 100644
--- a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
@@ -11761,4 +11761,36 @@ public Sql schema(CalciteAssert.SchemaSpec schemaSpec) {
.ok(expected);
}
+ /** Test case for
+ * [CALCITE-7428]
+ * Support regexp function change regexp operator for Hive library. */
+ @Test void testRegexpWithHive() {
+ final String query = "select \"brand_name\"\n"
+ + "from \"product\" where REGEXP(\"brand_name\",'[a-zA-Z]') ";
+ final String expectedHive = "SELECT `brand_name`\nFROM "
+ + "`foodmart`.`product`\nWHERE (`brand_name` REGEXP '[a-zA-Z]')";
+ sql(query).withLibrary(SqlLibrary.HIVE).withHive().ok(expectedHive);
+ }
+
+ /** Test case for
+ * [CALCITE-7428]
+ * Support regexp function change regexp operator for Hive library. */
+ @Test void testRegexpWithHiveIsNotNull() {
+ final String query = "select \"brand_name\"\n"
+ + "from \"product\" where REGEXP(\"brand_name\",'[a-zA-Z]') is not null ";
+ final String expectedHive = "SELECT `brand_name`\nFROM "
+ + "`foodmart`.`product`\nWHERE (`brand_name` REGEXP '[a-zA-Z]') IS NOT NULL";
+ sql(query).withLibrary(SqlLibrary.HIVE).withHive().ok(expectedHive);
+ }
+
+ /** Test case for
+ * [CALCITE-7428]
+ * Support regexp function change regexp operator for Hive library. */
+ @Test void testSelectRegexpWithHiveIsNotNull() {
+ final String query = "select REGEXP(\"brand_name\",'[a-zA-Z]') is not null \n"
+ + "from \"product\"";
+ final String expectedHive = "SELECT (`brand_name` REGEXP '[a-zA-Z]') IS NOT NULL\n"
+ + "FROM `foodmart`.`product`";
+ sql(query).withLibrary(SqlLibrary.HIVE).withHive().ok(expectedHive);
+ }
}
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index e1ea8e72069..ee3d2d739f8 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -3004,7 +3004,7 @@ In the following:
| b s | POW(numeric1, numeric2) | Returns *numeric1* raised to the power *numeric2*
| b c h q m o f s p r | POWER(numeric1, numeric2) | Returns *numeric1* raised to the power of *numeric2*
| p r | RANDOM() | Generates a random double between 0 and 1 inclusive
-| s | REGEXP(string, regexp) | Equivalent to `string1 RLIKE string2`
+| s h | REGEXP(string, regexp) | Equivalent to `string1 RLIKE string2`
| b | REGEXP_CONTAINS(string, regexp) | Returns whether *string* is a partial match for the *regexp*
| b | REGEXP_EXTRACT(string, regexp [, position [, occurrence]]) | Returns the substring in *string* that matches the *regexp*, starting search at *position* (default 1), and until locating the nth *occurrence* (default 1). Returns NULL if there is no match
| b | REGEXP_EXTRACT_ALL(string, regexp) | Returns an array of all substrings in *string* that matches the *regexp*. Returns an empty array if there is no match
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 41b45d3c761..b6731f9e63f 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -4232,6 +4232,7 @@ void checkIsNull(SqlOperatorFixture f, SqlOperator operator) {
checkRlikeFunc(f, SqlLibrary.HIVE, SqlLibraryOperators.RLIKE);
checkRlikeFunc(f, SqlLibrary.SPARK, SqlLibraryOperators.RLIKE);
checkRlikeFunc(f, SqlLibrary.SPARK, SqlLibraryOperators.REGEXP);
+ checkRlikeFunc(f, SqlLibrary.HIVE, SqlLibraryOperators.REGEXP);
checkRlikeFunc(f, SqlLibrary.MYSQL, SqlLibraryOperators.RLIKE);
checkNotRlikeFunc(f.withLibrary(SqlLibrary.HIVE));
checkNotRlikeFunc(f.withLibrary(SqlLibrary.SPARK));