Fix query range extraction for decimal int

This commit is contained in:
Zach41 2024-05-23 06:14:54 +00:00 committed by ob-robot
parent 00299ae0ca
commit 3da40a4a98
4 changed files with 44 additions and 18 deletions

View File

@ -1249,10 +1249,10 @@ public:
// col < -12.2341 <=> col < -12.234
// define 1 & 4 as up mode: val = val + 1 if val >= 0
// define 2 & 3 as down mode: val = val - 1 if val < 0
static ObCastMode get_const_cast_mode(const ObExprOperatorType op_type,
static ObCastMode get_const_cast_mode(const common::ObCmpOp cmp_op,
const bool right_const_param)
{
ObCmpOp cmp_op = get_cmp_op(op_type);
ObCastMode cm = CM_NONE;
if (cmp_op >= CO_CMP) {
// do nothing
@ -1275,6 +1275,12 @@ public:
}
return cm;
}
static ObCastMode get_const_cast_mode(const ObExprOperatorType op_type,
const bool right_const_param)
{
ObCmpOp cmp_op = get_cmp_op(op_type);
return get_const_cast_mode(cmp_op, right_const_param);
}
OB_INLINE static common::ObCmpOp get_cmp_op(const ObExprOperatorType type) {
/*

View File

@ -16,6 +16,7 @@
#include "sql/rewrite/ob_query_range.h"
#include "sql/engine/expr/ob_expr_result_type_util.h"
#include "sql/optimizer/ob_optimizer_util.h"
#include "sql/engine/expr/ob_datum_cast.h"
namespace oceanbase
{
@ -1445,10 +1446,10 @@ int ObKeyPart::cast_value_type(const ObDataTypeCastParams &dtc_params, bool cont
ret = OB_ERR_UNEXPECTED;
LOG_WARN("keypart isn't normal key", K_(key_type));
} else if (OB_FAIL(ObKeyPart::try_cast_value(dtc_params, allocator_, pos_,
normal_keypart_->start_, start_cmp))) {
normal_keypart_->start_, start_cmp, common::CO_LE, true))) {
LOG_WARN("failed to try cast value type", K(ret));
} else if (OB_FAIL(ObKeyPart::try_cast_value(dtc_params, allocator_, pos_,
normal_keypart_->end_, end_cmp))) {
normal_keypart_->end_, end_cmp, common::CO_LE, false))) {
LOG_WARN("failed to try cast value type", K(ret));
} else {
if (start_cmp < 0) {
@ -1479,7 +1480,8 @@ int ObKeyPart::cast_value_type(const ObDataTypeCastParams &dtc_params, bool cont
}
int ObKeyPart::try_cast_value(const ObDataTypeCastParams &dtc_params, ObIAllocator &alloc,
const ObKeyPartPos &pos, ObObj &value, int64_t &cmp)
const ObKeyPartPos &pos, ObObj &value, int64_t &cmp,
common::ObCmpOp cmp_op /* CO_EQ */, bool left_border /*true*/)
{
int ret = OB_SUCCESS;
if (!value.is_min_value() && !value.is_max_value() && !value.is_unknown()
@ -1491,6 +1493,15 @@ int ObKeyPart::try_cast_value(const ObDataTypeCastParams &dtc_params, ObIAllocat
ObAccuracy acc(pos.column_type_.get_accuracy());
if (pos.column_type_.is_decimal_int()) {
cast_ctx.res_accuracy_ = &acc;
int32_t out_bytes = wide::ObDecimalIntConstValue::get_int_bytes_by_precision(acc.get_precision());
int32_t in_bytes = value.get_int_bytes();
ObScale out_scale = acc.get_scale();
ObScale in_scale = value.get_scale();
if ((value.is_decimal_int()
&& ObDatumCast::need_scale_decimalint(in_scale, in_bytes, out_scale, out_bytes))
|| !value.is_decimal_int()) {
cast_ctx.cast_mode_ = ObRelationalExprOperator::get_const_cast_mode(cmp_op, !left_border);
}
}
ObObj &tmp_start = value;
ObExpectType expect_type;

View File

@ -307,7 +307,8 @@ public:
void reset_key();
typedef common::hash::ObHashMap<int64_t, ObSEArray<int64_t, 16>> SameValIdxMap;
static int try_cast_value(const ObDataTypeCastParams &dtc_params, ObIAllocator &alloc,
const ObKeyPartPos &pos, ObObj &value, int64_t &cmp);
const ObKeyPartPos &pos, ObObj &value, int64_t &cmp,
common::ObCmpOp cmp_op = CO_EQ, bool left_border = true);
inline bool operator <=(const ObKeyPart &other) const { return pos_.offset_ <= other.pos_.offset_; }
inline void set_normal_start(ObKeyPart *other)

View File

@ -7625,12 +7625,16 @@ if (OB_SUCC(ret) ) { \
if (!start.is_min_value() && !start.is_max_value() && !start.is_unknown() \
&& (!ObSQLUtils::is_same_type_for_compare(start.get_meta(), column_type.get_obj_meta()) || start.is_decimal_int())) { \
ObCastMode cm = CM_WARN_ON_FAIL;\
if (ObDecimalIntType == expect_type.get_type() && start.is_decimal_int()) {\
int32_t in_bytes = wide::ObDecimalIntConstValue::get_int_bytes_by_precision(column_type.get_accuracy().get_precision());\
ObScale in_scale = column_type.get_accuracy().get_scale();\
int32_t out_bytes = start.get_int_bytes();\
ObScale out_scale = start.get_scale();\
if (ObDatumCast::need_scale_decimalint(in_scale, in_bytes, out_scale, out_bytes)) {\
if (ObDecimalIntType == expect_type.get_type()) {\
if (start.is_decimal_int()) {\
int32_t in_bytes = wide::ObDecimalIntConstValue::get_int_bytes_by_precision(column_type.get_accuracy().get_precision());\
ObScale in_scale = column_type.get_accuracy().get_scale();\
int32_t out_bytes = start.get_int_bytes();\
ObScale out_scale = start.get_scale();\
if (ObDatumCast::need_scale_decimalint(in_scale, in_bytes, out_scale, out_bytes)) {\
cm |= ObRelationalExprOperator::get_const_cast_mode(T_OP_GE, true);\
}\
} else {\
cm |= ObRelationalExprOperator::get_const_cast_mode(T_OP_GE, true);\
}\
}\
@ -7669,12 +7673,16 @@ if (OB_SUCC(ret) ) { \
if (!end.is_min_value() && !end.is_max_value() && !end.is_unknown() \
&& (!ObSQLUtils::is_same_type_for_compare(end.get_meta(), column_type.get_obj_meta()) || end.is_decimal_int())) { \
ObCastMode cm = CM_WARN_ON_FAIL;\
if (ObDecimalIntType == expect_type.get_type() && end.is_decimal_int()) {\
int32_t in_bytes = wide::ObDecimalIntConstValue::get_int_bytes_by_precision(column_type.get_accuracy().get_precision());\
ObScale in_scale = column_type.get_accuracy().get_scale();\
int32_t out_bytes = start.get_int_bytes();\
ObScale out_scale = start.get_scale();\
if (ObDatumCast::need_scale_decimalint(in_scale, in_bytes, out_scale, out_bytes)) {\
if (ObDecimalIntType == expect_type.get_type()) {\
if (end.is_decimal_int()) {\
int32_t in_bytes = wide::ObDecimalIntConstValue::get_int_bytes_by_precision(column_type.get_accuracy().get_precision());\
ObScale in_scale = column_type.get_accuracy().get_scale();\
int32_t out_bytes = start.get_int_bytes();\
ObScale out_scale = start.get_scale();\
if (ObDatumCast::need_scale_decimalint(in_scale, in_bytes, out_scale, out_bytes)) {\
cm |= ObRelationalExprOperator::get_const_cast_mode(T_OP_LE, true);\
}\
} else {\
cm |= ObRelationalExprOperator::get_const_cast_mode(T_OP_LE, true);\
}\
}\