Files
oceanbase/src/sql/engine/basic/ob_group_join_buffer.h
2023-05-10 05:51:43 +00:00

173 lines
6.7 KiB
C++

/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef OCEANBASE_BASIC_OB_GROUP_JOIN_BUFFER_H_
#define OCEANBASE_BASIC_OB_GROUP_JOIN_BUFFER_H_
#include "sql/engine/basic/ob_chunk_datum_store.h"
#include "sql/engine/ob_operator.h"
namespace oceanbase
{
namespace sql
{
struct ObBatchRowDatums
{
ObBatchRowDatums() { reset(); }
int init(const ObExprPtrIArray *exprs, common::ObIAllocator *alloc, int32_t batch_size);
void reset()
{
alloc_ = NULL;
exprs_ = NULL;
batch_size_ = 0;
datums_ = NULL;
skip_ = NULL;
size_ = 0;
saved_size_ = 0;
is_inited_ = false;
}
void clear_saved_size() { saved_size_ = 0; }
void from_exprs(ObEvalCtx &ctx, ObBitVector *skip, int64_t size);
void extend_save(ObEvalCtx &ctx, int64_t size);
void to_exprs(ObEvalCtx &ctx);
void to_exprs(ObEvalCtx &ctx, int64_t from_idx, int64_t to_idx);
ObDatum &get_datum(int64_t row_id, int64_t col_id)
{
return datums_[col_id * batch_size_ + row_id];
}
ObBitVector *get_skip() { return skip_; }
int32_t get_size() { return size_; }
bool is_inited() const { return is_inited_; }
private:
common::ObIAllocator *alloc_;
const ObExprPtrIArray *exprs_;
int32_t batch_size_;
ObDatum *datums_;
ObBitVector *skip_;
int32_t size_;
int32_t saved_size_; // record the saved size, include extend saved size
bool is_inited_;
};
class ObGroupJoinBufffer
{
public:
ObGroupJoinBufffer();
~ObGroupJoinBufffer() {} // does not free memory
int init(ObOperator *op,
const int64_t max_group_size,
const int64_t group_scan_size,
const common::ObIArray<ObDynamicParamSetter> *rescan_params,
const common::ObIArray<ObDynamicParamSetter> *left_rescan_params,
const common::ObIArray<ObDynamicParamSetter> *right_rescan_params);
bool is_inited() const { return is_inited_; }
bool is_full() const { return left_store_.get_row_cnt() >= group_scan_size_; }
bool need_fill_group_buffer() { return !(left_store_iter_.is_valid() && left_store_iter_.has_next()); }
bool is_multi_level() const { return is_multi_level_; }
int has_next_left_row(bool &has_next);
int init_above_group_params();
int fill_cur_row_group_param();
int drain_left();
int rescan_left();
int rescan_right();
int fill_group_buffer();
int batch_fill_group_buffer(const int64_t max_row_cnt, const ObBatchRows *&batch_rows);
int get_next_row_from_store();
int get_next_batch_from_store(int64_t max_rows, int64_t &read_rows);
ObBatchRowDatums &get_last_batch() { return last_batch_; }
void destroy();
private:
int init_group_params();
int deep_copy_dynamic_obj();
int bind_group_params_to_store();
int prepare_rescan_params();
int get_next_left_iter();
int add_row_to_store();
int build_above_group_params(const common::ObIArray<ObDynamicParamSetter> &above_rescan_params,
common::ObIArray<ObSqlArrayObj *> &above_group_params,
int64_t &group_size);
int set_above_group_size();
void reset_buffer_state();
int backup_above_params(common::ObIArray<ObObjParam> &left_params_backup,
common::ObIArray<ObObjParam> &right_params_backup);
int restore_above_params(common::ObIArray<ObObjParam> &left_params_backup,
common::ObIArray<ObObjParam> &right_params_backup);
private:
ObOperator *op_;
const ObOpSpec *spec_;
ObExecContext *ctx_;
ObEvalCtx *eval_ctx_;
ObOperator *left_;
ObOperator * right_;
const common::ObIArray<ObDynamicParamSetter> *rescan_params_;
const common::ObIArray<ObDynamicParamSetter> *left_rescan_params_;
const common::ObIArray<ObDynamicParamSetter> *right_rescan_params_;
lib::MemoryContext mem_context_; // for dynamic param copying, will reset after each group rescan
// buffer for rows read from left child
ObChunkDatumStore left_store_;
ObChunkDatumStore::Iterator left_store_iter_;
// for multi level batch rescan
// NLJ 1
// / \
// TSC 1 NLJ 2
// / \
// TSC 2 TSC 3
// During NLJ 2's rescan, NLJ 1 may have supplied a batch of params to TSC 2 and TSC 3.
// Thus, NLJ 2 need to keep track of NLJ 1's batch rescan pace and make sure only output
// rows corresponding to NLJ 2's current rescan.
//
// store batch index corresponding to NLJ above this op
common::ObSEArray<int64_t, 2> left_store_group_idx_;
// for NLJ 2, above_left_batch_params_ stores batch rescan params used by TSC 2 and supplied by NLJ 1
common::ObSEArray<ObSqlArrayObj *, 2> above_left_group_params_;
// for NLJ 2, above_right_batch_params_ stores batch rescan params used by TSC 3 and supplied by NLJ 1
common::ObSEArray<ObSqlArrayObj *, 2> above_right_group_params_;
// batch rescan params supplied by this op
common::ObArrayWrap<ObSqlArrayObj> group_params_;
// for NLJ 2, we need to rewrite params in above_right_batch_params_ and align them with our rescan pace,
// above_bnlj_params_ stores batch params supplied by NLJ 1 and overwritten by NLJ 2
common::ObArrayWrap<ObSqlArrayObj> above_group_params_;
ObChunkDatumStore::ShadowStoredRow last_row_;
ObBatchRowDatums last_batch_;
int64_t right_cnt_;
int64_t cur_group_idx_;
// rows read from left_store_iter_
int64_t left_store_read_;
// index used when filling group buffer,
// see fill_group_buffer() and batch_fill_group_buffer()
int64_t above_group_idx_for_expand_;
// index used when reading from right child,
// see get_next_row_from_store() and get_next_batch_from_store()
int64_t above_group_idx_for_read_;
int64_t above_group_size_;
int64_t max_group_size_;
int64_t group_scan_size_;
union {
uint64_t flags_;
struct {
uint64_t is_inited_ : 1;
uint64_t need_check_above_ : 1;
uint64_t is_multi_level_ : 1;
uint64_t is_left_end_ : 1;
uint64_t save_last_row_ : 1;
uint64_t save_last_batch_ : 1;
uint64_t skip_rescan_right_ : 1;
uint64_t reserved_ : 57;
};
};
};
} // end namespace sql
} // end namespace oceanbase
#endif // OCEANBASE_BASIC_OB_GROUP_JOIN_BUFFER_H_