Skip to content

Commit b254cf6

Browse files
committed
fixes
Signed-off-by: Kai Huang <ahkcs@amazon.com>
1 parent 16eaa86 commit b254cf6

2 files changed

Lines changed: 48 additions & 48 deletions

File tree

core/src/main/java/org/opensearch/sql/expression/function/CollectionUDF/MVFindFunctionImpl.java

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -60,44 +60,45 @@ public Expression implement(
6060
// Check if regex pattern is a literal - compile at planning time
6161
if (call.operands.size() >= 2 && call.operands.get(1) instanceof RexLiteral) {
6262
RexLiteral patternLiteral = (RexLiteral) call.operands.get(1);
63-
Object literalValue = patternLiteral.getValue();
64-
65-
if (literalValue != null) {
66-
// Convert numeric or other types to string for regex matching
67-
String patternString = literalValue.toString();
68-
try {
69-
// Compile pattern at planning time and validate
70-
Pattern compiledPattern = Pattern.compile(patternString);
71-
// Generate code that uses the pre-compiled pattern
72-
return Expressions.call(
73-
Types.lookupMethod(
74-
MVFindFunctionImpl.class, "evalWithPattern", List.class, Pattern.class),
75-
arrayExpr,
76-
Expressions.constant(compiledPattern, Pattern.class));
77-
} catch (PatternSyntaxException e) {
78-
// Convert to IllegalArgumentException so it's treated as a client error (400)
79-
throw new IllegalArgumentException(
80-
String.format("Invalid regex pattern '%s': %s", patternString, e.getDescription()),
81-
e);
82-
}
63+
Expression literalPatternExpr = tryCompileLiteralPattern(patternLiteral, arrayExpr);
64+
if (literalPatternExpr != null) {
65+
return literalPatternExpr;
8366
}
8467
}
8568

86-
// For null or dynamic patterns, use evalWithString
69+
// For dynamic patterns, use evalWithString
8770
return Expressions.call(
8871
Types.lookupMethod(MVFindFunctionImpl.class, "evalWithString", List.class, Object.class),
8972
arrayExpr,
9073
patternExpr);
9174
}
75+
76+
private static Expression tryCompileLiteralPattern(
77+
RexLiteral patternLiteral, Expression arrayExpr) {
78+
Object literalValue = patternLiteral.getValue();
79+
if (literalValue == null) {
80+
return null;
81+
}
82+
83+
// Convert numeric or other types to string for regex matching
84+
String patternString = literalValue.toString();
85+
try {
86+
// Compile pattern at planning time and validate
87+
Pattern compiledPattern = Pattern.compile(patternString);
88+
// Generate code that uses the pre-compiled pattern
89+
return Expressions.call(
90+
Types.lookupMethod(
91+
MVFindFunctionImpl.class, "evalWithPattern", List.class, Pattern.class),
92+
arrayExpr,
93+
Expressions.constant(compiledPattern, Pattern.class));
94+
} catch (PatternSyntaxException e) {
95+
// Convert to IllegalArgumentException so it's treated as a client error (400)
96+
throw new IllegalArgumentException(
97+
String.format("Invalid regex pattern '%s': %s", patternString, e.getDescription()), e);
98+
}
99+
}
92100
}
93101

94-
/**
95-
* Core mvfind logic that searches for a pattern in an array.
96-
*
97-
* @param array The array to search
98-
* @param pattern The pre-compiled regex pattern
99-
* @return The 0-based index of the first matching element, or null if no match
100-
*/
101102
private static Integer mvfindCore(List<Object> array, Pattern pattern) {
102103
for (int i = 0; i < array.size(); i++) {
103104
Object element = array.get(i);
@@ -130,14 +131,32 @@ public static Integer evalWithPattern(List<Object> array, Pattern pattern) {
130131
}
131132
}
132133

134+
/**
135+
* Evaluates mvfind with type coercion support (for dynamic patterns at runtime). Converts numeric
136+
* or other types to string before pattern compilation.
137+
*
138+
* @param array The array to search
139+
* @param regex The regex pattern (String, Number, or any object with toString())
140+
* @return The 0-based index of the first matching element, or null if no match
141+
*/
142+
public static Integer evalWithString(List<Object> array, Object regex) {
143+
if (array == null || regex == null) {
144+
return null;
145+
}
146+
147+
// Support type coercion: convert numeric or other types to string
148+
String patternString = regex.toString();
149+
return mvfind(array, patternString);
150+
}
151+
133152
/**
134153
* Evaluates mvfind with a String pattern. Compiles the regex pattern and executes search.
135154
*
136155
* @param array The array to search
137156
* @param regex The regex pattern string
138157
* @return The 0-based index of the first matching element, or null if no match
139158
*/
140-
public static Integer mvfind(List<Object> array, String regex) {
159+
private static Integer mvfind(List<Object> array, String regex) {
141160
if (array == null || regex == null) {
142161
return null;
143162
}
@@ -154,22 +173,4 @@ public static Integer mvfind(List<Object> array, String regex) {
154173
throw new RuntimeException("Error in mvfind function: " + e.getMessage(), e);
155174
}
156175
}
157-
158-
/**
159-
* Evaluates mvfind with type coercion support (for dynamic patterns at runtime). Converts numeric
160-
* or other types to string before pattern compilation.
161-
*
162-
* @param array The array to search
163-
* @param regex The regex pattern (String, Number, or any object with toString())
164-
* @return The 0-based index of the first matching element, or null if no match
165-
*/
166-
public static Integer evalWithString(List<Object> array, Object regex) {
167-
if (array == null || regex == null) {
168-
return null;
169-
}
170-
171-
// Support type coercion: convert numeric or other types to string
172-
String patternString = regex.toString();
173-
return mvfind(array, patternString);
174-
}
175176
}

core/src/test/java/org/opensearch/sql/expression/function/CollectionUDF/MVFindFunctionImplTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import java.util.List;
1515
import org.junit.jupiter.api.Test;
1616

17-
/** Unit tests for MVFindFunctionImpl. */
1817
public class MVFindFunctionImplTest {
1918

2019
// Basic functionality tests

0 commit comments

Comments
 (0)