This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new 599f7d37a9 [vortex] Free intermediate expressions in the predicate
converter (#10073)
599f7d37a9 is described below
commit 599f7d37a944073cbc132d30ddc66cdd8330fb28
Author: jackylee <[email protected]>
AuthorDate: Tue Sep 22 11:27:29 2026 +0800
[vortex] Free intermediate expressions in the predicate converter (#10073)
---
.../format/vortex/VortexPredicateConverter.java | 101 +++++++++++----------
1 file changed, 55 insertions(+), 46 deletions(-)
diff --git
a/paimon-vortex/paimon-vortex-format/src/main/java/org/apache/paimon/format/vortex/VortexPredicateConverter.java
b/paimon-vortex/paimon-vortex-format/src/main/java/org/apache/paimon/format/vortex/VortexPredicateConverter.java
index baf315e86b..02326ba684 100644
---
a/paimon-vortex/paimon-vortex-format/src/main/java/org/apache/paimon/format/vortex/VortexPredicateConverter.java
+++
b/paimon-vortex/paimon-vortex-format/src/main/java/org/apache/paimon/format/vortex/VortexPredicateConverter.java
@@ -69,69 +69,78 @@ public class VortexPredicateConverter implements
PredicateVisitor<Expression> {
return null;
}
FieldRef fieldRef = fieldRefOpt.get();
- Expression field = Expression.column(fieldRef.name());
+ // Builders clone their inputs and leave freeing to the caller (see
the vortex-jni
+ // expression.rs module doc), so the column and the literal are ours
to release once
+ // the call consuming them has returned.
+ try (Expression field = Expression.column(fieldRef.name())) {
+ if (predicate.function() instanceof IsNull) {
+ return Expression.isNull(field);
+ }
+ if (predicate.function() instanceof IsNotNull) {
+ return Expression.isNotNull(field);
+ }
- if (predicate.function() instanceof IsNull) {
- return Expression.isNull(field);
- }
- if (predicate.function() instanceof IsNotNull) {
- return Expression.isNotNull(field);
- }
+ List<Object> literals = predicate.literals();
+ if (literals == null || literals.isEmpty()) {
+ return null;
+ }
- List<Object> literals = predicate.literals();
- if (literals == null || literals.isEmpty()) {
- return null;
- }
+ try (Expression vortexLiteral = toLiteral(fieldRef.type(),
literals.get(0))) {
+ if (vortexLiteral == null) {
+ return null;
+ }
- Expression vortexLiteral = toLiteral(fieldRef.type(), literals.get(0));
- if (vortexLiteral == null) {
- return null;
- }
+ if (predicate.function() instanceof Equal) {
+ return Expression.binary(Expression.BinaryOp.EQ, field,
vortexLiteral);
+ } else if (predicate.function() instanceof NotEqual) {
+ return Expression.binary(Expression.BinaryOp.NOT_EQ,
field, vortexLiteral);
+ } else if (predicate.function() instanceof GreaterThan) {
+ return Expression.binary(Expression.BinaryOp.GT, field,
vortexLiteral);
+ } else if (predicate.function() instanceof GreaterOrEqual) {
+ return Expression.binary(Expression.BinaryOp.GTE, field,
vortexLiteral);
+ } else if (predicate.function() instanceof LessThan) {
+ return Expression.binary(Expression.BinaryOp.LT, field,
vortexLiteral);
+ } else if (predicate.function() instanceof LessOrEqual) {
+ return Expression.binary(Expression.BinaryOp.LTE, field,
vortexLiteral);
+ }
- if (predicate.function() instanceof Equal) {
- return Expression.binary(Expression.BinaryOp.EQ, field,
vortexLiteral);
- } else if (predicate.function() instanceof NotEqual) {
- return Expression.binary(Expression.BinaryOp.NOT_EQ, field,
vortexLiteral);
- } else if (predicate.function() instanceof GreaterThan) {
- return Expression.binary(Expression.BinaryOp.GT, field,
vortexLiteral);
- } else if (predicate.function() instanceof GreaterOrEqual) {
- return Expression.binary(Expression.BinaryOp.GTE, field,
vortexLiteral);
- } else if (predicate.function() instanceof LessThan) {
- return Expression.binary(Expression.BinaryOp.LT, field,
vortexLiteral);
- } else if (predicate.function() instanceof LessOrEqual) {
- return Expression.binary(Expression.BinaryOp.LTE, field,
vortexLiteral);
+ return null;
+ }
}
-
- return null;
}
@Override
public Expression visit(CompoundPredicate predicate) {
- if (predicate.function() instanceof And) {
- List<Expression> children = new ArrayList<>();
+ boolean isAnd = predicate.function() instanceof And;
+ if (!isAnd && !(predicate.function() instanceof Or)) {
+ return null;
+ }
+
+ List<Expression> children = new ArrayList<>();
+ try {
for (Predicate child : predicate.children()) {
Expression expr = child.visit(this);
- if (expr != null) {
- children.add(expr);
+ if (expr == null) {
+ // An Or must push all children or none: dropping a
disjunct narrows the
+ // filter and would drop rows the predicate matches.
Dropping a conjunct
+ // from an And only widens it, which the best-effort
contract allows.
+ if (!isAnd) {
+ return null;
+ }
+ continue;
}
+ children.add(expr);
}
if (children.isEmpty()) {
return null;
}
- return Expression.and(children.toArray(new Expression[0]));
- } else if (predicate.function() instanceof Or) {
- List<Expression> children = new ArrayList<>();
- for (Predicate child : predicate.children()) {
- Expression expr = child.visit(this);
- if (expr == null) {
- return null;
- }
- children.add(expr);
- }
- return Expression.or(children.toArray(new Expression[0]));
+ Expression[] operands = children.toArray(new Expression[0]);
+ return isAnd ? Expression.and(operands) : Expression.or(operands);
+ } finally {
+ // and/or clone their operands, so the children are ours either
way -- and on the Or
+ // give-up path above, the ones already collected would otherwise
be unreachable.
+ children.forEach(Expression::close);
}
-
- return null;
}
@Nullable