MCPcopy Create free account
hub / github.com/apache/impala / InitNextPartition

Method InitNextPartition

be/src/exec/analytic-eval-node.cc:513–600  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

511}
512
513inline Status AnalyticEvalNode::InitNextPartition(RuntimeState* state,
514 int64_t stream_idx) {
515 VLOG_FILE << id() << " InitNextPartition idx=" << stream_idx;
516 DCHECK_LT(curr_partition_idx_, stream_idx);
517 int64_t prev_partition_stream_idx = curr_partition_idx_;
518 curr_partition_idx_ = stream_idx;
519
520 // If the window has an end bound preceding the current row, we will have output tuples
521 // for rows beyond the previous partition, so they should be removed. Because
522 // result_tuples_ is a sparse structure, the last result tuple of the previous
523 // partition may have been added to result_tuples_ with a stream index equal to or
524 // beyond curr_partition_idx_. So the last entry in result_tuples_ with a stream index
525 // >= curr_partition_idx_ is the last result tuple of the previous partition. Adding
526 // the last result tuple to result_tuples_ with a stream index curr_partition_idx_ - 1
527 // ensures that all rows in the previous partition have corresponding analytic results.
528 Tuple* prev_partition_last_result_tuple = nullptr;
529 while (!result_tuples_.empty() && result_tuples_.back().first >= curr_partition_idx_) {
530 DCHECK(fn_scope_ == ROWS && window_.__isset.window_end &&
531 window_.window_end.type == TAnalyticWindowBoundaryType::PRECEDING);
532 VLOG_ROW << id() << " Removing result past partition idx: "
533 << result_tuples_.back().first;
534 prev_partition_last_result_tuple = result_tuples_.back().second;
535 result_tuples_.pop_back();
536 }
537 if (prev_partition_last_result_tuple != nullptr) {
538 if (result_tuples_.empty() ||
539 result_tuples_.back().first < curr_partition_idx_ - 1) {
540 // prev_partition_last_result_tuple was the last result tuple in the partition, add
541 // it back with the index of the last row in the partition so that all output rows
542 // in this partition get the correct value.
543 result_tuples_.emplace_back(
544 curr_partition_idx_ - 1, prev_partition_last_result_tuple);
545 }
546 DCHECK(!result_tuples_.empty());
547 last_result_idx_ = result_tuples_.back().first;
548 VLOG_ROW << id() << " After removing results past partition: "
549 << DebugStateString(true);
550 DCHECK_EQ(last_result_idx_, curr_partition_idx_ - 1);
551 DCHECK_LE(input_stream_->rows_returned(), last_result_idx_);
552 }
553 DCHECK(result_tuples_.empty() || (last_result_idx_ == result_tuples_.back().first));
554
555 if (fn_scope_ == ROWS && stream_idx > 0 && (!window_.__isset.window_end ||
556 window_.window_end.type == TAnalyticWindowBoundaryType::FOLLOWING)) {
557 RETURN_IF_ERROR(TryAddRemainingResults(stream_idx, prev_partition_stream_idx));
558 }
559 window_tuples_.clear();
560
561 VLOG_ROW << id() << " Reset curr_tuple";
562 // Call finalize to release resources; result is not needed but the dst tuple must be
563 // a tuple described by result_tuple_desc_.
564 DCHECK(curr_tuple_init_);
565 AggFnEvaluator::Finalize(analytic_fn_evals_, curr_tuple_, dummy_result_tuple_);
566 // Re-initialize curr_tuple_.
567 // TODO: zeroing out curr_tuple_ shouldn't be strictly necessary.
568 curr_tuple_->Init(intermediate_tuple_desc_->byte_size());
569 AggFnEvaluator::Init(analytic_fn_evals_, curr_tuple_);
570 // Check for errors in AggFnEvaluator::Init().

Callers

nothing calls this directly

Calls 7

OKFunction · 0.85
clearMethod · 0.65
emptyMethod · 0.45
rows_returnedMethod · 0.45
InitMethod · 0.45
byte_sizeMethod · 0.45
GetQueryStatusMethod · 0.45

Tested by

no test coverage detected