/** * 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 { 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 &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::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 &get_sort_columns() const { return sort_columns_; } inline const common::ObIArray &get_sort_extra_infos() const { return extra_infos_; } inline common::ObIArray &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 *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 &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 sort_columns_; ObSqlExpression separator_param_expr_; int64_t real_param_col_count_; public: common::ObFixedArray aggr_cs_types_; protected: int64_t output_column_count_; common::ObFixedArray 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 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 &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 &src_exprs, common::ObIArray &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 static int make_expr(ObPhysicalPlan *physical_plan, T *&expr); }; } // end namespace sql } // end namespace oceanbase #endif /* OCEANBASE_SQL_ENGINE_EXPR_SQL_EXPRESSION_H_ */