Skip to content

Commit 9061987

Browse files
committed
properly handle non-string field
Signed-off-by: Jialiang Liang <jiallian@amazon.com>
1 parent 5723a9f commit 9061987

2 files changed

Lines changed: 22 additions & 14 deletions

File tree

core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import org.apache.calcite.rex.RexNode;
4949
import org.apache.calcite.rex.RexWindowBounds;
5050
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
51+
import org.apache.calcite.sql.type.SqlTypeFamily;
5152
import org.apache.calcite.sql.type.SqlTypeName;
5253
import org.apache.calcite.tools.RelBuilder;
5354
import org.apache.calcite.tools.RelBuilder.AggCall;
@@ -182,6 +183,13 @@ public RelNode visitRegex(Regex node, CalcitePlanContext context) {
182183
RexNode fieldRex = rexVisitor.analyze(node.getField(), context);
183184
RexNode patternRex = rexVisitor.analyze(node.getPattern(), context);
184185

186+
if (!SqlTypeFamily.CHARACTER.contains(fieldRex.getType())) {
187+
throw new IllegalArgumentException(
188+
String.format(
189+
"Regex command requires field of string type, but got %s for field '%s'",
190+
fieldRex.getType().getSqlTypeName(), node.getField().toString()));
191+
}
192+
185193
RexNode regexCondition =
186194
context.rexBuilder.makeCall(
187195
org.apache.calcite.sql.fun.SqlLibraryOperators.REGEXP_CONTAINS, fieldRex, patternRex);

ppl/src/test/java/org/opensearch/sql/ppl/calcite/CalcitePPLRegexTest.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
package org.opensearch.sql.ppl.calcite;
77

8+
import static org.junit.Assert.assertTrue;
9+
import static org.junit.Assert.fail;
10+
811
import org.apache.calcite.rel.RelNode;
912
import org.apache.calcite.test.CalciteAssert;
1013
import org.junit.Test;
@@ -154,19 +157,16 @@ public void testRegexCaseInsensitive() {
154157
}
155158

156159
@Test
157-
public void testRegexWithNumericPattern() {
158-
String ppl = "source=EMP | regex SAL='[0-9]{4,}' | fields ENAME, SAL";
159-
RelNode root = getRelNode(ppl);
160-
String expectedLogical =
161-
"LogicalProject(ENAME=[$1], SAL=[$5])\n"
162-
+ " LogicalFilter(condition=[REGEXP_CONTAINS($5, '[0-9]{4,}':VARCHAR)])\n"
163-
+ " LogicalTableScan(table=[[scott, EMP]])\n";
164-
verifyLogical(root, expectedLogical);
165-
166-
String expectedSparkSql =
167-
"SELECT `ENAME`, `SAL`\n"
168-
+ "FROM `scott`.`EMP`\n"
169-
+ "WHERE REGEXP_CONTAINS(`SAL`, '[0-9]{4,}')";
170-
verifyPPLToSparkSQL(root, expectedSparkSql);
160+
public void testRegexWithNonStringFieldThrowsException() {
161+
String ppl = "source=EMP | regex EMPNO='123.*'";
162+
try {
163+
getRelNode(ppl);
164+
fail("Expected IllegalArgumentException for non-string field type");
165+
} catch (IllegalArgumentException e) {
166+
assertTrue(
167+
"Expected error message about field type",
168+
e.getMessage().contains("Regex command requires field of string type"));
169+
assertTrue("Expected error message to mention field name", e.getMessage().contains("EMPNO"));
170+
}
171171
}
172172
}

0 commit comments

Comments
 (0)