blob: 899e6bd8ca8dfd606fa58365131b70b7bb200733 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include "kudu/common/column_predicate.h"
#include "kudu/common/columnblock.h"
namespace kudu {
// A ColumnMaterializationContext provides a clean interface to the set of
// objects that get passed down to the column iterator and decoders during
// materialization.
//
// Example of path taken:
// MaterializingIterator -> CFileSet::Iterator -> CFileIterator -> BlockDecoder
class ColumnMaterializationContext {
public:
ColumnMaterializationContext(size_t col_idx,
const ColumnPredicate* pred,
ColumnBlock* block,
SelectionVector* sel)
: col_idx_(col_idx),
pred_(pred),
block_(block),
sel_(sel),
decoder_eval_status_(kNotSet) {
if (!pred_ || !sel || !block) {
decoder_eval_status_ = kDecoderEvalNotSupported;
}
}
// Column index in within the projection schema, not the underlying schema.
const size_t col_idx() { return col_idx_; }
// Predicate being evaluated.
const ColumnPredicate* pred() { return pred_; }
// Destination for copied data.
ColumnBlock* block() { return block_; }
// Selection vector reflecting the result of the predicate evaluation.
// If a given bit is already cleared, that row can be skipped.
//
// Required non-null if used by scans, else there will be a nullptr reference
// when creating a SelectionVectorView around it. Must be large enough to
// cover the number of rows being scanned.
SelectionVector* sel() { return sel_; }
// Checked after returning from the decoder to determine whether or not the
// block must still be evaluated (on true).
bool DecoderEvalNotSupported() const {
return decoder_eval_status_ == kDecoderEvalNotSupported;
}
// Checked by CFileIterator::Scan() to determine whether decoder-level
// evaluation should be attempted (on true).
bool DecoderEvalNotDisabled() const {
return decoder_eval_status_ != kDecoderEvalNotSupported;
}
// Checked during materialization to determine whether null values should be
// cleared in the results vector.
bool EvaluatingIsNull() const {
return pred_ && pred_->predicate_type() == PredicateType::IsNull;
}
// A context should not switch from supporting decoder-level eval to not
// supporting it, or vice versa.
//
// Going from NotSupported to Supported may lead to incorrect results if
// previously scanned rows materialize values that should not be in the
// results set. To prevent this, attempts to do this will result in no-ops.
// This will disable decoder-level evaluation and yield correct values.
//
// Should only be called by CopyNextAndEval() of a decoder that supports
// evaluation.
void SetDecoderEvalSupported() {
DCHECK(decoder_eval_status_ != kDecoderEvalNotSupported);
if (decoder_eval_status_ == kNotSet) {
DCHECK(sel_ != nullptr && pred_ != nullptr);
decoder_eval_status_ = kDecoderEvalSupported;
}
}
// Going from Supported to NotSupported may lead to errors if the scan
// previously evaluated rows that were deemed to be not in the result set.
// During batch evaluation, these rows would be missing from the buffer,
// and this could lead to a memory error.
//
// Should be called before materializing a column if support has manually
// been turned off with materializing_iterator_decoder_eval flag, or by
// CopyNextAndEval() of a decoder that does not support evaluation.
void SetDecoderEvalNotSupported() {
CHECK(decoder_eval_status_ != kDecoderEvalSupported);
decoder_eval_status_ = kDecoderEvalNotSupported;
}
private:
enum DecoderEvalStatus {
// During scan, will try to evaluate with the decoder, after which the
// correct status will be set.
kNotSet = 0,
// May be set before scanning if the decoder eval flag is set to false
// or if iterator has deltas associated with it or if the predicate is
// determined to be ineffective.
// May be set by decoder during scan if decoder eval is not supported.
// Once set, scanning will materialize the entire column into the block,
// leaving evaluation for after the scan.
kDecoderEvalNotSupported,
// Is set by a decoder during scan if decoder eval is supported.
// Once set, the decoder is contractually bound to return with selection
// vector filled out.
kDecoderEvalSupported
};
const size_t col_idx_;
const ColumnPredicate* pred_;
ColumnBlock* block_;
SelectionVector* const sel_;
DecoderEvalStatus decoder_eval_status_;
};
} // namespace kudu