@@ -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}
0 commit comments