Merge branch 'column_store'
Co-authored-by: wangt1xiuyi <13547954130@163.com> Co-authored-by: yangqise7en <877793735@qq.com> Co-authored-by: Zach41 <zach_41@163.com>
This commit is contained in:
@ -33,6 +33,7 @@
|
||||
#include "lib/timezone/ob_oracle_format_models.h"
|
||||
#include "sql/engine/expr/ob_expr_lob_utils.h"
|
||||
#include "sql/resolver/dml/ob_select_stmt.h"
|
||||
#include "sql/engine/expr/ob_expr_func_round.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -1119,6 +1120,8 @@ int ObExprOperator::aggregate_result_type_for_merge(
|
||||
type.set_collation_type(session->get_local_collation_connection());
|
||||
} else {
|
||||
ObObjType res_type = types[0].get_type();
|
||||
bool is_oracle_all_same_number = is_oracle_mode &&
|
||||
ob_is_number_or_decimal_int_tc(types[0].get_type());
|
||||
for (int64_t i = 1; OB_SUCC(ret) && i < param_num; ++i) {
|
||||
if (OB_FAIL(ObExprResultTypeUtil::get_merge_result_type(res_type,
|
||||
res_type,
|
||||
@ -1127,12 +1130,24 @@ int ObExprOperator::aggregate_result_type_for_merge(
|
||||
} else if (OB_UNLIKELY(ObMaxType == res_type)) {
|
||||
ret = OB_INVALID_ARGUMENT; // not compatible input
|
||||
LOG_WARN("invalid argument. wrong type for merge", K(i), K(types[i].get_type()), K(ret));
|
||||
} else if (is_oracle_all_same_number) {
|
||||
is_oracle_all_same_number = types[i].get_type() == types[i-1].get_type() &&
|
||||
types[i].get_precision() == types[i-1].get_precision() &&
|
||||
types[i].get_scale() == types[i-1].get_scale();
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (is_oracle_all_same_number) {
|
||||
// in oracle mode, When all inputs are of the same number type with same PS info,
|
||||
// the result type is also the same as the inputs
|
||||
res_type = types[0].get_type();
|
||||
}
|
||||
type.set_type(res_type);
|
||||
if (ob_is_numeric_type(res_type)) {
|
||||
if ((ob_is_decimal_int_tc(res_type) || ob_is_number_tc(res_type))
|
||||
&& is_oracle_all_same_number) {
|
||||
// no need to aggregate numeric accuracy again
|
||||
type.set_accuracy(types[0].get_accuracy());
|
||||
} else if (ob_is_numeric_type(res_type)) {
|
||||
ret = aggregate_numeric_accuracy_for_merge(type, types, param_num, is_oracle_mode);
|
||||
} else if (ob_is_temporal_type(res_type) || ob_is_otimestamp_type(res_type)) {
|
||||
ret = aggregate_temporal_accuracy_for_merge(type, types, param_num);
|
||||
@ -1406,6 +1421,7 @@ int ObExprOperator::aggregate_numeric_accuracy_for_merge(ObExprResType &type,
|
||||
types[i].get_precision());
|
||||
scale = 0;
|
||||
} else if (ob_is_number_tc(types[i].get_type())
|
||||
|| ob_is_decimal_int_tc(types[i].get_type())
|
||||
|| ob_is_temporal_type(types[i].get_type())
|
||||
|| ob_is_bit_tc(types[i].get_type())) {
|
||||
precision = types[i].get_precision();
|
||||
@ -1444,12 +1460,18 @@ int ObExprOperator::aggregate_numeric_accuracy_for_merge(ObExprResType &type,
|
||||
} else {
|
||||
if (max_integer_digits + max_decimal_digits >= 0) {
|
||||
precision = static_cast<ObPrecision>(max_integer_digits + max_decimal_digits);
|
||||
type.set_precision(MIN(precision, ObAccuracy::MAX_ACCURACY2[is_oracle_mode][type.get_type()].precision_));
|
||||
if (type.is_decimal_int()) {
|
||||
type.set_precision(MIN(precision, OB_MAX_DECIMAL_POSSIBLE_PRECISION));
|
||||
} else {
|
||||
type.set_precision(
|
||||
MIN(precision, ObAccuracy::MAX_ACCURACY2[is_oracle_mode][type.get_type()].precision_));
|
||||
}
|
||||
}
|
||||
if (max_decimal_digits >= 0) {
|
||||
type.set_scale(MIN(max_decimal_digits, ObAccuracy::MAX_ACCURACY2[is_oracle_mode][type.get_type()].scale_));
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("aggregate numeric accuracy", K(max_integer_digits), K(max_decimal_digits), K(type));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1545,6 +1567,15 @@ ObObjType ObExprOperator::enumset_calc_types_[ObMaxTC] =
|
||||
ObUInt64Type,/*ObBitTC*/
|
||||
ObVarcharType,/*ObEnumSetTC*/
|
||||
ObVarcharType,/*ObEnumSetInnerTC*/
|
||||
ObVarcharType, /*ObOTimestampTC*/
|
||||
ObNullType, /*ObRawTC*/
|
||||
ObVarcharType, /*ObInternalTC*/
|
||||
ObVarcharType, /*ObRowIDTC*/
|
||||
ObMaxType, /*ObLobTC*/
|
||||
ObVarcharType, /*ObJsonTC*/
|
||||
ObMaxType, /*ObGeometryTC*/
|
||||
ObNullType, /*UDT*/
|
||||
ObUInt64Type, /*ObDecimalIntTC*/
|
||||
};
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -1816,14 +1847,22 @@ int ObRelationalExprOperator::compare_cast(ObObj &result,
|
||||
const ObObj *res_obj2 = NULL;
|
||||
bool need_cast = false;
|
||||
cast_ctx.dest_collation_ = cmp_ctx.cmp_cs_type_;
|
||||
if (OB_FAIL(ObObjCaster::to_type(cmp_ctx.cmp_type_, cast_ctx, obj1, buf_obj1, res_obj1))) {
|
||||
LOG_WARN("failed to cast obj", K(ret), K(cmp_ctx.cmp_type_), K(obj1));
|
||||
} else if (OB_FAIL(ObObjCaster::to_type(cmp_ctx.cmp_type_, cast_ctx, obj2, buf_obj2, res_obj2))) {
|
||||
LOG_WARN("failed to cast obj", K(ret), K(cmp_ctx.cmp_type_), K(obj2));
|
||||
ObCompareCtx tmp_cmp_ctx = cmp_ctx;
|
||||
if (ob_is_decimal_int(tmp_cmp_ctx.cmp_type_)) {
|
||||
// result accuracy can't determined here,
|
||||
// just use ObNumberType instead
|
||||
tmp_cmp_ctx.cmp_type_ = ObNumberType;
|
||||
}
|
||||
if (OB_FAIL(ObObjCaster::to_type(tmp_cmp_ctx.cmp_type_, cast_ctx, obj1, buf_obj1, res_obj1))) {
|
||||
LOG_WARN("failed to cast obj", K(ret), K(tmp_cmp_ctx), K(obj1));
|
||||
} else if (OB_FAIL(
|
||||
ObObjCaster::to_type(tmp_cmp_ctx.cmp_type_, cast_ctx, obj2, buf_obj2, res_obj2))) {
|
||||
LOG_WARN("failed to cast obj", K(ret), K(tmp_cmp_ctx), K(obj2));
|
||||
} else if (OB_ISNULL(res_obj1) || OB_ISNULL(res_obj2)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("res_obj1 or res_obj2 is null");
|
||||
} else if (OB_FAIL(ObObjCmpFuncs::compare(result, *res_obj1, *res_obj2, cmp_ctx, cmp_op, need_cast))) {
|
||||
} else if (OB_FAIL(ObObjCmpFuncs::compare(result, *res_obj1, *res_obj2, tmp_cmp_ctx, cmp_op,
|
||||
need_cast))) {
|
||||
LOG_WARN("failed to compare objects", K(ret), K(*res_obj1), K(*res_obj2), K(cmp_op));
|
||||
} else if (need_cast) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -1860,12 +1899,10 @@ int ObRelationalExprOperator::compare_nullsafe(int64_t &result,
|
||||
|
||||
bool ObRelationalExprOperator::can_cmp_without_cast(ObExprResType type1,
|
||||
ObExprResType type2,
|
||||
ObCmpOp cmp_op,
|
||||
const ObSQLSessionInfo &session)
|
||||
ObCmpOp cmp_op)
|
||||
{
|
||||
bool need_no_cast = false;
|
||||
bool has_lob_header = type1.has_lob_header() || type2.has_lob_header();
|
||||
UNUSED(session);
|
||||
//特殊处理显示调用compare(例如:c1 > c2),此时enum/set均应该转换成string处理
|
||||
//内部比较(order by),enum/set不需要转换。
|
||||
if (ob_is_enum_or_set_type(type1.get_type())
|
||||
@ -1890,11 +1927,18 @@ bool ObRelationalExprOperator::can_cmp_without_cast(ObExprResType type1,
|
||||
lib::is_oracle_mode(),
|
||||
type2.get_collation_type(),
|
||||
type2.get_collation_type()));
|
||||
} else if (ob_is_decimal_int_tc(type1.get_type()) && ob_is_decimal_int_tc(type2.get_type())) {
|
||||
// if scale1 != scale2 or int_bytes1 != int_bytes2
|
||||
need_no_cast = (type1.get_scale() == type2.get_scale()
|
||||
&& get_decimalint_type(type1.get_precision())
|
||||
== get_decimalint_type(type2.get_precision()));
|
||||
} else {
|
||||
auto func_ptr = ObExprCmpFuncsHelper::get_eval_expr_cmp_func(type1.get_type(),
|
||||
type2.get_type(),
|
||||
type1.get_scale(),
|
||||
type2.get_scale(),
|
||||
type1.get_precision(),
|
||||
type2.get_precision(),
|
||||
cmp_op,
|
||||
lib::is_oracle_mode(),
|
||||
CS_TYPE_BINARY,
|
||||
@ -1974,14 +2018,42 @@ int ObRelationalExprOperator::get_equal_meta(ObObjMeta &meta,
|
||||
int ObExprOperator::calc_cmp_type2(ObExprResType &type,
|
||||
const ObExprResType &type1,
|
||||
const ObExprResType &type2,
|
||||
const ObCollationType coll_type) const
|
||||
const ObCollationType coll_type,
|
||||
const bool left_is_const, /* false */
|
||||
const bool right_is_const /* false*/) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObObjType cmp_type = ObMaxType;
|
||||
// todo(jiuren): we can add such code after plan cache add same optimization.
|
||||
// if (is_int_cmp_const_str(&type1, &type2, cmp_type)) {
|
||||
// } else
|
||||
if (is_oracle_mode() && (type1.is_blob() || type2.is_blob()
|
||||
ObObjType obj_type1 = type1.get_type();
|
||||
ObObjType obj_type2 = type2.get_type();
|
||||
bool is_finish = false;
|
||||
// decimal int cmps number, rules are follows:
|
||||
// 1. if decimal int is not const, number is const, cast number_const as decimal_int
|
||||
// 2. if number's (P, S) does not satisfy: P >= S && S >= 0, cast decimal int as number
|
||||
if (ObDecimalIntType == obj_type1 && ObNumberTC == ob_obj_type_class(obj_type2)) {
|
||||
if (!left_is_const && right_is_const) {
|
||||
cmp_type = ObDecimalIntType;
|
||||
is_finish = true;
|
||||
} else if (type2.get_precision() == PRECISION_UNKNOWN_YET || type2.get_scale() < 0
|
||||
|| type2.get_precision() < type2.get_scale()) {
|
||||
cmp_type = ObNumberType;
|
||||
is_finish = true;
|
||||
}
|
||||
} else if (ObDecimalIntType == obj_type2 && ObNumberTC == ob_obj_type_class(obj_type1)) {
|
||||
if (!right_is_const && left_is_const) {
|
||||
cmp_type = ObDecimalIntType;
|
||||
is_finish = true;
|
||||
} else if (type1.get_precision() == PRECISION_UNKNOWN_YET || type1.get_scale() < 0
|
||||
|| type1.get_precision() < type1.get_scale()) {
|
||||
cmp_type = ObNumberType;
|
||||
is_finish = true;
|
||||
}
|
||||
}
|
||||
if (is_finish) {// do nothing
|
||||
} else if (is_oracle_mode() && (type1.is_blob() || type2.is_blob()
|
||||
|| type1.is_blob_locator() || type2.is_blob_locator())
|
||||
&& type_ != T_OP_IS && type_ != T_OP_IS_NOT) {
|
||||
ret = OB_ERR_INVALID_TYPE_FOR_OP;
|
||||
@ -2018,6 +2090,7 @@ int ObExprOperator::calc_cmp_type2(ObExprResType &type,
|
||||
LOG_WARN("fail to get cmp_type",K(ret));
|
||||
} else if (OB_UNLIKELY(ObMaxType == cmp_type)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid cmp type", K(ret), K(type1), K(type2), K(left_is_const), K(right_is_const));
|
||||
} else if (ObURowIDType == cmp_type) {
|
||||
// 如果比较是urwoid类型,只支持<urwoid, urowid>,<string, urwoid>, <urowid, string>,
|
||||
// <NULL, urowid>, <urowid, NULL>
|
||||
@ -2047,7 +2120,7 @@ int ObExprOperator::calc_cmp_type2(ObExprResType &type,
|
||||
} else if (ObRawType == cmp_type) {
|
||||
type.get_calc_meta().set_collation_type(CS_TYPE_BINARY);
|
||||
}
|
||||
LOG_DEBUG("calc cmp type", K(type1), K(type2), K(type.get_calc_meta()));
|
||||
LOG_DEBUG("calc cmp type", K(type1), K(type2), K(type.get_calc_meta()), K(lbt()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -2242,8 +2315,26 @@ int ObRelationalExprOperator::deduce_cmp_type(const ObExprOperator &expr,
|
||||
int ret = OB_SUCCESS;
|
||||
ObExprResType cmp_type;
|
||||
CK(NULL != type_ctx.get_session());
|
||||
ObRawExpr *left_param = nullptr, *right_param = nullptr;
|
||||
ObRawExpr *op_expr = expr.get_raw_expr();
|
||||
if (OB_ISNULL(op_expr)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid null operator raw expr", K(ret), K(op_expr));
|
||||
} else if (OB_UNLIKELY(op_expr->get_param_count() != 2)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid param count", K(ret), K(op_expr->get_param_count()));
|
||||
} else if (OB_ISNULL(op_expr->get_param_expr(0)) || OB_ISNULL(op_expr->get_param_expr(1))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid null param expr", K(ret), K(op_expr->get_param_expr(0)),
|
||||
K(op_expr->get_param_expr(1)));
|
||||
} else {
|
||||
left_param = op_expr->get_param_expr(0);
|
||||
right_param = op_expr->get_param_expr(1);
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_SUCC(expr.calc_cmp_type2(cmp_type, type1, type2, type_ctx.get_coll_type()))) {
|
||||
} else if (OB_SUCC(expr.calc_cmp_type2(cmp_type, type1, type2, type_ctx.get_coll_type(),
|
||||
left_param->is_static_const_expr(),
|
||||
right_param->is_static_const_expr()))) {
|
||||
type.set_int32(); // not tinyint, compatible with MySQL
|
||||
type.set_precision(DEFAULT_PRECISION_FOR_BOOL);
|
||||
type.set_scale(DEFAULT_SCALE_FOR_INTEGER);
|
||||
@ -2251,10 +2342,23 @@ int ObRelationalExprOperator::deduce_cmp_type(const ObExprOperator &expr,
|
||||
type.set_calc_type(cmp_type.get_calc_type());
|
||||
ObExprOperator::calc_result_flag2(type, type1, type2);
|
||||
bool need_no_cast = can_cmp_without_cast(
|
||||
type1, type2, get_cmp_op(expr.get_type()), *type_ctx.get_session());
|
||||
type1, type2, get_cmp_op(expr.get_type()));
|
||||
type1.set_calc_type(need_no_cast ? type1.get_type() : cmp_type.get_calc_type());
|
||||
type2.set_calc_type(need_no_cast ? type2.get_type() : cmp_type.get_calc_type());
|
||||
if (ob_is_string_or_lob_type(cmp_type.get_calc_type())) {
|
||||
if (cmp_type.get_calc_type() == ObDecimalIntType) {
|
||||
if (OB_FAIL(deduce_decimalint_cmp_calc_type(left_param->is_static_const_expr(),
|
||||
right_param->is_static_const_expr(), need_no_cast,
|
||||
expr.get_type(), type1, type2))) {
|
||||
LOG_WARN("deduce decimal int calc type failed", K(ret));
|
||||
}
|
||||
} else if (is_oracle_mode() && cmp_type.get_calc_type() == ObNumberType) {
|
||||
if (ObDecimalIntType == type1.get_type() && ObNumberTC == type2.get_type_class()) {
|
||||
type1.set_calc_accuracy(type2.get_accuracy());
|
||||
} else if (ObDecimalIntType == type2.get_type() && ObNumberTC == type1.get_type_class()) {
|
||||
type2.set_calc_accuracy(type1.get_accuracy());
|
||||
}
|
||||
LOG_DEBUG("decimalint vs number compare", K(type1), K(type2));
|
||||
} else if (ob_is_string_or_lob_type(cmp_type.get_calc_type())) {
|
||||
type1.set_calc_collation_type(cmp_type.get_calc_collation_type());
|
||||
type2.set_calc_collation_type(cmp_type.get_calc_collation_type());
|
||||
} else if (ObRawType == cmp_type.get_calc_type()) {
|
||||
@ -2372,7 +2476,9 @@ int ObRelationalExprOperator::calc_calc_type3(ObExprResType &type1,
|
||||
ObExprResType cmp_type21; // b <= a
|
||||
ObExprResType cmp_type13; // a <= c
|
||||
bool need_no_cast = false;
|
||||
bool need_no_cast_21 = false, need_no_cast_13 = false;
|
||||
CK(NULL != type_ctx.get_session());
|
||||
CK(NULL != raw_expr_);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(calc_cmp_type2(cmp_type21, type2, type1, type_ctx.get_coll_type()))) {
|
||||
LOG_WARN("get cmp failed", K(ret), K(type2), K(type1));
|
||||
@ -2383,29 +2489,71 @@ int ObRelationalExprOperator::calc_calc_type3(ObExprResType &type1,
|
||||
ObObjType type13 = cmp_type13.get_calc_type();
|
||||
if (OB_LIKELY(type21 == type13 && type13 == cmp_type)) {
|
||||
//type21 == type13 == cmp_type
|
||||
bool need_no_cast_21 = can_cmp_without_cast(
|
||||
type2, type1, get_cmp_op(type_), *type_ctx.get_session());
|
||||
bool need_no_cast_13 = can_cmp_without_cast(
|
||||
type1, type3, get_cmp_op(type_), *type_ctx.get_session());
|
||||
need_no_cast_21 = can_cmp_without_cast(
|
||||
type2, type1, get_cmp_op(type_));
|
||||
need_no_cast_13 = can_cmp_without_cast(
|
||||
type1, type3, get_cmp_op(type_));
|
||||
need_no_cast = need_no_cast_21 && need_no_cast_13;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (need_no_cast) {
|
||||
type1.set_calc_type(type1.get_type());
|
||||
type1.set_calc_accuracy(type1.get_accuracy());
|
||||
type2.set_calc_type(type2.get_type());
|
||||
type2.set_calc_accuracy(type2.get_accuracy());
|
||||
type3.set_calc_type(type3.get_type());
|
||||
type3.set_calc_accuracy(type3.get_calc_accuracy());
|
||||
} else if (cmp_type == ObDecimalIntType) {
|
||||
if (type1.is_decimal_int()) {
|
||||
type1.set_calc_type(type1.get_type());
|
||||
type1.set_calc_accuracy(type1.get_accuracy());
|
||||
// b >= a >= c, if cmp_type is decimal int
|
||||
// 1. if a is decimal int, cast b & c to decimal int with cm_const_to_decint mode
|
||||
if (need_no_cast_21) {
|
||||
type2.set_calc_accuracy(type2.get_accuracy());
|
||||
type2.set_calc_type(type2.get_type());
|
||||
} else {
|
||||
type2.set_calc_accuracy(type1.get_accuracy());
|
||||
type2.set_calc_type(ObDecimalIntType);
|
||||
// between expr: a >= b, expr_type using T_OP_GE, right is const
|
||||
// not between expr: a < b, expr_type using T_OP_LT, right, is const
|
||||
type2.add_cast_mode(
|
||||
get_const_cast_mode(raw_expr_->get_expr_type() == T_OP_BTW ? T_OP_GE : T_OP_LT, true));
|
||||
}
|
||||
if (need_no_cast_13) {
|
||||
type3.set_calc_accuracy(type3.get_accuracy());
|
||||
type3.set_calc_type(type3.get_type());
|
||||
} else {
|
||||
type3.set_calc_accuracy(type1.get_accuracy());
|
||||
type3.set_calc_type(ObDecimalIntType);
|
||||
// between expr: a <= c, expr_type using T_OP_LE, right is const
|
||||
// not between expr: a > b
|
||||
type3.add_cast_mode(
|
||||
get_const_cast_mode(raw_expr_->get_expr_type() == T_OP_BTW ? T_OP_LE : T_OP_GT, true));
|
||||
}
|
||||
} else {
|
||||
type1.set_calc_type(ObNumberType);
|
||||
type2.set_calc_type(ObNumberType);
|
||||
type3.set_calc_type(ObNumberType);
|
||||
}
|
||||
} else {
|
||||
type1.set_calc_type(cmp_type);
|
||||
type2.set_calc_type(cmp_type);
|
||||
type3.set_calc_type(cmp_type);
|
||||
}
|
||||
LOG_DEBUG("calc type3", K(type1.get_calc_type()), K(type2.get_calc_type()),
|
||||
K(type3.get_calc_type()), K(type1.get_calc_accuracy()), K(type2.get_calc_accuracy()),
|
||||
K(type3.get_calc_accuracy()), K(type1.get_cast_mode()), K(type2.get_cast_mode()),
|
||||
K(type3.get_cast_mode()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRelationalExprOperator::get_cmp_result_type3(ObExprResType &type, bool &need_no_cast,
|
||||
const ObExprResType *types, const int64_t param_num, const sql::ObSQLSessionInfo &my_session)
|
||||
ObExprResType *types,
|
||||
const int64_t param_num, const bool has_lower,
|
||||
const sql::ObSQLSessionInfo &my_session)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
need_no_cast = false;
|
||||
@ -2421,14 +2569,40 @@ int ObRelationalExprOperator::get_cmp_result_type3(ObExprResType &type, bool &ne
|
||||
if (OB_FAIL(my_session.get_collation_connection(coll_type))) {
|
||||
LOG_WARN("fail to get_collation_connection", K(ret));
|
||||
} else if (2 == param_num) {
|
||||
need_no_cast = can_cmp_without_cast(types[1], types[0], CO_CMP, my_session);
|
||||
need_no_cast = can_cmp_without_cast(types[1], types[0], CO_CMP);
|
||||
if (!need_no_cast) {
|
||||
ret = calc_cmp_type2(type, types[0], types[1], coll_type);
|
||||
if (OB_FAIL(calc_cmp_type2(type, types[0], types[1], coll_type))) {
|
||||
LOG_WARN("calc_cmp_type2 failed", K(ret));
|
||||
} else if (type.get_calc_type() == ObDecimalIntType) {
|
||||
if (types[0].is_decimal_int()) {
|
||||
types[0].set_calc_type(types[0].get_type());
|
||||
types[0].set_calc_accuracy(types[0].get_accuracy());
|
||||
// cast to order type
|
||||
types[1].set_calc_type(ObDecimalIntType);
|
||||
types[1].set_calc_accuracy(types[0].get_accuracy());
|
||||
if (has_lower) { // order_expr >= low_expr
|
||||
types[1].add_cast_mode(get_const_cast_mode(T_OP_GE, true));
|
||||
} else { // order_expr <= upper_expr
|
||||
types[1].add_cast_mode(get_const_cast_mode(T_OP_LE, true));
|
||||
}
|
||||
} else {
|
||||
types[0].set_calc_type(ObNumberType);
|
||||
types[1].set_calc_type(ObNumberType);
|
||||
}
|
||||
} else {
|
||||
types[0].set_calc_meta(type.get_calc_meta());
|
||||
types[1].set_calc_meta(type.get_calc_meta());
|
||||
}
|
||||
} else {
|
||||
types[0].set_calc_type(types[0].get_type());
|
||||
types[0].set_calc_accuracy(types[0].get_accuracy());
|
||||
types[1].set_calc_type(types[0].get_type());
|
||||
types[1].set_calc_accuracy(types[1].get_accuracy());
|
||||
}
|
||||
} else {
|
||||
const ObExprResType &type1 = types[0];
|
||||
const ObExprResType &type2 = types[1];
|
||||
const ObExprResType &type3 = types[2];
|
||||
ObExprResType &type1 = types[0];
|
||||
ObExprResType &type2 = types[1];
|
||||
ObExprResType &type3 = types[2];
|
||||
//a(type1) between b(type2) and c(type3) <==> b<=a && a <=c
|
||||
ObExprResType cmp_type21; // b <= a
|
||||
ObExprResType cmp_type13; // a <= c
|
||||
@ -2441,10 +2615,19 @@ int ObRelationalExprOperator::get_cmp_result_type3(ObExprResType &type, bool &ne
|
||||
} else if (cmp_type21.get_calc_type() == cmp_type13.get_calc_type()
|
||||
&& cmp_type13.get_calc_type() == type.get_calc_type()) {
|
||||
//type21 == type13 == cmp_type
|
||||
bool need_no_cast_21 = can_cmp_without_cast(type2, type1, CO_CMP, my_session);
|
||||
bool need_no_cast_13 = can_cmp_without_cast(type1, type3, CO_CMP, my_session);
|
||||
bool need_no_cast_21 = can_cmp_without_cast(type2, type1, CO_CMP);
|
||||
bool need_no_cast_13 = can_cmp_without_cast(type1, type3, CO_CMP);
|
||||
need_no_cast = need_no_cast_21 && need_no_cast_13;
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
ObExprTypeCtx dummy_ctx;
|
||||
dummy_ctx.set_raw_expr(raw_expr_);
|
||||
ObSQLUtils::init_type_ctx(&my_session, dummy_ctx);
|
||||
ObExprResType dummy_res;
|
||||
if (OB_FAIL(calc_result_type3(dummy_res, type1, type2, type3, dummy_ctx))) {
|
||||
LOG_WARN("calc_result_type3 failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -3345,14 +3528,14 @@ int ObSubQueryRelationalExpr::compare_single_row(const ObNewRow &left_row,
|
||||
}
|
||||
|
||||
int ObSubQueryRelationalExpr::get_param_types(
|
||||
const ObRawExpr ¶m, const bool is_iter, ObIArray<ObObjMeta> &types) const
|
||||
const ObRawExpr ¶m, const bool is_iter, ObIArray<ObExprResType> &types) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (param.get_expr_type() == T_OP_ROW) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < param.get_param_count(); i++) {
|
||||
const ObRawExpr *e = param.get_param_expr(i);
|
||||
CK(NULL != e);
|
||||
OZ(types.push_back(e->get_result_meta()));
|
||||
OZ(types.push_back(e->get_result_type()));
|
||||
}
|
||||
} else if (param.get_expr_type() == T_REF_QUERY && is_iter) {
|
||||
const ObQueryRefRawExpr &ref = static_cast<const ObQueryRefRawExpr &>(param);
|
||||
@ -3360,7 +3543,7 @@ int ObSubQueryRelationalExpr::get_param_types(
|
||||
OZ(types.push_back(*t));
|
||||
}
|
||||
} else {
|
||||
OZ(types.push_back(param.get_result_meta()));
|
||||
OZ(types.push_back(param.get_result_type()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -3370,8 +3553,8 @@ int ObSubQueryRelationalExpr::cg_expr(ObExprCGCtx &op_cg_ctx,
|
||||
ObExpr &rt_expr) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<ObObjMeta, 1> left_types;
|
||||
ObSEArray<ObObjMeta, 1> right_types;
|
||||
ObSEArray<ObExprResType, 1> left_types;
|
||||
ObSEArray<ObExprResType, 1> right_types;
|
||||
void **funcs = NULL;
|
||||
|
||||
CK(NULL != op_cg_ctx.allocator_);
|
||||
@ -3405,8 +3588,8 @@ int ObSubQueryRelationalExpr::cg_expr(ObExprCGCtx &op_cg_ctx,
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
funcs[i] = (void *)ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
|
||||
l.get_type(), r.get_type(), l.get_scale(), r.get_scale(),
|
||||
lib::is_oracle_mode(), l.get_collation_type(), has_lob_header);
|
||||
l.get_type(), r.get_type(), l.get_scale(), r.get_scale(), l.get_precision(),
|
||||
r.get_precision(), lib::is_oracle_mode(), l.get_collation_type(), has_lob_header);
|
||||
CK(NULL != funcs[i]);
|
||||
}
|
||||
}
|
||||
@ -3928,11 +4111,16 @@ int ObVectorExprOperator::calc_result_typeN(ObExprResType &type,
|
||||
{
|
||||
UNUSED(type_ctx);
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(types) || OB_UNLIKELY(param_num <= 0 || 0 >= row_dimension_)
|
||||
|| OB_ISNULL(type_ctx.get_session())) {
|
||||
if (OB_ISNULL(get_raw_expr()) || OB_ISNULL(get_raw_expr()->get_param_expr(0))
|
||||
|| OB_ISNULL(get_raw_expr()->get_param_expr(1))) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("types is null or invalid param num or row_dimension_",
|
||||
K(types), K(param_num), K(row_dimension_), K(type_ctx.get_session()), K(ret));
|
||||
LOG_WARN("invalid null raw expr", K(ret), K(get_raw_expr()),
|
||||
K(get_raw_expr()->get_param_expr(0)), K(get_raw_expr()->get_param_expr(1)));
|
||||
} else if (OB_ISNULL(types) || OB_UNLIKELY(param_num <= 0 || 0 >= row_dimension_)
|
||||
|| OB_ISNULL(type_ctx.get_session())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("types is null or invalid param num or row_dimension_", K(types), K(param_num),
|
||||
K(row_dimension_), K(type_ctx.get_session()), K(ret));
|
||||
} else {
|
||||
int64_t left_start_idx = 0;
|
||||
int64_t right_start_idx = row_dimension_;
|
||||
@ -3945,36 +4133,38 @@ int ObVectorExprOperator::calc_result_typeN(ObExprResType &type,
|
||||
bool has_composite_elem = false;
|
||||
// in 可能是nest table, (nt1 in (nt2, nt3, nt4))
|
||||
for (int64_t k = 0; lib::is_oracle_mode() && k < param_num; ++k) {
|
||||
if (!types[k].is_ext()) {
|
||||
not_composite_elem_idx = k;
|
||||
}
|
||||
if (!types[k].is_ext()) { not_composite_elem_idx = k; }
|
||||
has_composite_elem |= types[k].is_ext();
|
||||
}
|
||||
if (lib::is_oracle_mode() && has_composite_elem) {
|
||||
if (row_dimension_ != 1) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("in condition of nest table can only have one left operator", K(ret),
|
||||
K(row_dimension_),
|
||||
K(param_num));
|
||||
K(row_dimension_), K(param_num));
|
||||
} else if (not_composite_elem_idx != OB_INVALID_INDEX) {
|
||||
ret = OB_ERR_INVALID_TYPE_FOR_OP;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_TYPE_FOR_OP,
|
||||
ob_obj_type_str(types[not_composite_elem_idx].get_type()), ob_obj_type_str(ObExtendType));
|
||||
ob_obj_type_str(types[not_composite_elem_idx].get_type()),
|
||||
ob_obj_type_str(ObExtendType));
|
||||
} else {
|
||||
// 在这儿extend type不知道具体元素的类型。需要在计算时获取。
|
||||
// do nothing
|
||||
}
|
||||
} else {
|
||||
const ObRawExpr *left_param = get_raw_expr()->get_param_expr(0);
|
||||
const ObRawExpr *right_vec_param = get_raw_expr()->get_param_expr(1);
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < right_element_count;
|
||||
++i, right_start_idx += row_dimension_) {
|
||||
++i, right_start_idx += row_dimension_) {
|
||||
tmp_res_type.reset();
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < row_dimension_; ++j) {
|
||||
if (OB_FAIL(ObVectorExprOperator::calc_result_type2_(tmp_res_type,
|
||||
types[left_start_idx+ j],
|
||||
types[right_start_idx + j],
|
||||
type_ctx))) {
|
||||
if (OB_FAIL(ret)) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(ObVectorExprOperator::calc_result_type2_(
|
||||
tmp_res_type, types[left_start_idx + j], types[right_start_idx + j],
|
||||
type_ctx))) {
|
||||
LOG_WARN("failed to calc result types", K(ret));
|
||||
} else if (OB_FAIL(type.get_row_calc_cmp_types().push_back(tmp_res_type.get_calc_meta()))) {
|
||||
} else if (OB_FAIL(
|
||||
type.get_row_calc_cmp_types().push_back(tmp_res_type.get_calc_meta()))) {
|
||||
LOG_WARN("failed to push back cmp type", K(ret));
|
||||
}
|
||||
}
|
||||
@ -3998,6 +4188,7 @@ int ObVectorExprOperator::calc_result_type2_(ObExprResType &type,
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObExprResType cmp_type;
|
||||
bool left_is_const = false, right_is_const = true;
|
||||
if (lib::is_oracle_mode() && (type1.is_lob()
|
||||
|| type1.is_lob_locator())) {
|
||||
ret = OB_ERR_INVALID_TYPE_FOR_OP;
|
||||
@ -4011,7 +4202,8 @@ int ObVectorExprOperator::calc_result_type2_(ObExprResType &type,
|
||||
} else if (lib::is_oracle_mode() && (type1.is_json() || type2.is_json())) {
|
||||
ret = OB_ERR_INVALID_CMP_OP;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_CMP_OP);
|
||||
} else if (OB_SUCC(calc_cmp_type2(cmp_type, type1, type2, type_ctx.get_coll_type()))) {
|
||||
} else if (OB_SUCC(calc_cmp_type2(cmp_type, type1, type2, type_ctx.get_coll_type(), left_is_const,
|
||||
right_is_const))) {
|
||||
type.set_int(); // not tinyint, compatiable with MySQL
|
||||
type.set_calc_collation(cmp_type);
|
||||
type.set_calc_type(cmp_type.get_calc_type());
|
||||
@ -4022,7 +4214,23 @@ int ObVectorExprOperator::calc_result_type2_(ObExprResType &type,
|
||||
CO_EQ);
|
||||
type1.set_calc_type(need_no_cast ? type1.get_type() : cmp_type.get_calc_type());
|
||||
type2.set_calc_type(need_no_cast ? type2.get_type() : cmp_type.get_calc_type());
|
||||
if (ob_is_string_type(cmp_type.get_calc_type())) {
|
||||
// a in (x0, x1, x2) and calc_cmp_type is ObDecimalIntType
|
||||
// if a is decimal int, cast x to decimal int type with CM_CONST_TO_DECIMAL_INT_EQ
|
||||
// else if fallback to ObNumberType, i.e. cast a and x to ObNumberType
|
||||
if (ObDecimalIntType == cmp_type.get_calc_type()) {
|
||||
if (OB_FAIL(ObRelationalExprOperator::deduce_decimalint_cmp_calc_type(
|
||||
left_is_const, right_is_const, need_no_cast, T_OP_EQ, type1, type2))) {
|
||||
LOG_WARN("deduce decimal int calc type failed", K(ret));
|
||||
} else {
|
||||
if (!type1.is_decimal_int()) {
|
||||
type1.set_calc_type(ObNumberType);
|
||||
type2.set_calc_type(ObNumberType);
|
||||
type.set_calc_type(ObNumberType);
|
||||
}
|
||||
LOG_DEBUG("decimal int calc meta for vector", K(type1), K(type1.get_calc_accuracy()),
|
||||
K(type2), K(type2.get_calc_accuracy()));
|
||||
}
|
||||
} else if (ob_is_string_type(cmp_type.get_calc_type())) {
|
||||
if (OB_ISNULL(type_ctx.get_session())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid null session", K(type_ctx.get_session()));
|
||||
@ -4065,6 +4273,62 @@ int ObVectorExprOperator::calc_result_type2_(ObExprResType &type,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRelationalExprOperator::deduce_decimalint_cmp_calc_type(
|
||||
const bool left_is_const, const bool right_is_const, const bool need_no_cast,
|
||||
const ObExprOperatorType expr_type, ObExprResType &type1, ObExprResType &type2)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (need_no_cast) {
|
||||
// no need to cast, set calc_type's scale to org type's scale
|
||||
ObAccuracy calc_accuracy;
|
||||
calc_accuracy.set_scale(type1.get_scale());
|
||||
calc_accuracy.set_precision(type1.get_precision());
|
||||
type1.set_calc_accuracy(calc_accuracy);
|
||||
|
||||
calc_accuracy.set_scale(type2.get_scale());
|
||||
calc_accuracy.set_precision(type2.get_precision());
|
||||
type2.set_calc_accuracy(calc_accuracy);
|
||||
} else {
|
||||
// align scale for decimalint comparasion
|
||||
// one side cast:
|
||||
// not_decint(col/const) cmp col_decint
|
||||
// decint_const cmp col_decint
|
||||
ObAccuracy calc_accuracy;
|
||||
bool all_decint_arg = type1.is_decimal_int() && type2.is_decimal_int();
|
||||
|
||||
bool left_const_to_decint = all_decint_arg && left_is_const && !right_is_const;
|
||||
bool right_const_to_decint = all_decint_arg && right_is_const && !left_is_const;
|
||||
|
||||
bool left_to_decint = (!type1.is_decimal_int() || left_const_to_decint);
|
||||
bool right_to_decint = (!type2.is_decimal_int() || right_const_to_decint);
|
||||
if (!left_to_decint && !right_to_decint) {
|
||||
ObScale calc_scale = MAX(type1.get_scale(), type2.get_scale());
|
||||
ObPrecision calc_prec1 = (calc_scale > type1.get_scale() ?
|
||||
calc_scale - type1.get_scale() + MAX(type1.get_precision(), 0) :
|
||||
type1.get_precision());
|
||||
ObPrecision calc_prec2 = (calc_scale > type2.get_scale() ?
|
||||
calc_scale - type2.get_scale() + MAX(type2.get_precision(), 0) :
|
||||
type2.get_precision());
|
||||
calc_accuracy.set_precision(MAX(calc_prec1, calc_prec2));
|
||||
calc_accuracy.set_scale(calc_scale);
|
||||
} else if (left_to_decint) { // align to right
|
||||
calc_accuracy.set_precision(type2.get_precision());
|
||||
calc_accuracy.set_scale(type2.get_scale());
|
||||
type1.add_cast_mode(get_const_cast_mode(expr_type, false));
|
||||
} else if (right_to_decint) { // align to left
|
||||
calc_accuracy.set_precision(type1.get_precision());
|
||||
calc_accuracy.set_scale(type1.get_scale());
|
||||
type2.add_cast_mode(get_const_cast_mode(expr_type, true));
|
||||
}
|
||||
type1.set_calc_accuracy(calc_accuracy);
|
||||
type2.set_calc_accuracy(calc_accuracy);
|
||||
}
|
||||
LOG_DEBUG("decimal int calc accuracy", K(type1.get_calc_accuracy()), K(type2.get_calc_accuracy()),
|
||||
K(type1), K(type2), K(need_no_cast), K(left_is_const), K(type1.get_cast_mode()),
|
||||
K(type2.get_cast_mode()), K(right_is_const));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObStringExprOperator::convert_result_collation(const ObExprResType &result_type,
|
||||
ObObj &in_obj, ObIAllocator *allocator)
|
||||
{
|
||||
@ -4280,8 +4544,7 @@ int ObBitwiseExprOperator::set_calc_type(ObExprResType &type)
|
||||
type.set_precision(DEFAULT_NUMBER_PRECISION_FOR_INTEGER);
|
||||
type.set_scale(DEFAULT_NUMBER_SCALE_FOR_INTEGER);
|
||||
} else {
|
||||
if (ObNumberType == type.get_type()) {
|
||||
type.set_calc_type(ObNumberType);
|
||||
if (ObNumberType == type.get_type() || ObDecimalIntType == type.get_type()) {
|
||||
type.set_precision(DEFAULT_NUMBER_PRECISION_FOR_INTEGER);
|
||||
type.set_scale(DEFAULT_NUMBER_SCALE_FOR_INTEGER);
|
||||
} else {
|
||||
@ -4508,19 +4771,18 @@ int ObBitwiseExprOperator::calc_result2_mysql(const ObExpr &expr, ObEvalCtx &ctx
|
||||
uint64_t right_uint = 0;
|
||||
void *get_uint_func0 = NULL;
|
||||
void *get_uint_func1 = NULL;
|
||||
const ObObjType &left_type = expr.args_[0]->datum_meta_.type_;
|
||||
const ObObjType &right_type = expr.args_[1]->datum_meta_.type_;
|
||||
|
||||
const ObDatumMeta &left_meta = expr.args_[0]->datum_meta_;
|
||||
const ObDatumMeta &right_meta = expr.args_[1]->datum_meta_;
|
||||
// choose_get_int_func可以想办法放到cg阶段,但是bitwise表达式
|
||||
// 应该不是性能敏感的地方
|
||||
if (OB_FAIL(choose_get_int_func(left_type, get_uint_func0))) {
|
||||
LOG_WARN("choose_get_int_func failed", K(ret), K(left_type));
|
||||
} else if (OB_FAIL((reinterpret_cast<GetUIntFunc>(get_uint_func0)(*left, true,
|
||||
if (OB_FAIL(choose_get_int_func(left_meta, get_uint_func0))) {
|
||||
LOG_WARN("choose_get_int_func failed", K(ret), K(left_meta));
|
||||
} else if (OB_FAIL((reinterpret_cast<GetUIntFunc>(get_uint_func0)(left_meta, *left, true,
|
||||
left_uint, cast_mode)))) {
|
||||
LOG_WARN("get uint64 failed", K(ret), K(*left));
|
||||
} else if (OB_FAIL(choose_get_int_func(right_type, get_uint_func1))) {
|
||||
LOG_WARN("choose_get_int_func failed", K(ret), K(right_type));
|
||||
} else if (OB_FAIL((reinterpret_cast<GetUIntFunc>(get_uint_func1)(*right, true,
|
||||
} else if (OB_FAIL(choose_get_int_func(right_meta, get_uint_func1))) {
|
||||
LOG_WARN("choose_get_int_func failed", K(ret), K(right_meta));
|
||||
} else if (OB_FAIL((reinterpret_cast<GetUIntFunc>(get_uint_func1)(right_meta, *right, true,
|
||||
right_uint, cast_mode)))) {
|
||||
LOG_WARN("get uint64 failed", K(ret), K(*right));
|
||||
} else {
|
||||
@ -4571,19 +4833,18 @@ int ObBitwiseExprOperator::calc_result2_oracle(const ObExpr &expr, ObEvalCtx &ct
|
||||
ObNumber result;
|
||||
void *get_int_func0 = NULL;
|
||||
void *get_int_func1 = NULL;
|
||||
const ObObjType &left_type = expr.args_[0]->datum_meta_.type_;
|
||||
const ObObjType &right_type = expr.args_[1]->datum_meta_.type_;
|
||||
|
||||
const ObDatumMeta &left_meta = expr.args_[0]->datum_meta_;
|
||||
const ObDatumMeta &right_meta = expr.args_[1]->datum_meta_;
|
||||
// choose_get_int_func可以想办法放到cg阶段,但是bitwise表达式
|
||||
// 应该不是性能敏感的地方
|
||||
if (OB_FAIL(choose_get_int_func(left_type, get_int_func0))) {
|
||||
LOG_WARN("choose_get_int_func failed", K(ret), K(left_type));
|
||||
} else if (OB_FAIL((reinterpret_cast<GetIntFunc>(get_int_func0)(*left, false,
|
||||
if (OB_FAIL(choose_get_int_func(left_meta, get_int_func0))) {
|
||||
LOG_WARN("choose_get_int_func failed", K(ret), K(left_meta));
|
||||
} else if (OB_FAIL((reinterpret_cast<GetIntFunc>(get_int_func0)(left_meta, *left, false,
|
||||
left_int, cast_mode)))) {
|
||||
LOG_WARN("get uint64 failed", K(ret), K(*left));
|
||||
} else if (OB_FAIL(choose_get_int_func(right_type, get_int_func1))) {
|
||||
LOG_WARN("choose_get_int_func failed", K(ret), K(right_type));
|
||||
} else if (OB_FAIL((reinterpret_cast<GetIntFunc>(get_int_func1)(*right, false,
|
||||
} else if (OB_FAIL(choose_get_int_func(right_meta, get_int_func1))) {
|
||||
LOG_WARN("choose_get_int_func failed", K(ret), K(right_meta));
|
||||
} else if (OB_FAIL((reinterpret_cast<GetIntFunc>(get_int_func1)(right_meta, *right, false,
|
||||
right_int, cast_mode)))) {
|
||||
LOG_WARN("get uint64 failed", K(ret), K(*right));
|
||||
} else if (OB_FAIL(result.from((left_int & right_int), tmp_alloc))) {
|
||||
@ -4625,9 +4886,10 @@ int ObBitwiseExprOperator::cg_bitwise_expr(ObExprCGCtx &expr_cg_ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObBitwiseExprOperator::choose_get_int_func(const ObObjType type, void *&out_func)
|
||||
int ObBitwiseExprOperator::choose_get_int_func(const ObDatumMeta datum_meta, void *&out_func)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObObjType type = datum_meta.get_type();
|
||||
if (ObNumberTC == ob_obj_type_class(type)) {
|
||||
if (lib::is_oracle_mode()) {
|
||||
out_func = reinterpret_cast<void*>(
|
||||
@ -4636,6 +4898,13 @@ int ObBitwiseExprOperator::choose_get_int_func(const ObObjType type, void *&out_
|
||||
out_func = reinterpret_cast<void*>(
|
||||
ObBitwiseExprOperator::get_uint64_from_number_type);
|
||||
}
|
||||
} else if (ObDecimalIntTC == ob_obj_type_class(type)) {
|
||||
if (lib::is_oracle_mode()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("type of params in bitwise expr is unexpected", K(ret), K(type));
|
||||
} else { // mysql mode
|
||||
out_func = reinterpret_cast<void*>(ObBitwiseExprOperator::get_uint64_from_decimalint_type);
|
||||
}
|
||||
} else {
|
||||
// 针对非number的输入,类型推导阶段会增加implicit cast将其转为int64/uint64
|
||||
if (lib::is_oracle_mode()) {
|
||||
@ -4647,32 +4916,38 @@ int ObBitwiseExprOperator::choose_get_int_func(const ObObjType type, void *&out_
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObBitwiseExprOperator::get_int64_from_int_tc(const ObDatum &datum, bool is_round,
|
||||
int64_t &out, const ObCastMode &cast_mode)
|
||||
int ObBitwiseExprOperator::get_int64_from_int_tc(
|
||||
const ObDatumMeta &datum_meta, const ObDatum &datum, bool is_round,
|
||||
int64_t &out, const ObCastMode &cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
UNUSED(is_round);
|
||||
UNUSED(cast_mode);
|
||||
UNUSED(datum_meta);
|
||||
out = datum.get_int();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObBitwiseExprOperator::get_uint64_from_int_tc(const ObDatum &datum, bool is_round,
|
||||
uint64_t &out, const ObCastMode &cast_mode)
|
||||
int ObBitwiseExprOperator::get_uint64_from_int_tc(
|
||||
const ObDatumMeta &datum_meta, const ObDatum &datum, bool is_round,
|
||||
uint64_t &out, const ObCastMode &cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
UNUSED(is_round);
|
||||
UNUSED(cast_mode);
|
||||
UNUSED(datum_meta);
|
||||
out = datum.get_uint();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObBitwiseExprOperator::get_int64_from_number_type(const ObDatum &datum,
|
||||
int ObBitwiseExprOperator::get_int64_from_number_type(const ObDatumMeta &datum_meta,
|
||||
const ObDatum &datum,
|
||||
bool is_round,
|
||||
int64_t &out,
|
||||
const ObCastMode &cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
UNUSED(datum_meta);
|
||||
int64_t tmp_int = 0;
|
||||
ObNumStackAllocator<> num_allocator;
|
||||
number::ObNumber nmb;
|
||||
@ -4692,12 +4967,14 @@ int ObBitwiseExprOperator::get_int64_from_number_type(const ObDatum &datum,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObBitwiseExprOperator::get_uint64_from_number_type(const ObDatum &datum,
|
||||
bool is_round,
|
||||
uint64_t &out,
|
||||
const ObCastMode &cast_mode)
|
||||
int ObBitwiseExprOperator::get_uint64_from_number_type(const ObDatumMeta &datum_meta,
|
||||
const ObDatum &datum,
|
||||
bool is_round,
|
||||
uint64_t &out,
|
||||
const ObCastMode &cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
UNUSED(datum_meta);
|
||||
ObNumStackAllocator<> num_allocator;
|
||||
number::ObNumber nmb;
|
||||
int64_t tmp_int = 0;
|
||||
@ -4720,6 +4997,43 @@ int ObBitwiseExprOperator::get_uint64_from_number_type(const ObDatum &datum,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObBitwiseExprOperator::get_uint64_from_decimalint_type(
|
||||
const ObDatumMeta &datum_meta, const common::ObDatum &datum, bool is_round,
|
||||
uint64_t &out, const common::ObCastMode &cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t tmp_int = 0;
|
||||
uint64_t tmp_uint = 0;
|
||||
ObDecimalIntBuilder builder;
|
||||
bool is_valid_int64 = true;
|
||||
bool is_valid_uint64 = true;
|
||||
if (false == is_round) { // this func is only used in mysql mode, is_round can only be true
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("is_round is false", K(ret));
|
||||
} else if (OB_FAIL(ObExprFuncRound::do_round_decimalint(datum_meta.precision_, datum_meta.scale_,
|
||||
DEFAULT_NUMBER_PRECISION_FOR_INTEGER, DEFAULT_NUMBER_SCALE_FOR_INTEGER, 0,
|
||||
datum, builder))) {
|
||||
LOG_WARN("do_round_decimalint failed", K(ret), K(datum_meta));
|
||||
} else if (OB_FAIL(wide::check_range_valid_int64(
|
||||
builder.get_decimal_int(), builder.get_int_bytes(), is_valid_int64, tmp_int))) {
|
||||
LOG_WARN("check_range_valid_int64 failed", K(ret), K(builder.get_int_bytes()));
|
||||
} else if (is_valid_int64) {
|
||||
out = static_cast<uint64_t>(tmp_int);
|
||||
} else if (OB_FAIL(wide::check_range_valid_uint64(
|
||||
builder.get_decimal_int(), builder.get_int_bytes(), is_valid_uint64, tmp_uint))) {
|
||||
LOG_WARN("check_range_valid_int64 failed", K(ret), K(builder.get_int_bytes()));
|
||||
} else if (is_valid_uint64) {
|
||||
out = tmp_uint;
|
||||
} else {
|
||||
ret = OB_ERR_TRUNCATED_WRONG_VALUE;
|
||||
if (CM_IS_WARN_ON_FAIL(cast_mode)) {
|
||||
ret = OB_SUCCESS;
|
||||
out = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObBitwiseExprOperator::get_int64(const ObObj &obj,
|
||||
ObExprCtx &expr_ctx,
|
||||
bool is_round,
|
||||
@ -4865,8 +5179,15 @@ int ObMinMaxExprOperator::aggregate_cmp_type_for_comparison(ObExprResType &type,
|
||||
ret = OB_INVALID_ARGUMENT; // not compatible input
|
||||
}
|
||||
}
|
||||
ObScale calc_scale = types[0].get_scale();
|
||||
for (int64_t i = 1; i < param_num; i++) {
|
||||
calc_scale = MAX(calc_scale, types[i].get_scale());
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
type.set_calc_type(cmp_type);
|
||||
if (ob_is_decimal_int(cmp_type)) {
|
||||
type.get_calc_meta().set_scale(calc_scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4878,7 +5199,8 @@ int ObMinMaxExprOperator::calc_result_meta_for_comparison(
|
||||
ObExprResType *types_stack,
|
||||
int64_t param_num,
|
||||
const ObCollationType coll_type,
|
||||
const ObLengthSemantics default_length_semantics) const
|
||||
const ObLengthSemantics default_length_semantics,
|
||||
const bool enable_decimal_int) const
|
||||
{
|
||||
UNUSED(default_length_semantics);
|
||||
int ret = OB_SUCCESS;
|
||||
@ -4926,15 +5248,23 @@ int ObMinMaxExprOperator::calc_result_meta_for_comparison(
|
||||
int64_t max_scale = 0;
|
||||
int64_t max_precision = 0;
|
||||
for (i = 0; i < param_num; ++i) {
|
||||
max_scale = MAX(max_scale, types_stack[i].get_mysql_compatible_scale());
|
||||
max_precision = MAX(max_precision, types_stack[i].get_precision());
|
||||
if (types_stack[i].is_integer_type()) { // integer scale is zero
|
||||
max_scale = MAX(max_scale, 0);
|
||||
} else if (!types_stack[i].is_null()) {
|
||||
max_scale = MAX(max_scale, types_stack[i].get_mysql_compatible_scale());
|
||||
max_precision = MAX(max_precision, types_stack[i].get_precision());
|
||||
}
|
||||
}
|
||||
ObScale result_scale = static_cast<ObScale>(NOT_FIXED_DEC == max_scale ? -1 : max_scale);
|
||||
const int64_t int32_max_precision = 11;
|
||||
if (result_scale > 0 && ob_is_int_tc(type.get_type())) {
|
||||
//兼容mysql行为,least(datetime/time/timestamp,int)结果类型为int
|
||||
//least(datetime(3)/time(3)/timestamp(3),int)结果类型为decimal。
|
||||
type.set_type(ObNumberType);
|
||||
if (enable_decimal_int) {
|
||||
type.set_type(ObDecimalIntType);
|
||||
} else {
|
||||
type.set_type(ObNumberType);
|
||||
}
|
||||
} else if (max_precision > int32_max_precision && ObInt32Type == type.get_type()) {
|
||||
//兼容mysql行为对类型进行提升。
|
||||
type.set_type(ObIntType);
|
||||
@ -4949,7 +5279,11 @@ int ObMinMaxExprOperator::calc_result_meta_for_comparison(
|
||||
}
|
||||
} else {
|
||||
type.set_scale(result_scale);
|
||||
type.set_precision(static_cast<ObPrecision>(max_precision + max_scale)); // esti, not accurate
|
||||
int16_t result_precision = max_precision + max_scale;
|
||||
if (ob_is_number_or_decimal_int_tc(type.get_type())) {
|
||||
result_precision = MIN(result_precision, OB_MAX_DECIMAL_POSSIBLE_PRECISION);
|
||||
}
|
||||
type.set_precision(static_cast<ObPrecision>(result_precision)); // esti, not accurate
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5972,6 +6306,8 @@ int ObRelationalExprOperator::cg_datum_cmp_expr(const ObRawExpr &raw_expr,
|
||||
rt_expr.args_[1]->obj_meta_.has_lob_header();
|
||||
const ObScale input_scale1 = rt_expr.args_[0]->datum_meta_.scale_;
|
||||
const ObScale input_scale2 = rt_expr.args_[1]->datum_meta_.scale_;
|
||||
const ObPrecision in_prec1 = rt_expr.args_[0]->datum_meta_.precision_;
|
||||
const ObPrecision in_prec2 = rt_expr.args_[1]->datum_meta_.precision_;
|
||||
LOG_DEBUG("CG Datum CMP Expr", K(input_type1), K(input_type2), K(cmp_op));
|
||||
const ObCollationType cs_type = rt_expr.args_[0]->datum_meta_.cs_type_;
|
||||
if (ObDatumFuncs::is_string_type(input_type1) && ObDatumFuncs::is_string_type(input_type2)) {
|
||||
@ -5979,11 +6315,11 @@ int ObRelationalExprOperator::cg_datum_cmp_expr(const ObRawExpr &raw_expr,
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
rt_expr.eval_func_ = ObExprCmpFuncsHelper::get_eval_expr_cmp_func(
|
||||
input_type1, input_type2, input_scale1, input_scale2, cmp_op, lib::is_oracle_mode(),
|
||||
cs_type, has_lob_header);
|
||||
input_type1, input_type2, input_scale1, input_scale2, in_prec1, in_prec2, cmp_op,
|
||||
lib::is_oracle_mode(), cs_type, has_lob_header);
|
||||
rt_expr.eval_batch_func_ = ObExprCmpFuncsHelper::get_eval_batch_expr_cmp_func(
|
||||
input_type1, input_type2, input_scale1, input_scale2, cmp_op, lib::is_oracle_mode(),
|
||||
cs_type, has_lob_header);
|
||||
input_type1, input_type2, input_scale1, input_scale2, in_prec1, in_prec2, cmp_op,
|
||||
lib::is_oracle_mode(), cs_type, has_lob_header);
|
||||
}
|
||||
CK(NULL != rt_expr.eval_func_);
|
||||
CK(NULL != rt_expr.eval_batch_func_);
|
||||
@ -6045,6 +6381,8 @@ int ObRelationalExprOperator::cg_row_cmp_expr(const int row_dimension,
|
||||
const ObObjType type2 = right_row->args_[i]->datum_meta_.type_;
|
||||
const ObScale scale1 = left_row->args_[i]->datum_meta_.scale_;
|
||||
const ObScale scale2 = right_row->args_[i]->datum_meta_.scale_;
|
||||
const ObPrecision prec1 = left_row->args_[i]->datum_meta_.precision_;
|
||||
const ObPrecision prec2 = right_row->args_[i]->datum_meta_.precision_;
|
||||
const ObCollationType cs_type = left_row->args_[i]->datum_meta_.cs_type_;
|
||||
const bool has_lob_header = left_row->args_[i]->obj_meta_.has_lob_header() ||
|
||||
right_row->args_[i]->obj_meta_.has_lob_header();
|
||||
@ -6054,12 +6392,14 @@ int ObRelationalExprOperator::cg_row_cmp_expr(const int row_dimension,
|
||||
rt_expr.inner_functions_[i] = (void*)ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
|
||||
type1, type2,
|
||||
scale1, scale2,
|
||||
prec1, prec2,
|
||||
lib::is_oracle_mode(),
|
||||
cs_type,
|
||||
has_lob_header);
|
||||
} else {
|
||||
rt_expr.inner_functions_[i] = (void *)ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
|
||||
type1, type2, scale1, scale2, lib::is_oracle_mode(), cs_type, has_lob_header);
|
||||
type1, type2, scale1, scale2, prec1, prec2, lib::is_oracle_mode(), cs_type,
|
||||
has_lob_header);
|
||||
if (OB_ISNULL(rt_expr.inner_functions_[i])) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null function", K(ret), K(i), K(type1), K(type2));
|
||||
|
||||
Reference in New Issue
Block a user