Skip to content

[GLUTEN-12924][VL] Defer literal node construction for InSet to reduce memory - #12925

Open
WangGuangxin wants to merge 1 commit into
apache:mainfrom
WangGuangxin:inset
Open

[GLUTEN-12924][VL] Defer literal node construction for InSet to reduce memory#12925
WangGuangxin wants to merge 1 commit into
apache:mainfrom
WangGuangxin:inset

Conversation

@WangGuangxin

@WangGuangxin WangGuangxin commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What changes are proposed in this pull request?

This PR reduces driver-side memory usage when converting large InSet expressions to Substrait.

Before this change, InSetTransformer eagerly materialized one Substrait LiteralNode for each element in the IN set and stored all of them in SingularOrListNode. For large IN lists, this creates a large
number of intermediate objects and increases retained heap usage before protobuf serialization.

This PR changes the flow as follows:

  • InSetTransformer keeps the raw IN-set values together with the child data type, instead of eagerly building one LiteralNode per value.
  • SingularOrListNode constructs the corresponding Substrait literal protobuf entries lazily in toProtobuf().
  • During protobuf serialization, options are appended to the builder directly, instead of first collecting them into an extra temporary List<Expression>.
  • The existing deterministic ordering is preserved by sorting IN-set values with the same Literal(_, valueType).toString() logic as before.

In short, this patch reduces the number of long-lived intermediate objects created for large InSet expressions and also avoids an extra temporary protobuf list during serialization.

Why are the changes needed?

Queries with very large IN (...) predicates may be optimized by Spark into InSet. In Gluten's Substrait conversion path, eagerly creating and retaining one LiteralNode per IN-set value can cause high memory
pressure on the driver.

The issue is especially visible for large IN lists, where the conversion step itself may consume much more memory than necessary even though the final serialized representation is only needed at protobuf
generation time.

By deferring literal node construction until toProtobuf(), we reduce retained heap usage in the expression tree and lower peak allocation pressure in the conversion path.

How was this patch tested?

Manually.

Was this patch authored or co-authored using generative AI tooling?

No.

Related issue: #12924

…mory footprint

Keep raw IN-set values and the value data type on SingularOrListNode and build
the substrait LiteralNode options lazily in toProtobuf(), instead of eagerly
materializing one LiteralNode per value. This avoids holding many LiteralNode
objects in memory for large IN lists.

- Add ExpressionBuilder.makeSingularOrListNode(value, rawValues, dataType) and a
  matching SingularOrListNode constructor; build options from raw values lazily.
- InSetTransformer passes sorted raw hset values (deterministic) and defers
  LiteralNode creation to protobuf serialization.
@github-actions github-actions Bot added the CORE works for Gluten Core label Aug 28, 2026
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CORE works for Gluten Core

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant