Files
oceanbase/src/sql/engine/expr/ob_sql_expression.h
2023-02-07 00:40:02 +08:00

413 lines
16 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_SQL_ENGINE_EXPR_SQL_EXPRESSION_H_
#define OCEANBASE_SQL_ENGINE_EXPR_SQL_EXPRESSION_H_
#include "common/object/ob_object.h"
#include "common/row/ob_row.h"
#include "share/ob_i_sql_expression.h"
#include "sql/engine/expr/ob_postfix_expression.h"
#include "sql/engine/expr/ob_infix_expression.h"
#include "sql/engine/expr/ob_sql_expression_factory.h"
#include "sql/engine/sort/ob_base_sort.h"
#include "sql/engine/ob_operator.h" // ObOpSchemaObj
class ObAggregateFunctionTest;
// 这个宏由于expr的构造需要传参,暂时没统一
#define OB_UNIS_DECODE_EXPR_DLIST(Type, expr_list, phy_plan) \
do { \
int64_t list_count = 0; \
OB_UNIS_DECODE(list_count); \
if (OB_UNLIKELY(list_count < 0)) { \
} else { \
for (int64_t i = 0; OB_SUCC(ret) && i < list_count; ++i) { \
Type *p = NULL; \
if (OB_FAIL(ObSqlExpressionUtil::make_sql_expr((phy_plan), p))) { \
LOG_WARN("make sql expr failed", K(i), K(list_count), K(ret)); \
} else if (OB_ISNULL(p)) { \
ret = OB_BAD_NULL_ERROR; \
LOG_WARN("sql expr is null", K(i), K(list_count), K(ret)); \
} else if (OB_FAIL(p->deserialize(buf, data_len, pos))) { \
LOG_WARN("deserialize expr failed", K(i), K(list_count), K(ret)); \
} else { \
if (!(expr_list).add_last(p)) { \
ret = OB_ERR_UNEXPECTED; \
LOG_WARN("add expr list failed", K(i), K(list_count), K(ret)); \
} \
} \
} \
} \
} while(0)
namespace oceanbase
{
namespace sql
{
class ObPhysicalPlan;
class ObSqlExpression: public common::ObISqlExpression, public common::ObDLinkBase<ObSqlExpression>
{
OB_UNIS_VERSION_V(1);
public:
enum ExpressionType
{
EXPR_TYPE_SQL = 0,
EXPR_TYPE_COLUMN,
EXPR_TYPE_AGGREGATE,
EXPR_TYPE_MAX
};
public:
ObSqlExpression(common::ObIAllocator &alloc, int64_t item_count = 0);
virtual ~ObSqlExpression();
int assign(const ObSqlExpression &other);
int set_item_count(int64_t count);
inline void set_need_construct_binding_array(bool need_construct) { need_construct_binding_array_ = need_construct; }
inline bool need_construct_binding_array() const { return need_construct_binding_array_; }
inline int64_t get_array_param_index() const { return array_param_index_; }
/**
common::ObIAllocator &alloc, * 设置表达式
* @param expr [in] 表达式,表达方式与实现相关,目前定义为后缀表达式
*
* @return error code
*/
virtual int add_expr_item(const ObPostExprItem &item, const ObRawExpr *raw_expr = nullptr);
inline const ObSqlFixedArray<ObInfixExprItem> &get_expr_items() const
{
return infix_expr_.get_exprs();
}
virtual void reset();
virtual void start_gen_infix_exr() { gen_infix_expr_ = true; }
bool is_gen_infix_expr() const { return gen_infix_expr_; }
void set_gen_infix_expr(const bool is_gen_infix_expr ) { gen_infix_expr_ = is_gen_infix_expr; }
ObInfixExpression &get_infix_expr() { return infix_expr_; }
bool is_equijoin_cond(int64_t &c1, int64_t &c2,
common::ObObjType &cmp_type, common::ObCollationType &cmp_cs_type,
bool &is_null_safe) const;
/**
* 根据表达式语义对row的值进行计算
*
* @param row [in] 输入行
* @param result [out] 计算结果
*
* @return error code
*/
virtual int calc(common::ObExprCtx &expr_ctx, const common::ObNewRow &row,
common::ObObj &result) const;
virtual int calc(common::ObExprCtx &expr_ctx, const common::ObNewRow &row1,
const common::ObNewRow &row2,
common::ObObj &result) const;
TO_STRING_KV(K_(infix_expr), K_(post_expr), K_(gen_infix_expr), KP(expr_));
// check expression type
int generate_idx_for_regexp_ops(int16_t &cur_regexp_op_count);
inline bool is_empty() const;
virtual int32_t get_type() const { return ObSqlExpression::EXPR_TYPE_SQL; }
inline void set_fast_expr(ObFastExprOperator *fast_expr) { fast_expr_ = fast_expr; }
bool is_use_jitted_expr() const
{
return false;
}
void set_is_pl_mock_default_expr(bool v) { is_pl_mock_default_expr_ = v; }
bool get_is_pl_mock_default_expr() const { return is_pl_mock_default_expr_; }
void set_expr(const ObExpr *expr) { expr_ = expr; }
virtual const ObExpr *get_expr() const override { return expr_; }
private:
DISALLOW_COPY_AND_ASSIGN(ObSqlExpression);
protected:
friend class ::ObAggregateFunctionTest;
common::ObIAllocator &inner_alloc_;
// data members
ObPostfixExpression post_expr_;
//fast expr目前不序列化,不在远端执行
ObFastExprOperator *fast_expr_;
ObInfixExpression infix_expr_;
int32_t array_param_index_;
bool need_construct_binding_array_;
// used for infix generation, no need to serialize
bool gen_infix_expr_;
// expression for static engine, only used in PL
bool is_pl_mock_default_expr_;
const ObExpr *expr_;
};
inline void ObSqlExpression::reset(void)
{
common::ObDLinkBase<ObSqlExpression>::reset();
post_expr_.reset();
fast_expr_ = NULL;
gen_infix_expr_ = false;
infix_expr_.reset();
need_construct_binding_array_ = false;
array_param_index_ = common::OB_INVALID_INDEX;
}
inline bool ObSqlExpression::is_empty() const
{
return infix_expr_.is_empty() && post_expr_.is_empty();
}
class ObColumnExpression: public ObSqlExpression, public common::ObIColumnExpression
{
OB_UNIS_VERSION_V(1);
public:
ObColumnExpression(common::ObIAllocator &alloc, int64_t item_count = 0);
virtual ~ObColumnExpression();
int assign(const ObColumnExpression &other);
void set_result_index(int64_t index) { result_index_ = index; }
inline int64_t get_result_index() const { return result_index_; }
inline void set_collation_type(common::ObCollationType cs_type) { cs_type_ = cs_type; }
inline common::ObCollationType get_collation_type() const { return cs_type_; }
inline void set_accuracy(const common::ObAccuracy &accuracy) { accuracy_.set_accuracy(accuracy); }
inline const common::ObAccuracy &get_accuracy() const { return accuracy_; }
int calc_and_project(common::ObExprCtx &expr_ctx, common::ObNewRow &row) const;
virtual void reset();
virtual int32_t get_type() const { return ObSqlExpression::EXPR_TYPE_COLUMN; }
int64_t to_string(char *buf, const int64_t buf_len) const;
private:
DISALLOW_COPY_AND_ASSIGN(ObColumnExpression);
protected:
int64_t result_index_; //result's index in output row
common::ObCollationType cs_type_;
common::ObAccuracy accuracy_;
};
inline void ObColumnExpression::reset()
{
ObSqlExpression::reset();
cs_type_ = common::CS_TYPE_INVALID;
}
class ObAggregateExpression: public ObColumnExpression
{
OB_UNIS_VERSION_V(1);
public:
ObAggregateExpression(common::ObIAllocator &alloc, int64_t item_count = 0);
virtual ~ObAggregateExpression();
int assign(const ObAggregateExpression &other);
virtual void reset();
virtual int32_t get_type() const { return ObSqlExpression::EXPR_TYPE_AGGREGATE; }
virtual int calc(common::ObExprCtx &expr_ctx, const common::ObNewRow &row,
common::ObObj &result) const;
virtual int calc(common::ObExprCtx &expr_ctx,
const common::ObNewRow &row1,
const common::ObNewRow &row2,
common::ObObj &result) const;
int calc_result_row(common::ObExprCtx &expr_ctx,
const common::ObNewRow &row,
common::ObNewRow &result_row) const;
int64_t to_string(char *buf, const int64_t buf_len) const;
inline void set_aggr_func(ObItemType aggr_fun, bool is_distinct);
inline int get_aggr_column(ObItemType &aggr_fun, bool &is_distinct,
common::ObCollationType &cs_type) const;
inline int add_separator_param_expr_item(const ObPostExprItem &item, const ObRawExpr *raw_expr)
{ return separator_param_expr_.add_expr_item(item, raw_expr); }
inline const ObSqlExpression &get_separator_param_expr() const { return separator_param_expr_; }
// 不包括sort column的真正param的列数
inline void set_real_param_col_count(int64_t real_param_col_count) { real_param_col_count_ = real_param_col_count; }
inline int64_t get_real_param_col_count() const { return real_param_col_count_; }
// 包括sort column的所有param的列数
inline void set_all_param_col_count(int64_t all_param_col_count) { output_column_count_ = all_param_col_count; }
inline int64_t get_all_param_col_count() const { return output_column_count_; }
int init_sort_column_count(int64_t count) { return sort_columns_.init(count); }
int init_sort_extra_infos_(int64_t count) { return extra_infos_.init(count); }
int add_sort_column(const int64_t index,
common::ObCollationType cs_type,
bool is_ascending);
inline const common::ObIArray<ObSortColumn> &get_sort_columns() const { return sort_columns_; }
inline const common::ObIArray<ObOpSchemaObj> &get_sort_extra_infos() const { return extra_infos_; }
inline common::ObIArray<ObOpSchemaObj> &get_sort_extra_infos() { return extra_infos_; }
inline ObItemType get_aggr_func() const { return aggr_func_; }
int init_aggr_cs_type_count(int64_t count) { return aggr_cs_types_.init(count); }
int add_aggr_cs_type(common::ObCollationType cs_type) { return aggr_cs_types_.push_back(cs_type); }
const common::ObIArray<common::ObCollationType> *get_aggr_cs_types() const { return &aggr_cs_types_; }
virtual void start_gen_infix_exr() {
gen_infix_expr_ = true;
separator_param_expr_.start_gen_infix_exr();
window_size_param_expr_.start_gen_infix_exr();
item_size_param_expr_.start_gen_infix_exr();
bucket_num_expr_.start_gen_infix_exr();
}
inline int add_window_size_param_expr_item(const ObPostExprItem &item,
const ObRawExpr *raw_expr) {
return window_size_param_expr_.add_expr_item(item, raw_expr); }
inline const ObSqlExpression &get_window_size_param_expr() const {
return window_size_param_expr_; }
inline int add_item_size_param_expr_item(const ObPostExprItem &item, const ObRawExpr *raw_expr) {
return item_size_param_expr_.add_expr_item(item, raw_expr); }
inline const ObSqlExpression &get_item_size_param_expr() const {
return item_size_param_expr_; }
void set_is_need_deserialize_row(bool is_need) {
is_need_deserialize_row_ = is_need;
}
bool is_need_deserialize_row() const {
return is_need_deserialize_row_;
}
void set_pl_agg_udf_type_id(int64_t type_id) { pl_agg_udf_type_id_ = type_id; }
int64_t get_pl_agg_udf_type_id() const { return pl_agg_udf_type_id_; }
inline void set_result_type(ObExprResType result_type) { result_type_ = result_type; }
inline ObExprResType get_result_type() const { return result_type_; }
int init_pl_agg_udf_params_type_count(int64_t count) {
return pl_agg_udf_params_type_.init(count); }
int add_pl_agg_udf_param_type(ObExprResType type) {
return pl_agg_udf_params_type_.push_back(type); }
const common::ObIArray<ObExprResType> &get_pl_agg_udf_params_type() const {
return pl_agg_udf_params_type_; }
inline int add_bucket_num_expr_item(const ObPostExprItem &item, const ObRawExpr *raw_expr) {
return bucket_num_expr_.add_expr_item(item, raw_expr); }
inline const ObSqlExpression &get_bucket_num_expr() const {
return bucket_num_expr_; }
private:
DISALLOW_COPY_AND_ASSIGN(ObAggregateExpression);
protected:
ObItemType aggr_func_;
bool is_distinct_;
common::ObFixedArray<ObSortColumn, common::ObIAllocator> sort_columns_;
ObSqlExpression separator_param_expr_;
int64_t real_param_col_count_;
public:
common::ObFixedArray<common::ObCollationType, common::ObIAllocator> aggr_cs_types_;
protected:
int64_t output_column_count_;
common::ObFixedArray<ObOpSchemaObj, common::ObIAllocator> extra_infos_;//支持NULLs FIRST
protected:
ObSqlExpression window_size_param_expr_;
ObSqlExpression item_size_param_expr_;
bool is_need_deserialize_row_;
protected:
int64_t pl_agg_udf_type_id_;
common::ObFixedArray<ObExprResType, common::ObIAllocator> pl_agg_udf_params_type_;
ObExprResType result_type_;
ObSqlExpression bucket_num_expr_;
};
inline void ObAggregateExpression::reset()
{
ObColumnExpression::reset();
aggr_func_ = ::T_INVALID;
is_distinct_ = false;
sort_columns_.reset();
//separator_param_idx_ = common::OB_INVALID_INDEX;
separator_param_expr_.reset();
real_param_col_count_ = 0;
aggr_cs_types_.reset();
window_size_param_expr_.reset();
item_size_param_expr_.reset();
is_need_deserialize_row_ = false;
pl_agg_udf_type_id_ = common::OB_INVALID_ID;
pl_agg_udf_params_type_.reset();
result_type_.reset();
bucket_num_expr_.reset();
}
inline void ObAggregateExpression::set_aggr_func(ObItemType aggr_func, bool is_distinct)
{
aggr_func_ = aggr_func;
is_distinct_ = is_distinct;
}
inline int ObAggregateExpression::get_aggr_column(ObItemType &aggr_fun,
bool &is_distinct,
common::ObCollationType &cs_type) const
{
int ret = common::OB_SUCCESS;
aggr_fun = aggr_func_;
is_distinct = is_distinct_;
cs_type = cs_type_;
return ret;
}
// ObExprOperatorFetcher is used fetch the ObExprOperator of ObExprGeneratorImpl.
// only override the add_expr_item.
struct ObExprOperatorFetcher: public ObSqlExpression
{
public:
ObExprOperatorFetcher()
// the allocator is never used
: ObSqlExpression(*lib::ObMallocAllocator::get_instance(), 0), op_(NULL)
{}
virtual int add_expr_item(const ObPostExprItem &item, const ObRawExpr *raw_expr) override
{
UNUSED(raw_expr);
int ret = common::OB_SUCCESS;
if (IS_EXPR_OP(item.get_item_type())) {
if (NULL != op_) {
ret = common::OB_ERR_UNEXPECTED;
SQL_ENG_LOG(WARN, "only one expr operator expected", K(ret));
} else {
op_ = item.get_expr_operator();
}
} else {
op_ = NULL;
}
return ret;
}
void reset() { op_ = NULL; }
const ObExprOperator *op_;
};
class ObSqlExpressionUtil
{
public:
static int make_sql_expr(ObPhysicalPlan *physical_plan, ObSqlExpression *&expr);
static int make_sql_expr(ObPhysicalPlan *physical_plan, ObColumnExpression *&expr);
static int make_sql_expr(ObPhysicalPlan *physical_plan, ObAggregateExpression *&expr);
static int add_expr_to_list(common::ObDList<ObSqlExpression> &list, ObSqlExpression *expr);
static int copy_sql_expression(ObSqlExpressionFactory &sql_expression_factory,
const ObSqlExpression *src_expr,
ObSqlExpression *&dst_expr);
static int copy_sql_expressions(ObSqlExpressionFactory &sql_expression_factory,
const common::ObIArray<ObSqlExpression *> &src_exprs,
common::ObIArray<ObSqlExpression *> &dst_exprs);
static int expand_array_params(common::ObExprCtx &expr_ctx,
const common::ObObj &src_param,
const common::ObObj *&result);
private:
DISALLOW_COPY_AND_ASSIGN(ObSqlExpressionUtil);
ObSqlExpressionUtil();
~ObSqlExpressionUtil();
template <class T>
static int make_expr(ObPhysicalPlan *physical_plan, T *&expr);
};
} // end namespace sql
} // end namespace oceanbase
#endif /* OCEANBASE_SQL_ENGINE_EXPR_SQL_EXPRESSION_H_ */