init push
This commit is contained in:
151
src/sql/optimizer/ob_opt_est_utils.h
Normal file
151
src/sql/optimizer/ob_opt_est_utils.h
Normal file
@ -0,0 +1,151 @@
|
||||
/**
|
||||
* 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_OPTIMIZER_OB_OPT_EST_UTILS_
|
||||
#define OCEANBASE_SQL_OPTIMIZER_OB_OPT_EST_UTILS_
|
||||
#include "sql/resolver/expr/ob_raw_expr.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace share {
|
||||
namespace schema {
|
||||
class ObSchemaGetterGuard;
|
||||
}
|
||||
} // namespace share
|
||||
namespace sql {
|
||||
class ObLogPlan;
|
||||
class ObEstSelInfo;
|
||||
class ObSQLSessionInfo;
|
||||
class ObOptimizerContext;
|
||||
struct RangeExprs {
|
||||
RangeExprs() : table_id_(common::OB_INVALID_ID), column_id_(common::OB_INVALID_ID), range_exprs_()
|
||||
{}
|
||||
TO_STRING_KV(K_(table_id), K_(column_id));
|
||||
uint64_t table_id_;
|
||||
uint64_t column_id_;
|
||||
common::ObSEArray<ObRawExpr*, 2, common::ModulePageAllocator, true> range_exprs_;
|
||||
};
|
||||
|
||||
class ObOptEstUtils {
|
||||
public:
|
||||
// check if op is monotonic, some type may not considered.
|
||||
static bool is_monotonic_op(const ObItemType type);
|
||||
|
||||
//@brief expr is cmp_op , has is_range_cond flag or is simple op_and,op_or
|
||||
// such as, c1 > 1 and c1 < 2, c1 between 1 and 1000, c1 > 100 or c1 < 10000
|
||||
//@param in qual
|
||||
//@param out is_range
|
||||
static int is_range_expr(const ObRawExpr* qual, bool& is_simple_filter, const int64_t level = 0);
|
||||
|
||||
// extract column exprs with simple operator check.
|
||||
// level must be initialized with 0(default value)
|
||||
static int extract_column_exprs_with_op_check(const ObRawExpr* raw_expr,
|
||||
common::ObIArray<const ObRawExpr*>& column_exprs, bool& only_monotonic_op, const int64_t level = 0);
|
||||
|
||||
//@brief according different column, generate one or more range_exprs, push them into column_exprs_array.
|
||||
//@brief the item in range_exprs mush be is_range_expr() -> see notes below.
|
||||
//@param qual the expr need be dealed with
|
||||
//@param out can_be_extracted, if the expr can be extracted range here
|
||||
//@param out column_exprs_array, if generate new range_expr, pushed it into this array
|
||||
static int extract_simple_cond_filters(
|
||||
ObRawExpr& qual, bool& can_be_extracted, common::ObIArray<RangeExprs>& column_exprs_array);
|
||||
|
||||
// is_calculable_expr:is PARAM with param idx[0, param_count) or const value, or calculable
|
||||
static bool is_calculable_expr(const ObRawExpr& expr, const int64_t param_count);
|
||||
|
||||
// get the expr's value.
|
||||
//@@param get_value[out]:is_calculable_expr:true, otherwise:false
|
||||
//@@param value[out]:the value of calculable expr
|
||||
static int get_expr_value(const ParamStore* params, const ObRawExpr& expr, ObSQLSessionInfo* session,
|
||||
common::ObIAllocator& allocator, bool& get_value, common::ObObj& value);
|
||||
|
||||
// whether the value of calculable expr is null.
|
||||
static int if_expr_value_null(const ParamStore* params, const ObRawExpr& expr, ObSQLSessionInfo* session,
|
||||
common::ObIAllocator& allocator, bool& is_null);
|
||||
|
||||
// whether the like condition's patten start with '%' or '_' and not start with escape sign
|
||||
static int if_expr_start_with_patten_sign(const ParamStore* params, const ObRawExpr* expr, const ObRawExpr* esp_expr,
|
||||
ObSQLSessionInfo* session, ObIAllocator& allocator, bool& is_start_with);
|
||||
|
||||
// whether the value of first_expr and second_expr is equal.
|
||||
// if someone of the exprs is not calculable, equal return false;
|
||||
//@@param null_safe, if think NULL equal NULL, null_safe should be true, otherwise false.
|
||||
static int if_expr_value_equal(ObOptimizerContext& context, const ObDMLStmt* stmt, const ObRawExpr& first_expr,
|
||||
const ObRawExpr& second_expr, const bool null_safe, bool& equal);
|
||||
|
||||
static int is_column_primary_key(const uint64_t col_id, const uint64_t table_id,
|
||||
share::schema::ObSchemaGetterGuard& schema_guard, bool& is_unique);
|
||||
|
||||
static int is_columns_contain_primary_key(const ObIArray<uint64_t>& col_ids, uint64_t table_id,
|
||||
share::schema::ObSchemaGetterGuard& schema_guard, bool& is_unique);
|
||||
|
||||
static int columns_has_unique_subset(const ObIArray<uint64_t>& full, const ObRowkeyInfo& sub, bool& is_subset);
|
||||
};
|
||||
|
||||
class ObOptEstObjToScalar {
|
||||
public:
|
||||
// Functionality: convert objs to scalars(double).
|
||||
// One Optimization : Limited precision of double type cannot distinguish long strs using
|
||||
// a static base of 256 (max distinguishable length is 6). We need to firstly truncate the
|
||||
// common headers, then use a dynamic base to convert strings.
|
||||
//
|
||||
// Choice of dynamic base : find min and max of all chars of all given strs beyond the already
|
||||
// found common prefix length, use (max - min) as base
|
||||
//
|
||||
// When to use this optimization : all given objs (2 to 4, min and max may be NULL) are string
|
||||
// or min or max.
|
||||
//
|
||||
// If this optimization is not used, use old method to convert objs.
|
||||
static int convert_objs_to_scalars(const common::ObObj* min, const common::ObObj* max, const common::ObObj* start,
|
||||
const common::ObObj* end, common::ObObj* min_out, common::ObObj* max_out, common::ObObj* start_out,
|
||||
common::ObObj* end_out);
|
||||
/////////////Start convert obj to scalar related function//////
|
||||
// @param obj
|
||||
// @return
|
||||
static double convert_obj_to_scalar(const common::ObObj* obj);
|
||||
|
||||
// double type cannot represent min (max can be represented using Double.INF).
|
||||
// wrap conversion result as obj, so it can represent min, max, etc.
|
||||
static int convert_obj_to_scalar_obj(const common::ObObj* obj, common::ObObj* out);
|
||||
|
||||
static int convert_obj_to_double(const common::ObObj* obj, double& num);
|
||||
|
||||
static int convert_string_to_scalar_for_number(const common::ObString& str, double& scala);
|
||||
|
||||
private:
|
||||
static int add_to_string_conversion_array(
|
||||
const common::ObObj& strobj, common::ObIArray<common::ObString>& arr, uint64_t& convertable_map, int64_t pos);
|
||||
// 1, find common prefix length of strings
|
||||
// 2, find dynamix base and offset of strings
|
||||
// 3, use dynamic base and offset to convert strings to scalars
|
||||
static int convert_strings_to_scalar(
|
||||
const common::ObIArray<common::ObString>& origin_strs, common::ObIArray<double>& scalars);
|
||||
|
||||
static double convert_string_to_scalar(
|
||||
const common::ObString& str, int64_t prefix_len = 0, uint8_t offset = 0, double base = 256.0);
|
||||
|
||||
static int find_common_prefix_len(const common::ObIArray<common::ObString>& strs, int64_t& length);
|
||||
static inline void expand_range(uint8_t& min, uint8_t& max, uint8_t rmin, uint8_t rmax)
|
||||
{
|
||||
if (rmin < min) {
|
||||
min = rmin;
|
||||
}
|
||||
if (rmax > max) {
|
||||
max = rmax;
|
||||
}
|
||||
}
|
||||
|
||||
static int find_string_scalar_offset_base(
|
||||
const common::ObIArray<common::ObString>& strs, int64_t prefix_len, uint8_t& offset, double& base);
|
||||
};
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif
|
||||
Reference in New Issue
Block a user