|
97 | 97 | import org.opensearch.sql.ast.tree.Patterns; |
98 | 98 | import org.opensearch.sql.ast.tree.Project; |
99 | 99 | import org.opensearch.sql.ast.tree.RareTopN; |
| 100 | +import org.opensearch.sql.ast.tree.Regex; |
100 | 101 | import org.opensearch.sql.ast.tree.Relation; |
101 | 102 | import org.opensearch.sql.ast.tree.Rename; |
102 | 103 | import org.opensearch.sql.ast.tree.Sort; |
@@ -169,6 +170,28 @@ public RelNode visitFilter(Filter node, CalcitePlanContext context) { |
169 | 170 | return context.relBuilder.peek(); |
170 | 171 | } |
171 | 172 |
|
| 173 | + @Override |
| 174 | + public RelNode visitRegex(Regex node, CalcitePlanContext context) { |
| 175 | + visitChildren(node, context); |
| 176 | + // For Calcite engine, use REGEXP function but the RegexMatch expression will be executed |
| 177 | + // with PCRE2 support in the script engine during pushdown |
| 178 | + List<UnresolvedExpression> args = new ArrayList<>(); |
| 179 | + args.add(node.getField()); |
| 180 | + args.add(node.getPattern()); |
| 181 | + |
| 182 | + // Use the standard REGEXP function - the PCRE2 execution happens in the script engine |
| 183 | + Function regexFunction = new Function("regexp", args); |
| 184 | + RexNode condition = rexVisitor.analyze(regexFunction, context); |
| 185 | + |
| 186 | + // If negated, wrap with NOT |
| 187 | + if (node.isNegated()) { |
| 188 | + condition = context.rexBuilder.makeCall(SqlStdOperatorTable.NOT, condition); |
| 189 | + } |
| 190 | + |
| 191 | + context.relBuilder.filter(condition); |
| 192 | + return context.relBuilder.peek(); |
| 193 | + } |
| 194 | + |
172 | 195 | private boolean containsSubqueryExpression(Node expr) { |
173 | 196 | if (expr == null) { |
174 | 197 | return false; |
|
0 commit comments