[FEAT MERGE] Lob SQL refactoring (Mem-LobLocator, expressions and dbms_lob adaptions)

Co-authored-by: chaser-ch <chaser.ch@antgroup.com>
This commit is contained in:
obdev
2023-01-28 20:40:15 +08:00
committed by ob-robot
parent 4bb1033505
commit 3d4f554258
350 changed files with 19091 additions and 3918 deletions

View File

@ -17,6 +17,7 @@
#include "share/datum/ob_datum_funcs.h"
#include "sql/engine/expr/ob_expr_operator.h"
#include "sql/engine/expr/ob_batch_eval_util.h"
#include "share/ob_lob_access_utils.h"
namespace oceanbase
{
@ -182,7 +183,6 @@ struct ObRelationalStrFunc<true, CS_TYPE, WITH_END_SPACE, CMP_OP>
// }
};
template<bool, ObScale SCALE, ObCmpOp CMP_OP>
struct ObRelationFixedDoubleFunc{};
@ -212,6 +212,130 @@ struct ObRelationFixedDoubleFunc<true, SCALE, CMP_OP>
}
};
template<bool, ObCollationType CS_TYPE, bool WITH_END_SPACE, ObCmpOp CMP_OP>
struct ObRelationalTextFunc{};
template<ObCollationType CS_TYPE, bool WITH_END_SPACE, ObCmpOp CMP_OP>
struct ObRelationalTextFunc<false, CS_TYPE, WITH_END_SPACE, CMP_OP> : ObDummyRelationalFunc {};
template<ObCollationType CS_TYPE, bool WITH_END_SPACE, ObCmpOp CMP_OP>
struct ObRelationalTextFunc<true, CS_TYPE, WITH_END_SPACE, CMP_OP>
{
struct DatumCmp
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r) const
{
res.set_int(get_cmp_ret<CMP_OP>(
datum_cmp::ObDatumTextCmp<CS_TYPE, WITH_END_SPACE>::cmp(l, r)));
return OB_SUCCESS;
}
};
inline static int eval(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum)
{
return def_relational_eval_func<DatumCmp>(expr, ctx, expr_datum);
}
};
template<bool, ObCollationType CS_TYPE, bool WITH_END_SPACE, ObCmpOp CMP_OP>
struct ObRelationalTextStrFunc{};
template<ObCollationType CS_TYPE, bool WITH_END_SPACE, ObCmpOp CMP_OP>
struct ObRelationalTextStrFunc<false, CS_TYPE, WITH_END_SPACE, CMP_OP> : ObDummyRelationalFunc {};
template<ObCollationType CS_TYPE, bool WITH_END_SPACE, ObCmpOp CMP_OP>
struct ObRelationalTextStrFunc<true, CS_TYPE, WITH_END_SPACE, CMP_OP>
{
struct DatumCmp
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r) const
{
res.set_int(get_cmp_ret<CMP_OP>(
datum_cmp::ObDatumTextStringCmp<CS_TYPE, WITH_END_SPACE>::cmp(l, r)));
return OB_SUCCESS;
}
};
inline static int eval(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum)
{
return def_relational_eval_func<DatumCmp>(expr, ctx, expr_datum);
}
};
template<bool, ObCollationType CS_TYPE, bool WITH_END_SPACE, ObCmpOp CMP_OP>
struct ObRelationalStrTextFunc{};
template<ObCollationType CS_TYPE, bool WITH_END_SPACE, ObCmpOp CMP_OP>
struct ObRelationalStrTextFunc<false, CS_TYPE, WITH_END_SPACE, CMP_OP> : ObDummyRelationalFunc {};
template<ObCollationType CS_TYPE, bool WITH_END_SPACE, ObCmpOp CMP_OP>
struct ObRelationalStrTextFunc<true, CS_TYPE, WITH_END_SPACE, CMP_OP>
{
struct DatumCmp
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r) const
{
res.set_int(get_cmp_ret<CMP_OP>(
datum_cmp::ObDatumStringTextCmp<CS_TYPE, WITH_END_SPACE>::cmp(l, r)));
return OB_SUCCESS;
}
};
inline static int eval(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum)
{
return def_relational_eval_func<DatumCmp>(expr, ctx, expr_datum);
}
};
template<bool, bool HAS_LOB_HEADER, ObCmpOp CMP_OP>
struct ObRelationalJsonFunc{};
template<bool HAS_LOB_HEADER, ObCmpOp CMP_OP>
struct ObRelationalJsonFunc<false, HAS_LOB_HEADER, CMP_OP> : ObDummyRelationalFunc {};
template<bool HAS_LOB_HEADER, ObCmpOp CMP_OP>
struct ObRelationalJsonFunc<true, HAS_LOB_HEADER, CMP_OP>
{
struct DatumCmp
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r) const
{
res.set_int(get_cmp_ret<CMP_OP>(
datum_cmp::ObDatumJsonCmp<HAS_LOB_HEADER>::cmp(l, r)));
return OB_SUCCESS;
}
};
inline static int eval(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum)
{
return def_relational_eval_func<DatumCmp>(expr, ctx, expr_datum);
}
};
template<bool, bool HAS_LOB_HEADER, ObCmpOp CMP_OP>
struct ObRelationalGeoFunc{};
template<bool HAS_LOB_HEADER, ObCmpOp CMP_OP>
struct ObRelationalGeoFunc<false, HAS_LOB_HEADER, CMP_OP> : ObDummyRelationalFunc {};
template<bool HAS_LOB_HEADER, ObCmpOp CMP_OP>
struct ObRelationalGeoFunc<true, HAS_LOB_HEADER, CMP_OP>
{
struct DatumCmp
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r) const
{
res.set_int(get_cmp_ret<CMP_OP>(
datum_cmp::ObDatumGeoCmp<HAS_LOB_HEADER>::cmp(l, r)));
return OB_SUCCESS;
}
};
inline static int eval(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum)
{
return def_relational_eval_func<DatumCmp>(expr, ctx, expr_datum);
}
};
// define null, extend, string evaluate batch functions.
template<ObCmpOp CMP_OP>
@ -269,11 +393,209 @@ struct ObRelationalExtraFunc
expr.args_[0]->datum_meta_.cs_type_,
with_end_space);
}
struct TextCmp
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r,
const ObCollationType cs_type, bool with_end_space) const
{
int ret = OB_SUCCESS;
ObString l_data;
ObString r_data;
ObTextStringIter l_instr_iter(ObLongTextType, cs_type, l.get_string(), true);
ObTextStringIter r_instr_iter(ObLongTextType, cs_type, r.get_string(), true);
common::ObArenaAllocator allocator(ObModIds::OB_LOB_READER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID());
if (OB_FAIL(l_instr_iter.init(0, NULL, &allocator))) {
COMMON_LOG(WARN, "Lob: init left text str iter failed", K(ret), K(cs_type), K(l));
} else if (OB_FAIL(l_instr_iter.get_full_data(l_data))) {
COMMON_LOG(WARN, "Lob: get left text str iter full data failed ", K(ret), K(cs_type), K(l_instr_iter));
} else if (OB_FAIL(r_instr_iter.init(0, NULL, &allocator))) {
COMMON_LOG(WARN, "Lob: init right text str iter failed", K(ret), K(ret), K(r));
} else if (OB_FAIL(r_instr_iter.get_full_data(r_data))) {
COMMON_LOG(WARN, "Lob: get right text str iter full data failed ", K(ret), K(cs_type), K(r_instr_iter));
} else {
int cmp_ret = ObCharset::strcmpsp(cs_type, l_data.ptr(), l_data.length(),
r_data.ptr(), r_data.length(), with_end_space);
res.set_int(get_cmp_ret<CMP_OP>(cmp_ret > 0 ? 1 : (cmp_ret < 0 ? -1 : 0)));
}
return ret;
}
};
inline static int text_eval_batch(BATCH_EVAL_FUNC_ARG_DECL)
{
bool with_end_space = is_calc_with_end_space(
expr.args_[0]->datum_meta_.type_,
expr.args_[1]->datum_meta_.type_,
lib::is_oracle_mode(),
expr.args_[0]->datum_meta_.cs_type_,
expr.args_[1]->datum_meta_.cs_type_);
return def_relational_eval_batch_func<TextCmp>(BATCH_EVAL_FUNC_ARG_LIST,
expr.args_[0]->datum_meta_.cs_type_,
with_end_space);
}
struct TextStrCmp
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r,
const ObCollationType cs_type, bool with_end_space) const
{
int ret = OB_SUCCESS;
ObString l_data;
ObTextStringIter l_instr_iter(ObLongTextType, cs_type, l.get_string(), true);
common::ObArenaAllocator allocator(ObModIds::OB_LOB_READER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID());
if (OB_FAIL(l_instr_iter.init(0, NULL, &allocator))) {
COMMON_LOG(WARN, "Lob: init left text str iter failed", K(ret), K(cs_type), K(l));
} else if (OB_FAIL(l_instr_iter.get_full_data(l_data))) {
COMMON_LOG(WARN, "Lob: get left text str iter full data failed ", K(ret), K(cs_type), K(l_instr_iter));
} else {
int cmp_ret = ObCharset::strcmpsp(cs_type, l_data.ptr(), l_data.length(),
r.ptr_, r.len_, with_end_space);
res.set_int(get_cmp_ret<CMP_OP>(cmp_ret > 0 ? 1 : (cmp_ret < 0 ? -1 : 0)));
}
return ret;
}
};
inline static int text_str_eval_batch(BATCH_EVAL_FUNC_ARG_DECL)
{
bool with_end_space = is_calc_with_end_space(
expr.args_[0]->datum_meta_.type_,
expr.args_[1]->datum_meta_.type_,
lib::is_oracle_mode(),
expr.args_[0]->datum_meta_.cs_type_,
expr.args_[1]->datum_meta_.cs_type_);
return def_relational_eval_batch_func<TextStrCmp>(BATCH_EVAL_FUNC_ARG_LIST,
expr.args_[0]->datum_meta_.cs_type_,
with_end_space);
}
struct StrTextCmp
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r,
const ObCollationType cs_type, bool with_end_space) const
{
int ret = OB_SUCCESS;
ObString r_data;
ObTextStringIter r_instr_iter(ObLongTextType, cs_type, r.get_string(), true);
common::ObArenaAllocator allocator(ObModIds::OB_LOB_READER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID());
if (OB_FAIL(r_instr_iter.init(0, NULL, &allocator))) {
COMMON_LOG(WARN, "Lob: init right text str iter failed", K(ret), K(ret), K(r));
} else if (OB_FAIL(r_instr_iter.get_full_data(r_data))) {
COMMON_LOG(WARN, "Lob: get right text str iter full data failed ", K(ret), K(cs_type), K(r_instr_iter));
} else {
int cmp_ret = ObCharset::strcmpsp(cs_type, l.ptr_, l.len_,
r_data.ptr(), r_data.length(), with_end_space);
res.set_int(get_cmp_ret<CMP_OP>(cmp_ret > 0 ? 1 : (cmp_ret < 0 ? -1 : 0)));
}
return ret;
}
};
inline static int str_text_eval_batch(BATCH_EVAL_FUNC_ARG_DECL)
{
bool with_end_space = is_calc_with_end_space(
expr.args_[0]->datum_meta_.type_,
expr.args_[1]->datum_meta_.type_,
lib::is_oracle_mode(),
expr.args_[0]->datum_meta_.cs_type_,
expr.args_[1]->datum_meta_.cs_type_);
return def_relational_eval_batch_func<StrTextCmp>(BATCH_EVAL_FUNC_ARG_LIST,
expr.args_[0]->datum_meta_.cs_type_,
with_end_space);
}
struct JsonCmp
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r,
bool has_lob_header) const
{
int ret = OB_SUCCESS;
int result = 0;
ObString l_data;
ObString r_data;
common::ObArenaAllocator allocator(ObModIds::OB_LOB_READER);
ObTextStringIter l_instr_iter(ObJsonType, CS_TYPE_BINARY, l.get_string(), has_lob_header);
ObTextStringIter r_instr_iter(ObJsonType, CS_TYPE_BINARY, r.get_string(), has_lob_header);
if (OB_FAIL(l_instr_iter.init(0, NULL, &allocator))) {
COMMON_LOG(WARN, "LobDebug: init left lob str iter failed", K(ret), K(l));
} else if (OB_FAIL(l_instr_iter.get_full_data(l_data))) {
COMMON_LOG(WARN, "LobDebug: get left lob str iter full data failed ", K(ret), K(l_instr_iter));
} else if (OB_FAIL(r_instr_iter.init(0, NULL, &allocator))) {
COMMON_LOG(WARN, "LobDebug: init right lob str iter failed", K(ret), K(ret), K(r));
} else if (OB_FAIL(r_instr_iter.get_full_data(r_data))) {
COMMON_LOG(WARN, "LobDebug: get right lob str iter full data failed ", K(ret), K(r_instr_iter));
} else {
ObJsonBin j_bin_l(l_data.ptr(), l_data.length());
ObJsonBin j_bin_r(r_data.ptr(), r_data.length());
ObIJsonBase *j_base_l = &j_bin_l;
ObIJsonBase *j_base_r = &j_bin_r;
if (OB_FAIL(j_bin_l.reset_iter())) {
COMMON_LOG(WARN, "fail to reset left json bin iter", K(ret), K(l.len_));
} else if (OB_FAIL(j_bin_r.reset_iter())) {
COMMON_LOG(WARN, "fail to reset right json bin iter", K(ret), K(r.len_));
} else if (OB_FAIL(j_base_l->compare(*j_base_r, result))) {
COMMON_LOG(WARN, "fail to compare json", K(ret), K(*j_base_l), K(*j_base_r));
} else {
res.set_int(get_cmp_ret<CMP_OP>(result > 0 ? 1 : (result < 0 ? -1 : 0)));
}
}
return ret;
}
};
inline static int json_eval_batch(BATCH_EVAL_FUNC_ARG_DECL)
{
bool has_lob_header = expr.args_[0]->obj_meta_.has_lob_header();
return def_relational_eval_batch_func<JsonCmp>(BATCH_EVAL_FUNC_ARG_LIST,
has_lob_header);
}
struct GeoCmp
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r,
bool has_lob_header) const
{
int ret = OB_SUCCESS;
int result = 0;
ObString l_data;
ObString r_data;
common::ObArenaAllocator allocator(ObModIds::OB_LOB_READER);
ObTextStringIter l_instr_iter(ObJsonType, CS_TYPE_BINARY, l.get_string(), has_lob_header);
ObTextStringIter r_instr_iter(ObJsonType, CS_TYPE_BINARY, r.get_string(), has_lob_header);
if (OB_FAIL(l_instr_iter.init(0, NULL, &allocator))) {
COMMON_LOG(WARN, "LobDebug: init left lob str iter failed", K(ret), K(l));
} else if (OB_FAIL(l_instr_iter.get_full_data(l_data))) {
COMMON_LOG(WARN, "LobDebug: get left lob str iter full data failed ", K(ret), K(l_instr_iter));
} else if (OB_FAIL(r_instr_iter.init(0, NULL, &allocator))) {
COMMON_LOG(WARN, "LobDebug: init right lob str iter failed", K(ret), K(ret), K(r));
} else if (OB_FAIL(r_instr_iter.get_full_data(r_data))) {
COMMON_LOG(WARN, "LobDebug: get right lob str iter full data failed ", K(ret), K(r_instr_iter));
} else {
result = ObCharset::strcmpsp(CS_TYPE_BINARY, l_data.ptr(), l_data.length(), r_data.ptr(), r_data.length(), false);
res.set_int(get_cmp_ret<CMP_OP>(result > 0 ? 1 : (result < 0 ? -1 : 0)));
}
return ret;
}
};
inline static int geo_eval_batch(BATCH_EVAL_FUNC_ARG_DECL)
{
bool has_lob_header = expr.args_[0]->obj_meta_.has_lob_header();
return def_relational_eval_batch_func<GeoCmp>(BATCH_EVAL_FUNC_ARG_LIST,
has_lob_header);
}
};
static ObExpr::EvalBatchFunc EVAL_BATCH_NULL_EXTEND_CMP_FUNCS[CO_MAX];
static ObExpr::EvalBatchFunc EVAL_BATCH_STR_CMP_FUNCS[CO_MAX];
static ObExpr::EvalBatchFunc EVAL_BATCH_TEXT_CMP_FUNCS[CO_MAX];
static ObExpr::EvalBatchFunc EVAL_BATCH_TEXT_STR_CMP_FUNCS[CO_MAX];
static ObExpr::EvalBatchFunc EVAL_BATCH_STR_TEXT_CMP_FUNCS[CO_MAX];
static ObExpr::EvalBatchFunc EVAL_BATCH_JSON_CMP_FUNCS[CO_MAX];
static ObExpr::EvalBatchFunc EVAL_BATCH_GEO_CMP_FUNCS[CO_MAX];
static ObExpr::EvalFunc EVAL_TYPE_CMP_FUNCS[ObMaxType][ObMaxType][CO_MAX];
static ObExpr::EvalBatchFunc EVAL_BATCH_TYPE_CMP_FUNCS[ObMaxType][ObMaxType][CO_MAX];
@ -286,6 +608,16 @@ static ObDatumCmpFuncType DATUM_TC_CMP_FUNCS[ObMaxTC][ObMaxTC];
static ObExpr::EvalFunc EVAL_STR_CMP_FUNCS[CS_TYPE_MAX][CO_MAX][2];
static ObDatumCmpFuncType DATUM_STR_CMP_FUNCS[CS_TYPE_MAX][2];
static ObExpr::EvalFunc EVAL_TEXT_CMP_FUNCS[CS_TYPE_MAX][CO_MAX][2];
static ObDatumCmpFuncType DATUM_TEXT_CMP_FUNCS[CS_TYPE_MAX][2];
static ObExpr::EvalFunc EVAL_TEXT_STR_CMP_FUNCS[CS_TYPE_MAX][CO_MAX][2];
static ObDatumCmpFuncType DATUM_TEXT_STR_CMP_FUNCS[CS_TYPE_MAX][2];
static ObExpr::EvalFunc EVAL_STR_TEXT_CMP_FUNCS[CS_TYPE_MAX][CO_MAX][2];
static ObDatumCmpFuncType DATUM_STR_TEXT_CMP_FUNCS[CS_TYPE_MAX][2];
static ObExpr::EvalFunc EVAL_JSON_CMP_FUNCS[CO_MAX][2];
static ObDatumCmpFuncType DATUM_JSON_CMP_FUNCS[2];
static ObExpr::EvalFunc EVAL_GEO_CMP_FUNCS[CO_MAX][2];
static ObDatumCmpFuncType DATUM_GEO_CMP_FUNCS[2];
static ObExpr::EvalFunc EVAL_FIXED_DOUBLE_CMP_FUNCS[OB_NOT_FIXED_SCALE][CO_MAX];
static ObExpr::EvalBatchFunc EVAL_BATCH_FIXED_DOUBLE_CMP_FUNCS[OB_NOT_FIXED_SCALE][CO_MAX];
@ -299,6 +631,11 @@ struct ExtraExprCmpIniter
using Func = ObRelationalExtraFunc<static_cast<ObCmpOp>(X)>;
EVAL_BATCH_NULL_EXTEND_CMP_FUNCS[X] = Func::null_extend_eval_batch;
EVAL_BATCH_STR_CMP_FUNCS[X] = Func::str_eval_batch;
EVAL_BATCH_TEXT_CMP_FUNCS[X] = Func::text_eval_batch;
EVAL_BATCH_TEXT_STR_CMP_FUNCS[X] = Func::text_str_eval_batch;
EVAL_BATCH_STR_TEXT_CMP_FUNCS[X] = Func::str_text_eval_batch;
EVAL_BATCH_JSON_CMP_FUNCS[X] = Func::json_eval_batch;
EVAL_BATCH_GEO_CMP_FUNCS[X] = Func::geo_eval_batch;
}
};
@ -401,6 +738,54 @@ struct StrExprFuncIniter
}
};
template<int X, int Y>
struct TextExprFuncIniter
{
using Def = datum_cmp::ObDatumTextCmp<static_cast<ObCollationType>(X), false>;
template<bool WITH_END_SPACE>
using EvalCmp = ObRelationalTextFunc<Def::defined_,
static_cast<ObCollationType>(X),
WITH_END_SPACE,
static_cast<ObCmpOp>(Y)>;
static void init_array()
{
EVAL_TEXT_CMP_FUNCS[X][Y][0] = Def::defined_ ? EvalCmp<0>::eval : NULL;
EVAL_TEXT_CMP_FUNCS[X][Y][1] = Def::defined_ ? EvalCmp<1>::eval : NULL;
}
};
template<int X, int Y>
struct TextStrExprFuncIniter
{
using Def = datum_cmp::ObDatumTextStringCmp<static_cast<ObCollationType>(X), false>;
template<bool WITH_END_SPACE>
using EvalCmp = ObRelationalTextStrFunc<Def::defined_,
static_cast<ObCollationType>(X),
WITH_END_SPACE,
static_cast<ObCmpOp>(Y)>;
static void init_array()
{
EVAL_TEXT_STR_CMP_FUNCS[X][Y][0] = Def::defined_ ? EvalCmp<0>::eval : NULL;
EVAL_TEXT_STR_CMP_FUNCS[X][Y][1] = Def::defined_ ? EvalCmp<1>::eval : NULL;
}
};
template<int X, int Y>
struct StrTextExprFuncIniter
{
using Def = datum_cmp::ObDatumStringTextCmp<static_cast<ObCollationType>(X), false>;
template<bool WITH_END_SPACE>
using EvalCmp = ObRelationalStrTextFunc<Def::defined_,
static_cast<ObCollationType>(X),
WITH_END_SPACE,
static_cast<ObCmpOp>(Y)>;
static void init_array()
{
EVAL_STR_TEXT_CMP_FUNCS[X][Y][0] = Def::defined_ ? EvalCmp<0>::eval : NULL;
EVAL_STR_TEXT_CMP_FUNCS[X][Y][1] = Def::defined_ ? EvalCmp<1>::eval : NULL;
}
};
template<int X>
struct DatumStrExprCmpIniter
{
@ -414,10 +799,115 @@ struct DatumStrExprCmpIniter
}
};
template<int X>
struct DatumTextExprCmpIniter
{
template<bool WITH_END_SPACE>
using DatumCmp = datum_cmp::ObDatumTextCmp<static_cast<ObCollationType>(X), WITH_END_SPACE>;
using Def = datum_cmp::ObDatumTextCmp<static_cast<ObCollationType>(X), false>;
static void init_array()
{
DATUM_TEXT_CMP_FUNCS[X][0] = Def::defined_ ? DatumCmp<0>::cmp : NULL;
DATUM_TEXT_CMP_FUNCS[X][1] = Def::defined_ ? DatumCmp<1>::cmp : NULL;
}
};
template<int X>
struct DatumTextStrExprCmpIniter
{
template<bool WITH_END_SPACE>
using DatumCmp = datum_cmp::ObDatumTextStringCmp<static_cast<ObCollationType>(X), WITH_END_SPACE>;
using Def = datum_cmp::ObDatumTextStringCmp<static_cast<ObCollationType>(X), false>;
static void init_array()
{
DATUM_TEXT_STR_CMP_FUNCS[X][0] = Def::defined_ ? DatumCmp<0>::cmp : NULL;
DATUM_TEXT_STR_CMP_FUNCS[X][1] = Def::defined_ ? DatumCmp<1>::cmp : NULL;
}
};
template<int X>
struct DatumStrTextExprCmpIniter
{
template<bool WITH_END_SPACE>
using DatumCmp = datum_cmp::ObDatumStringTextCmp<static_cast<ObCollationType>(X), WITH_END_SPACE>;
using Def = datum_cmp::ObDatumStringTextCmp<static_cast<ObCollationType>(X), false>;
static void init_array()
{
DATUM_STR_TEXT_CMP_FUNCS[X][0] = Def::defined_ ? DatumCmp<0>::cmp : NULL;
DATUM_STR_TEXT_CMP_FUNCS[X][1] = Def::defined_ ? DatumCmp<1>::cmp : NULL;
}
};
template<int Y>
struct JsonExprFuncIniter
{
using Def = datum_cmp::ObDatumJsonCmp<false>;
template<bool HAS_LOB_HEADER>
using EvalCmp = ObRelationalJsonFunc<Def::defined_,
HAS_LOB_HEADER,
static_cast<ObCmpOp>(Y)>;
static void init_array()
{
EVAL_JSON_CMP_FUNCS[Y][0] = Def::defined_ ? EvalCmp<0>::eval : NULL;
EVAL_JSON_CMP_FUNCS[Y][1] = Def::defined_ ? EvalCmp<1>::eval : NULL;
}
};
template<int X>
struct DatumJsonExprCmpIniter
{
template<bool HAS_LOB_HEADER>
using DatumCmp = datum_cmp::ObDatumJsonCmp<HAS_LOB_HEADER>;
using Def = datum_cmp::ObDatumJsonCmp<false>;
static void init_array()
{
DATUM_JSON_CMP_FUNCS[0] = Def::defined_ ? DatumCmp<0>::cmp : NULL;
DATUM_JSON_CMP_FUNCS[1] = Def::defined_ ? DatumCmp<1>::cmp : NULL;
}
};
template<int Y>
struct GeoExprFuncIniter
{
using Def = datum_cmp::ObDatumGeoCmp<false>;
template<bool HAS_LOB_HEADER>
using EvalCmp = ObRelationalGeoFunc<Def::defined_,
HAS_LOB_HEADER,
static_cast<ObCmpOp>(Y)>;
static void init_array()
{
EVAL_GEO_CMP_FUNCS[Y][0] = Def::defined_ ? EvalCmp<0>::eval : NULL;
EVAL_GEO_CMP_FUNCS[Y][1] = Def::defined_ ? EvalCmp<1>::eval : NULL;
}
};
template<int X>
struct DatumGeoExprCmpIniter
{
template<bool HAS_LOB_HEADER>
using DatumCmp = datum_cmp::ObDatumGeoCmp<HAS_LOB_HEADER>;
using Def = datum_cmp::ObDatumGeoCmp<false>;
static void init_array()
{
DATUM_GEO_CMP_FUNCS[0] = Def::defined_ ? DatumCmp<0>::cmp : NULL;
DATUM_GEO_CMP_FUNCS[1] = Def::defined_ ? DatumCmp<1>::cmp : NULL;
}
};
int g_init_type_ret = Ob2DArrayConstIniter<ObMaxType, ObMaxType, TypeExprCmpFuncIniter>::init();
int g_init_tc_ret = Ob2DArrayConstIniter<ObMaxTC, ObMaxTC, TCExprCmpFuncIniter>::init();
int g_init_str_ret = Ob2DArrayConstIniter<CS_TYPE_MAX, CO_MAX, StrExprFuncIniter>::init();
int g_init_datum_str_ret = ObArrayConstIniter<CS_TYPE_MAX, DatumStrExprCmpIniter>::init();
int g_init_text_ret = Ob2DArrayConstIniter<CS_TYPE_MAX, CO_MAX, TextExprFuncIniter>::init();
int g_init_datum_text_ret = ObArrayConstIniter<CS_TYPE_MAX, DatumTextExprCmpIniter>::init();
int g_init_text_str_ret = Ob2DArrayConstIniter<CS_TYPE_MAX, CO_MAX, TextStrExprFuncIniter>::init();
int g_init_datum_text_str_ret = ObArrayConstIniter<CS_TYPE_MAX, DatumTextStrExprCmpIniter>::init();
int g_init_str_text_ret = Ob2DArrayConstIniter<CS_TYPE_MAX, CO_MAX, StrTextExprFuncIniter>::init();
int g_init_str_datum_text_ret = ObArrayConstIniter<CS_TYPE_MAX, DatumStrTextExprCmpIniter>::init();
int g_init_json_ret = ObArrayConstIniter<CO_MAX, JsonExprFuncIniter>::init();
int g_init_json_datum_ret = ObArrayConstIniter<1, DatumJsonExprCmpIniter>::init();
int g_init_geo_ret = ObArrayConstIniter<CO_MAX, GeoExprFuncIniter>::init();
int g_init_geo_datum_ret = ObArrayConstIniter<1, DatumGeoExprCmpIniter>::init();
template<int X>
struct FixedDoubleCmpFuncIniter
@ -489,7 +979,8 @@ ObExpr::EvalFunc ObExprCmpFuncsHelper::get_eval_expr_cmp_func(const ObObjType ty
const ObScale scale2,
const ObCmpOp cmp_op,
const bool is_oracle_mode,
const ObCollationType cs_type)
const ObCollationType cs_type,
const bool has_lob_header)
{
OB_ASSERT(type1 >= ObNullType && type1 < ObMaxType);
OB_ASSERT(type2 >= ObNullType && type2 < ObMaxType);
@ -502,6 +993,10 @@ ObExpr::EvalFunc ObExprCmpFuncsHelper::get_eval_expr_cmp_func(const ObObjType ty
OB_UNLIKELY(ob_is_invalid_obj_tc(tc1) ||
OB_UNLIKELY(ob_is_invalid_obj_tc(tc2)))) {
func_ptr = NULL;
} else if (tc1 == ObJsonTC && tc2 == ObJsonTC) {
func_ptr = EVAL_JSON_CMP_FUNCS[cmp_op][has_lob_header];
} else if (tc1 == ObGeometryTC && tc2 == ObGeometryTC) {
func_ptr = EVAL_GEO_CMP_FUNCS[cmp_op][has_lob_header];
} else if (IS_FIXED_DOUBLE) {
func_ptr = EVAL_FIXED_DOUBLE_CMP_FUNCS[MAX(scale1, scale2)][cmp_op];
} else if (!ObDatumFuncs::is_string_type(type1) || !ObDatumFuncs::is_string_type(type2)) {
@ -510,7 +1005,17 @@ ObExpr::EvalFunc ObExprCmpFuncsHelper::get_eval_expr_cmp_func(const ObObjType ty
OB_ASSERT(cs_type > CS_TYPE_INVALID && cs_type < CS_TYPE_MAX);
int64_t calc_with_end_space_idx = (is_calc_with_end_space(type1, type2, is_oracle_mode,
cs_type, cs_type) ? 1 : 0);
func_ptr = EVAL_STR_CMP_FUNCS[cs_type][cmp_op][calc_with_end_space_idx];
if (has_lob_header && (ob_is_large_text(type1) || ob_is_large_text(type2))) {
if (ob_is_large_text(type1) && ob_is_large_text(type2)) {
func_ptr = EVAL_TEXT_CMP_FUNCS[cs_type][cmp_op][calc_with_end_space_idx];
} else if (ob_is_large_text(type1)) { // type2 not large text
func_ptr = EVAL_TEXT_STR_CMP_FUNCS[cs_type][cmp_op][calc_with_end_space_idx];
} else { // type1 not large text
func_ptr = EVAL_STR_TEXT_CMP_FUNCS[cs_type][cmp_op][calc_with_end_space_idx];
}
} else { // no lob header or tinytext use original str cmp func
func_ptr = EVAL_STR_CMP_FUNCS[cs_type][cmp_op][calc_with_end_space_idx];
}
}
return func_ptr;
}
@ -522,7 +1027,8 @@ ObExpr::EvalBatchFunc ObExprCmpFuncsHelper::get_eval_batch_expr_cmp_func(
const ObScale scale2,
const ObCmpOp cmp_op,
const bool is_oracle_mode,
const ObCollationType cs_type)
const ObCollationType cs_type,
const bool has_lob_header)
{
OB_ASSERT(type1 >= ObNullType && type1 < ObMaxType);
OB_ASSERT(type2 >= ObNullType && type2 < ObMaxType);
@ -535,6 +1041,14 @@ ObExpr::EvalBatchFunc ObExprCmpFuncsHelper::get_eval_batch_expr_cmp_func(
OB_UNLIKELY(ob_is_invalid_obj_tc(tc1) ||
OB_UNLIKELY(ob_is_invalid_obj_tc(tc2)))) {
func_ptr = NULL;
} else if (type1 == ObJsonType && type2 == ObJsonType) {
if (NULL != EVAL_JSON_CMP_FUNCS[cmp_op][has_lob_header]) {
func_ptr = EVAL_BATCH_JSON_CMP_FUNCS[cmp_op];
}
} else if (tc1 == ObGeometryTC && tc2 == ObGeometryTC) {
if (NULL != EVAL_GEO_CMP_FUNCS[cmp_op][has_lob_header]) {
func_ptr = EVAL_BATCH_GEO_CMP_FUNCS[cmp_op];
}
} else if (IS_FIXED_DOUBLE) {
func_ptr = EVAL_BATCH_FIXED_DOUBLE_CMP_FUNCS[MAX(scale1, scale2)][cmp_op];
} else if (!ObDatumFuncs::is_string_type(type1) || !ObDatumFuncs::is_string_type(type2)) {
@ -543,8 +1057,24 @@ ObExpr::EvalBatchFunc ObExprCmpFuncsHelper::get_eval_batch_expr_cmp_func(
OB_ASSERT(cs_type > CS_TYPE_INVALID && cs_type < CS_TYPE_MAX);
int64_t calc_with_end_space_idx = (is_calc_with_end_space(type1, type2, is_oracle_mode,
cs_type, cs_type) ? 1 : 0);
if (NULL != EVAL_STR_CMP_FUNCS[cs_type][cmp_op][calc_with_end_space_idx]) {
func_ptr = EVAL_BATCH_STR_CMP_FUNCS[cmp_op];
if (has_lob_header && (ob_is_large_text(type1) || ob_is_large_text(type2))) {
if (ob_is_large_text(type1) && ob_is_large_text(type2)) {
if (NULL != EVAL_TEXT_CMP_FUNCS[cs_type][cmp_op][calc_with_end_space_idx]) {
func_ptr = EVAL_BATCH_TEXT_CMP_FUNCS[cmp_op];
}
} else if (ob_is_large_text(type1)) { // type2 not large text
if (NULL != EVAL_TEXT_STR_CMP_FUNCS[cs_type][cmp_op][calc_with_end_space_idx]) {
func_ptr = EVAL_BATCH_TEXT_STR_CMP_FUNCS[cmp_op];
}
} else { // type1 not large text
if (NULL != EVAL_STR_TEXT_CMP_FUNCS[cs_type][cmp_op][calc_with_end_space_idx]) {
func_ptr = EVAL_BATCH_STR_TEXT_CMP_FUNCS[cmp_op];
}
}
} else { // no lob header or tinytext use original str cmp func
if (NULL != EVAL_STR_CMP_FUNCS[cs_type][cmp_op][calc_with_end_space_idx]) {
func_ptr = EVAL_BATCH_STR_CMP_FUNCS[cmp_op];
}
}
}
return func_ptr;
@ -555,7 +1085,8 @@ DatumCmpFunc ObExprCmpFuncsHelper::get_datum_expr_cmp_func(const ObObjType type1
const ObScale scale1,
const ObScale scale2,
const bool is_oracle_mode,
const ObCollationType cs_type)
const ObCollationType cs_type,
const bool has_lob_header)
{
OB_ASSERT(type1 >= ObNullType && type1 < ObMaxType);
OB_ASSERT(type2 >= ObNullType && type2 < ObMaxType);
@ -563,7 +1094,11 @@ DatumCmpFunc ObExprCmpFuncsHelper::get_datum_expr_cmp_func(const ObObjType type1
ObObjTypeClass tc1 = ob_obj_type_class(type1);
ObObjTypeClass tc2 = ob_obj_type_class(type2);
ObDatumCmpFuncType func_ptr = NULL;
if (IS_FIXED_DOUBLE) {
if (type1 == ObJsonType && type2 == ObJsonType) {
func_ptr = DATUM_JSON_CMP_FUNCS[has_lob_header];
} else if (type1 == ObGeometryType && type2 == ObGeometryType) {
func_ptr = DATUM_GEO_CMP_FUNCS[has_lob_header];
} else if (IS_FIXED_DOUBLE) {
func_ptr = DATUM_FIXED_DOUBLE_CMP_FUNCS[MAX(scale1, scale2)];
} else if (!ObDatumFuncs::is_string_type(type1) || !ObDatumFuncs::is_string_type(type2)) {
func_ptr = DATUM_TYPE_CMP_FUNCS[type1][type2];
@ -574,7 +1109,17 @@ DatumCmpFunc ObExprCmpFuncsHelper::get_datum_expr_cmp_func(const ObObjType type1
OB_ASSERT(cs_type > CS_TYPE_INVALID && cs_type < CS_TYPE_MAX);
int64_t calc_with_end_space_idx = (is_calc_with_end_space(type1, type2, is_oracle_mode,
cs_type, cs_type) ? 1 : 0);
func_ptr = DATUM_STR_CMP_FUNCS[cs_type][calc_with_end_space_idx];
if (has_lob_header && (ob_is_large_text(type1) || ob_is_large_text(type2))) {
if (ob_is_large_text(type1) && ob_is_large_text(type2)) {
func_ptr = DATUM_TEXT_CMP_FUNCS[cs_type][calc_with_end_space_idx];
} else if (ob_is_large_text(type1)) { // type2 not large text
func_ptr = DATUM_TEXT_STR_CMP_FUNCS[cs_type][calc_with_end_space_idx];
} else { // type1 not large text
func_ptr = DATUM_STR_TEXT_CMP_FUNCS[cs_type][calc_with_end_space_idx];
}
} else { // no lob header or tinytext use original str cmp func
func_ptr = DATUM_STR_CMP_FUNCS[cs_type][calc_with_end_space_idx];
}
}
return func_ptr;
}
@ -642,6 +1187,91 @@ REG_SER_FUNC_ARRAY(OB_SFA_DATUM_CMP_STR,
DATUM_STR_CMP_FUNCS,
sizeof(DATUM_STR_CMP_FUNCS) / sizeof(void *));
static_assert(7 == CO_MAX && CS_TYPE_MAX * 7 * 2 == sizeof(EVAL_TEXT_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_RELATION_EXPR_EVAL_TEXT,
EVAL_TEXT_CMP_FUNCS,
sizeof(EVAL_TEXT_CMP_FUNCS) / sizeof(void *));
REG_SER_FUNC_ARRAY(OB_SFA_RELATION_EXPR_TEXT_EVAL_BATCH,
EVAL_BATCH_TEXT_CMP_FUNCS,
sizeof(EVAL_BATCH_TEXT_CMP_FUNCS) / sizeof(void *));
static_assert(CS_TYPE_MAX * 2 == sizeof(DATUM_TEXT_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_DATUM_CMP_TEXT,
DATUM_TEXT_CMP_FUNCS,
sizeof(DATUM_TEXT_CMP_FUNCS) / sizeof(void *));
static_assert(7 == CO_MAX && CS_TYPE_MAX * 7 * 2 == sizeof(EVAL_TEXT_STR_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_RELATION_EXPR_EVAL_TEXT_STR,
EVAL_TEXT_STR_CMP_FUNCS,
sizeof(EVAL_TEXT_STR_CMP_FUNCS) / sizeof(void *));
REG_SER_FUNC_ARRAY(OB_SFA_RELATION_EXPR_TEXT_STR_EVAL_BATCH,
EVAL_BATCH_TEXT_STR_CMP_FUNCS,
sizeof(EVAL_BATCH_TEXT_STR_CMP_FUNCS) / sizeof(void *));
static_assert(CS_TYPE_MAX * 2 == sizeof(DATUM_TEXT_STR_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_DATUM_CMP_TEXT_STR,
DATUM_TEXT_STR_CMP_FUNCS,
sizeof(DATUM_TEXT_STR_CMP_FUNCS) / sizeof(void *));
static_assert(7 == CO_MAX && CS_TYPE_MAX * 7 * 2 == sizeof(EVAL_STR_TEXT_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_RELATION_EXPR_EVAL_STR_TEXT,
EVAL_STR_TEXT_CMP_FUNCS,
sizeof(EVAL_STR_TEXT_CMP_FUNCS) / sizeof(void *));
REG_SER_FUNC_ARRAY(OB_SFA_RELATION_EXPR_STR_TEXT_EVAL_BATCH,
EVAL_BATCH_STR_TEXT_CMP_FUNCS,
sizeof(EVAL_BATCH_STR_TEXT_CMP_FUNCS) / sizeof(void *));
static_assert(CS_TYPE_MAX * 2 == sizeof(DATUM_STR_TEXT_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_DATUM_CMP_STR_TEXT,
DATUM_STR_TEXT_CMP_FUNCS,
sizeof(DATUM_STR_TEXT_CMP_FUNCS) / sizeof(void *));
static_assert(7 == CO_MAX && CO_MAX * 2 == sizeof(EVAL_JSON_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_RELATION_EXPR_EVAL_JSON,
EVAL_JSON_CMP_FUNCS,
sizeof(EVAL_JSON_CMP_FUNCS) / sizeof(void *));
static_assert(7 == CO_MAX && CO_MAX == sizeof(EVAL_BATCH_JSON_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_RELATION_EXPR_JSON_EVAL_BATCH,
EVAL_BATCH_JSON_CMP_FUNCS,
sizeof(EVAL_BATCH_JSON_CMP_FUNCS) / sizeof(void *));
static_assert(2 == sizeof(DATUM_JSON_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_DATUM_CMP_JSON,
DATUM_JSON_CMP_FUNCS,
sizeof(DATUM_JSON_CMP_FUNCS) / sizeof(void *));
// Geo cmp functions reg
static_assert(7 == CO_MAX && CO_MAX * 2 == sizeof(EVAL_GEO_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_RELATION_EXPR_EVAL_GEO,
EVAL_GEO_CMP_FUNCS,
sizeof(EVAL_GEO_CMP_FUNCS) / sizeof(void *));
static_assert(7 == CO_MAX && CO_MAX == sizeof(EVAL_BATCH_GEO_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_RELATION_EXPR_GEO_EVAL_BATCH,
EVAL_BATCH_GEO_CMP_FUNCS,
sizeof(EVAL_BATCH_GEO_CMP_FUNCS) / sizeof(void *));
static_assert(2 == sizeof(DATUM_GEO_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_DATUM_CMP_GEO,
DATUM_GEO_CMP_FUNCS,
sizeof(DATUM_GEO_CMP_FUNCS) / sizeof(void *));
// Fixed double cmp functions reg
static_assert(
OB_NOT_FIXED_SCALE * CO_MAX == sizeof(EVAL_FIXED_DOUBLE_CMP_FUNCS) / sizeof(void *),