Skip to content

HIVE-29696: Vectorization: ClassCastException in VectorPTFGroupBatches when buffering complex window function inputs#6579

Open
Aggarwal-Raghav wants to merge 3 commits into
apache:masterfrom
Aggarwal-Raghav:HIVE-29696
Open

HIVE-29696: Vectorization: ClassCastException in VectorPTFGroupBatches when buffering complex window function inputs#6579
Aggarwal-Raghav wants to merge 3 commits into
apache:masterfrom
Aggarwal-Raghav:HIVE-29696

Conversation

@Aggarwal-Raghav

@Aggarwal-Raghav Aggarwal-Raghav commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Do Vector PTF input expressions evaluation eagerly on the original batch rather than lazily on the dense buffer.

Why are the changes needed?

To fix ClassCastExceptions in window functions during vectorized execution. When VectorPTFOperator buffers rows, it compacts the column array to save memory, which shuffles the column indices. The old logic attempted to dynamically patch these indices but failed to traverse nested child expressions (like A + B + C )

Caused by: java.lang.ClassCastException: class org.apache.hadoop.hive.ql.exec.vector.BytesColumnVector cannot be cast to class org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector (org.apache.hadoop.hive.ql.exec.vector.BytesColumnVector and org.apache.hadoop.hive.ql.exec.vector.DecimalColumnVector are in unnamed module of loader 'app')
	at org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColAddDecimalColumn.evaluate(DecimalColAddDecimalColumn.java:59)
	at org.apache.hadoop.hive.ql.exec.vector.expressions.VectorExpression.evaluateChildren(VectorExpression.java:323)
	at org.apache.hadoop.hive.ql.exec.vector.expressions.gen.DecimalColAddDecimalColumn.evaluate(DecimalColAddDecimalColumn.java:56)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFEvaluatorBase.evaluateInputExpr(VectorPTFEvaluatorBase.java:92)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFEvaluatorDecimalSum.evaluateGroupBatch(VectorPTFEvaluatorDecimalSum.java:51)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFGroupBatches.runEvaluator(VectorPTFGroupBatches.java:982)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFGroupBatches$BlockIterator.run(VectorPTFGroupBatches.java:263)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFGroupBatches.runEvaluatorOnRange(VectorPTFGroupBatches.java:894)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFGroupBatches.runEvaluatorForRow(VectorPTFGroupBatches.java:874)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFGroupBatches.finishPartition(VectorPTFGroupBatches.java:444)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFOperator.finishPartition(VectorPTFOperator.java:637)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFOperator.closeOp(VectorPTFOperator.java:788)
	at org.apache.hadoop.hive.ql.exec.Operator.close(Operator.java:686)
	at org.apache.hadoop.hive.ql.exec.Operator.close(Operator.java:708)
	at org.apache.hadoop.hive.ql.exec.tez.ReduceRecordProcessor.close(ReduceRecordProcessor.java:361)
	... 21 more

Does this PR introduce any user-facing change?

NO

How was this patch tested?

Wrote 2 q files

mvn test -Pitests -pl itests/qtest -Dtest=TestMiniLlapLocalCliDriver -Dqfile=vectorized_ptf_decimal_col_cast_exception.q,vectorized_ptf_long_col_cast_exception.q -Drat.skip=true

@Aggarwal-Raghav

Copy link
Copy Markdown
Contributor Author

CC @abstractdog, because of HIVE-24761

@deniskuzZ

Copy link
Copy Markdown
Member

@Aggarwal-Raghav , thanks for the fix! please check unused imports

@Aggarwal-Raghav

Copy link
Copy Markdown
Contributor Author

@Aggarwal-Raghav , thanks for the fix! please check unused imports

Sure, will do once first level review is done and address them along with review comments.

Comment on lines 397 to +503
@@ -476,39 +489,27 @@ private void initBufferedColumns() {
}

private void initExpressionColumns() {
for (int i = 0; i < evaluators.length; i++) {
VectorPTFEvaluatorBase evaluator = evaluators[i];
for (VectorPTFEvaluatorBase evaluator : evaluators) {
/*
* Non-streaming evaluators work on buffered batches, we need to adapt them. Before PTF
* bounded start vectorization (HIVE-24761), VectorExpression.outputColumnNum was closed and
* VectorExpression.inputColumnNum didn't even exist (even though the vast majority of
* VectorExpression subclasses use at least 1 input column). Since VectorPTFOperator and
* VectorPTFGroupBatches work on modified batches (by not storing all the columns, and having
* ordering columns first), the expressions planned in compile-time won't work with the
* original config (column layout). It would make sense to move this logic to compile time,
* because here in runtime, a very simple mapping (bufferedColumnMap) is used, so it might be
* used. However, vectorized expression compilation affects many layers of code (having
* VectorizationContext as the common scope), and moving the calculation of bufferedColumnMap
* and this override logic to compile-time would create much more complicated behavior there
* (probably involving hacking most of the time, or maybe a great re-design) just because of
* the optimized column layout of the PTF vectorization.
* Non-streaming window function evaluators (like SUM or LEAD) work on packed, buffered batches.
* VectorPTFOperator and VectorPTFGroupBatches significantly modify the batch structure to save memory
* (e.g. by dropping unused columns and moving ordering columns to the front).
*
* Because of this dense packing, the absolute column indices assigned by the compiler (e.g., Index 15)
* are no longer valid for the buffer (where it might now be Index 2).
* Therefore, we must dynamically map the evaluator's inputColumnNum to its new location in the packed array.
*
* NOTE: We ONLY patch the evaluator's input index here. We specifically DO NOT patch
* evaluator.inputVecExpr (the math expressions like A+B) because those are now evaluated eagerly

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any perf impact after the change?

@Aggarwal-Raghav Aggarwal-Raghav Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not an expert on vectorization but from the understanding while debugging this:
There is no performance degradation because the PTF operator does not filter rows; every row evaluated eagerly would have been lazily evaluated anyway. Infact, it provides benefits,

  • Instead of writing raw inputs to a memory/disk buffer and fetching them back later to do the math
  • By doing the math eagerly on the original batch, the buffering logic can drop the intermediate child scratch column (example Index 14) columns before buffering even starts. This means our BufferedVectorizedRowBatch takes up less RAM and disk footprint!"

Please let me know If I'm missing something.

flowchart TD
    subgraph Lazy ["😬 BEFORE (Lazy Evaluation) - High Memory & Evaluation Overhead"]
        direction TB
        L1["1. Raw Data Arrives"]
        L2["2. Pack into Buffer\n(Writes Raw Inputs to Memory / Disk)"]
        L3["3. Partition Finishes"]
        L4["4. Fetch rows back from Buffer"]
        L5["5. Evaluate Math (A+B+C)\n(Creates intermediate Index 14 in RAM)"]
        L6["6. Run SUM()"]
        
        L1 --> L2 --> L3 --> L4 --> L5 --> L6
    end

    subgraph Eager ["😀 AFTER (Eager Evaluation) - Max Memory Efficiency"]
        direction TB
        E1["1. Raw Data Arrives"]
        E2["2. Evaluate Math IMMEDIATELY\n(Index 1 ➔ Index 14 ➔ Index 15)"]
        E3["3. Pack Final Answer into Buffer\n(Drops Index 14 to save RAM! Writes Index 15)"]
        E4["4. Partition Finishes"]
        E5["5. Run SUM()\n(Reads final answer directly)"]
        
        E1 --> E2 --> E3 --> E4 --> E5
    end

    classDef bad fill:#f8d7da,stroke:#dc3545,stroke-width:2px;
    classDef good fill:#d4edda,stroke:#28a745,stroke-width:2px;
    classDef mem_win fill:#cce5ff,stroke:#004085,stroke-width:2px;
    
    class L4,L5 bad;
    class E1,E2 good;
    class E3 mem_win;
Loading

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sence!
btw lazy evaluation was introduced in https://github.com/apache/hive/pull/2278/changes, so let me cc @abstractdog

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, It would be beneficial to get further insights

Comment thread ql/src/test/queries/clientpositive/vectorized_ptf_long_col_cast_exception.q Outdated
Comment thread ql/src/test/queries/clientpositive/vectorized_ptf_decimal_col_cast_exception.q Outdated
@Aggarwal-Raghav

Copy link
Copy Markdown
Contributor Author

Sharing MORE Context, I observed 1 more stacktrace similar to this in hive-server2.err file, but the flow is similar. So, i guess it will be fixed by this PR.

Caused by: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing vector batch (tag=0) (vectorizedVertexNum 2)
	at org.apache.hadoop.hive.ql.exec.tez.ReduceRecordSource.pushRecord(ReduceRecordSource.java:410)
	at org.apache.hadoop.hive.ql.exec.tez.ReduceRecordSource.pushRecord(ReduceRecordSource.java:258)
	at org.apache.hadoop.hive.ql.exec.tez.ReduceRecordProcessor.run(ReduceRecordProcessor.java:291)
	at org.apache.hadoop.hive.ql.exec.tez.TezProcessor.initializeAndRunProcessor(TezProcessor.java:293)
	... 16 more
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing vector batch (tag=0) (vectorizedVertexNum 2)
	at org.apache.hadoop.hive.ql.exec.tez.ReduceRecordSource.processVectorGroup(ReduceRecordSource.java:518)
	at org.apache.hadoop.hive.ql.exec.tez.ReduceRecordSource.pushRecordVector(ReduceRecordSource.java:401)
	... 19 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 49 out of bounds for length 47
	at org.apache.hadoop.hive.ql.exec.vector.expressions.gen.StringGroupColEqualStringGroupScalarBase.evaluate(StringGroupColEqualStringGroupScalarBase.java:67)
	at org.apache.hadoop.hive.ql.exec.vector.expressions.VectorExpression.evaluateChildren(VectorExpression.java:323)
	at org.apache.hadoop.hive.ql.exec.vector.expressions.gen.IfExprLongScalarLongScalar.evaluate(IfExprLongScalarLongScalar.java:67)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFEvaluatorBase.evaluateInputExpr(VectorPTFEvaluatorBase.java:91)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFEvaluatorLongSum.evaluateGroupBatch(VectorPTFEvaluatorLongSum.java:45)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFGroupBatches.runEvaluator(VectorPTFGroupBatches.java:982)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFGroupBatches$BlockIterator.run(VectorPTFGroupBatches.java:263)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFGroupBatches.runEvaluatorOnRange(VectorPTFGroupBatches.java:894)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFGroupBatches.runEvaluatorForRow(VectorPTFGroupBatches.java:874)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFGroupBatches.finishPartition(VectorPTFGroupBatches.java:444)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFOperator.finishPartition(VectorPTFOperator.java:632)
	at org.apache.hadoop.hive.ql.exec.vector.ptf.VectorPTFOperator.process(VectorPTFOperator.java:402)
	at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:919)
	at org.apache.hadoop.hive.ql.exec.vector.VectorSelectOperator.process(VectorSelectOperator.java:158)
	at org.apache.hadoop.hive.ql.exec.tez.ReduceRecordSource.processVectorGroup(ReduceRecordSource.java:502)
	... 20 more

Comment thread ql/src/test/queries/clientpositive/vector_ptf_nested_input_expr.q
@sonarqubecloud

sonarqubecloud Bot commented Jul 8, 2026

Copy link
Copy Markdown

@deniskuzZ deniskuzZ left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM +1

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants