[FEAT MERGE] Support float/double(m, d) in mysql mode

This commit is contained in:
hezuojiao 2022-12-29 12:09:23 +00:00 committed by ob-robot
parent d967637528
commit 26f2754db2
58 changed files with 695 additions and 118 deletions

View File

@ -301,6 +301,9 @@ bool is_calc_with_end_space(ObObjType type1, ObObjType type2,
: CR_EQ; \
}
#define IS_FIXED_DOUBLE_CMP obj1.is_fixed_double() && obj2.is_fixed_double() && \
lib::is_mysql_mode()
#define DEFINE_CMP_OP_FUNC_REAL_REAL_EQ(real1_tc, real1_type, real2_tc, real2_type) \
template <> inline \
int ObObjCmpFuncs::cmp_op_func<real1_tc, real2_tc, CO_EQ>(const ObObj &obj1, \
@ -320,6 +323,8 @@ bool is_calc_with_end_space(ObObjType type1, ObObjType type2,
} else {\
ret = CR_FALSE;\
}\
} else if (IS_FIXED_DOUBLE_CMP) {\
ret = fixed_double_cmp(obj1, obj2) == 0 ? CR_TRUE : CR_FALSE;\
} else {\
ret = (l_num == r_num ? CR_TRUE : CR_FALSE);\
}\
@ -345,6 +350,8 @@ bool is_calc_with_end_space(ObObjType type1, ObObjType type2,
} else {\
ret = CR_TRUE;\
}\
} else if (IS_FIXED_DOUBLE_CMP) {\
ret = fixed_double_cmp(obj1, obj2) <= 0 ? CR_TRUE : CR_FALSE;\
} else {\
ret = (l_num <= r_num ? CR_TRUE : CR_FALSE);\
}\
@ -370,6 +377,8 @@ bool is_calc_with_end_space(ObObjType type1, ObObjType type2,
} else {\
ret = CR_TRUE;\
}\
} else if (IS_FIXED_DOUBLE_CMP) {\
ret = fixed_double_cmp(obj1, obj2) < 0 ? CR_TRUE : CR_FALSE;\
} else {\
ret = (l_num < r_num ? CR_TRUE : CR_FALSE);\
}\
@ -395,6 +404,8 @@ bool is_calc_with_end_space(ObObjType type1, ObObjType type2,
} else {\
ret = CR_FALSE;\
}\
} else if (IS_FIXED_DOUBLE_CMP) {\
ret = fixed_double_cmp(obj1, obj2) >= 0 ? CR_TRUE : CR_FALSE;\
} else {\
ret = (l_num >= r_num ? CR_TRUE : CR_FALSE);\
}\
@ -420,6 +431,8 @@ bool is_calc_with_end_space(ObObjType type1, ObObjType type2,
} else {\
ret = CR_FALSE;\
}\
} else if (IS_FIXED_DOUBLE_CMP) {\
ret = fixed_double_cmp(obj1, obj2) > 0 ? CR_TRUE : CR_FALSE;\
} else {\
ret = (l_num > r_num ? CR_TRUE : CR_FALSE);\
}\
@ -443,6 +456,8 @@ bool is_calc_with_end_space(ObObjType type1, ObObjType type2,
} else {\
ret = CR_TRUE;\
}\
} else if (IS_FIXED_DOUBLE_CMP) {\
ret = fixed_double_cmp(obj1, obj2) != 0 ? CR_TRUE : CR_FALSE;\
} else {\
ret = (l_num != r_num ? CR_TRUE : CR_FALSE);\
}\
@ -468,6 +483,9 @@ bool is_calc_with_end_space(ObObjType type1, ObObjType type2,
} else {\
ret = CR_LT;\
}\
} else if (IS_FIXED_DOUBLE_CMP) {\
int cmp_res = fixed_double_cmp(obj1, obj2);\
ret = cmp_res == 0 ? CR_EQ : (cmp_res < 0 ? CR_LT : CR_GT);\
} else {\
ret = l_num == r_num ? CR_EQ : (l_num < r_num ? CR_LT : CR_GT);\
}\

View File

@ -237,6 +237,36 @@ public:
ObCmpOp cmp_op,
obj_cmp_func_nullsafe &func);
OB_INLINE static int fixed_double_cmp(const ObObj &obj1, const ObObj &obj2)
{
int ret = 0;
const double P[] =
{
5/1e000, 5/1e001, 5/1e002, 5/1e003, 5/1e004, 5/1e005, 5/1e006, 5/1e007,
5/1e008, 5/1e009, 5/1e010, 5/1e011, 5/1e012, 5/1e013, 5/1e014, 5/1e015,
5/1e016, 5/1e017, 5/1e018, 5/1e019, 5/1e020, 5/1e021, 5/1e022, 5/1e023,
5/1e024, 5/1e025, 5/1e026, 5/1e027, 5/1e028, 5/1e029, 5/1e030, 5/1e031
};
// Compatible with mysql, the condition for judging whether two fixed double are equal
// is that their fabs is less than 5 divided by the log10 of the maximum scale plus 1.
const int cmp_scale = MAX(obj1.get_scale(), obj2.get_scale()) + 1;
double p = 0;
if (cmp_scale <= 0 || cmp_scale > OB_NOT_FIXED_SCALE) {
p = P[OB_NOT_FIXED_SCALE];
COMMON_LOG(ERROR, "not fixed obj", K(obj1), K(obj2), K(lbt()));
} else {
p = P[cmp_scale];
}
const double l = obj1.get_double();
const double r = obj2.get_double();
if (l == r || fabs(l - r) < p) {
ret = 0;
} else {
ret = (l < r ? -1 : 1);
}
return ret;
}
enum ObCmpRes
{
// for bool.

View File

@ -288,9 +288,31 @@ template <>
v = 0.0; \
} else if (isnan(v)) { \
v = NAN; \
} \
} else if (obj.is_fixed_double() && lib::is_mysql_mode()) { \
char buf[OB_CAST_TO_VARCHAR_MAX_LENGTH] = {0}; \
int64_t len = ob_fcvt(v, static_cast<int>(obj.get_scale()), sizeof(buf) - 1, buf, NULL); \
return murmurhash(buf, static_cast<int32_t>(len), ret); \
} \
return murmurhash(&v, sizeof(obj.get_##TYPE()), ret); \
} \
template <typename T> \
struct ObjHashCalculator<OBJTYPE, T, ObObj> \
{ \
static uint64_t calc_hash_value(const ObObj &obj, const uint64_t hash) { \
VTYPE v = obj.get_##TYPE(); \
HTYPE v2 = v; \
if (0.0 == v2) { \
v2 = 0.0; \
} else if (isnan(v2)) { \
v2 = NAN; \
} else if (obj.is_fixed_double() && lib::is_mysql_mode()) { \
char buf[OB_CAST_TO_VARCHAR_MAX_LENGTH] = {0}; \
int64_t len = ob_fcvt(v2, static_cast<int>(obj.get_scale()), sizeof(buf) - 1, buf, NULL); \
return T::hash(buf, static_cast<int32_t>(len), hash); \
} \
return T::hash(&v2, sizeof(v2), hash); \
} \
}; \
template <typename T, typename P> \
struct ObjHashCalculator<OBJTYPE, T, P> \
{ \

View File

@ -1193,6 +1193,8 @@ public:
OB_INLINE bool is_blob_locator() const { return meta_.is_blob_locator(); }
OB_INLINE bool is_clob_locator() const { return meta_.is_clob_locator(); }
OB_INLINE bool is_lob_locator() const { return meta_.is_lob_locator(); }
OB_INLINE bool is_fixed_double() const { return meta_.is_double() &&
SCALE_UNKNOWN_YET < meta_.get_scale() && OB_MAX_DOUBLE_FLOAT_SCALE >= meta_.get_scale(); }
OB_INLINE bool is_string_or_lob_locator_type() const {
return meta_.is_string_or_lob_locator_type();
}

View File

@ -18,6 +18,7 @@
#include "common/rowkey/ob_rowkey_info.h"
#include "common/object/ob_object.h"
#include "common/object/ob_obj_type.h"
#include "common/object/ob_obj_compare.h"
namespace oceanbase
{
@ -104,7 +105,13 @@ int ObRowkey::equal(const ObRowkey &rhs, bool &is_equal) const
is_equal = (obj.v_.float_ == rhs_obj.v_.float_);
break;
case ObDoubleTC:
is_equal = (obj.v_.double_ == rhs_obj.v_.double_);
{
if (lib::is_mysql_mode() && obj.is_fixed_double() && rhs_obj.is_fixed_double()) {
is_equal = ObObjCmpFuncs::fixed_double_cmp(obj, rhs_obj) == 0;
} else {
is_equal = (obj.v_.double_ == rhs_obj.v_.double_);
}
}
break;
case ObOTimestampTC:
is_equal = (obj.time_ctx_.desc_ == rhs_obj.time_ctx_.desc_ && obj.v_.datetime_ == rhs_obj.v_.datetime_);
@ -203,7 +210,13 @@ bool ObRowkey::simple_equal(const ObRowkey &rhs) const
ret = (obj.v_.float_ == rhs_obj.v_.float_);
break;
case ObDoubleTC:
ret = (obj.v_.double_ == rhs_obj.v_.double_);
{
if (lib::is_mysql_mode() && obj.is_fixed_double() && rhs_obj.is_fixed_double()) {
ret = ObObjCmpFuncs::fixed_double_cmp(obj, rhs_obj) == 0;
} else {
ret = (obj.v_.double_ == rhs_obj.v_.double_);
}
}
break;
case ObOTimestampTC:
ret = (obj.time_ctx_.desc_ == rhs_obj.time_ctx_.desc_ && obj.v_.datetime_ == rhs_obj.v_.datetime_);

View File

@ -1583,6 +1583,7 @@ const double OB_PRECISION_BINARY_TO_DECIMAL_FACTOR = 0.30103;
const double OB_PRECISION_DECIMAL_TO_BINARY_FACTOR = 3.32193;
const int64_t OB_MAX_DOUBLE_FLOAT_SCALE = 30;
const int64_t OB_NOT_FIXED_SCALE = OB_MAX_DOUBLE_FLOAT_SCALE + 1;
const int64_t OB_MAX_DOUBLE_FLOAT_PRECISION = 53;//why?? mysql is 255 TODO::@yanhua
const int64_t OB_MAX_FLOAT_PRECISION = 24;
const int64_t OB_MAX_INTEGER_DISPLAY_WIDTH = 255; //TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT

View File

@ -431,6 +431,7 @@ public:
const common::ObLobLocator &lob_locator, int64_t &pos);
static int json_cell_str(char *buf, const int64_t len, const ObString &val, int64_t &pos);
static int geometry_cell_str(char *buf, const int64_t len, const ObString &val, int64_t &pos);
static inline int16_t float_length(const int16_t scale);
public:
static const uint64_t NULL_;
@ -737,6 +738,14 @@ void ObMySQLUtil::get_uint8(char *&pos, uint64_t &v)
}
}
/*
* get precision for double type, keep same with MySQL
*/
int16_t ObMySQLUtil::float_length(const int16_t scale)
{
return (scale >= 0 && scale <= OB_MAX_DOUBLE_FLOAT_SCALE) ? DBL_DIG + 2 + scale : DBL_DIG + 8;
}
} // namespace obmysql
} // namespace oceanbase

View File

@ -120,6 +120,32 @@ struct ObDatumTCCmp<ObFloatTC, ObFloatTC> : public ObDefined<>
}
};
template <ObScale SCALE>
struct ObFixedDoubleCmp: public ObDefined<>
{
constexpr static double LOG_10[] =
{
1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007,
1e008, 1e009, 1e010, 1e011, 1e012, 1e013, 1e014, 1e015,
1e016, 1e017, 1e018, 1e019, 1e020, 1e021, 1e022, 1e023,
1e024, 1e025, 1e026, 1e027, 1e028, 1e029, 1e030, 1e031
};
constexpr static double P = 5 / LOG_10[SCALE + 1];
inline static int cmp(const ObDatum &l_datum, const ObDatum &r_datum)
{
int ret = 0;
const double l = l_datum.get_double();
const double r = r_datum.get_double();
if (l == r || fabs(l - r) < P) {
ret = 0;
} else {
ret = (l < r ? -1 : 1);
}
return ret;
}
};
template <>
struct ObDatumTCCmp<ObDoubleTC, ObDoubleTC> : public ObDatumTCCmp<ObFloatTC, ObFloatTC>
{

View File

@ -76,6 +76,24 @@ struct ObNullSafeDatumStrCmp
}
};
template <ObScale SCALE, bool NULL_FIRST>
struct ObNullSafeFixedDoubleCmp
{
inline static int cmp(const ObDatum &l, const ObDatum &r) {
int ret = 0;
if (OB_UNLIKELY(l.is_null()) && OB_UNLIKELY(r.is_null())) {
ret = 0;
} else if (OB_UNLIKELY(l.is_null())) {
ret = NULL_FIRST ? -1 : 1;
} else if (OB_UNLIKELY(r.is_null())) {
ret = NULL_FIRST ? 1 : -1;
} else {
ret = datum_cmp::ObFixedDoubleCmp<SCALE>::cmp(l, r);
}
return ret;
}
};
static ObDatumCmpFuncType NULLSAFE_TYPE_CMP_FUNCS[ObMaxType][ObMaxType][2];
// init type type compare function array
template <int X, int Y>
@ -153,9 +171,24 @@ struct InitStrCmpArray
bool g_str_cmp_array_inited = ObArrayConstIniter<CS_TYPE_MAX, InitStrCmpArray>::init();
static ObDatumCmpFuncType FIXED_DOUBLE_CMP_FUNCS[OB_NOT_FIXED_SCALE][2];
template <int X>
struct InitFixedDoubleCmpArray
{
static void init_array()
{
auto &funcs = FIXED_DOUBLE_CMP_FUNCS;
funcs[X][0] = ObNullSafeFixedDoubleCmp<static_cast<ObScale>(X), false>::cmp;
funcs[X][1] = ObNullSafeFixedDoubleCmp<static_cast<ObScale>(X), true>::cmp;
}
};
bool g_fixed_double_cmp_array_inited =
ObArrayConstIniter<OB_NOT_FIXED_SCALE, InitFixedDoubleCmpArray>::init();
ObDatumCmpFuncType ObDatumFuncs::get_nullsafe_cmp_func(
const ObObjType type1, const ObObjType type2, const ObCmpNullPos null_pos,
const ObCollationType cs_type, const bool is_oracle_mode) {
const ObCollationType cs_type, const ObScale max_scale, const bool is_oracle_mode) {
OB_ASSERT(type1 >= ObNullType && type1 < ObMaxType);
OB_ASSERT(type2 >= ObNullType && type2 < ObMaxType);
OB_ASSERT(cs_type > CS_TYPE_INVALID && cs_type < CS_TYPE_MAX);
@ -163,7 +196,10 @@ ObDatumCmpFuncType ObDatumFuncs::get_nullsafe_cmp_func(
ObDatumCmpFuncType func_ptr = NULL;
int null_pos_idx = NULL_LAST == null_pos ? 0 : 1;
if (!is_string_type(type1) || !is_string_type(type2)) {
if (!is_oracle_mode && ob_is_double_type(type1) && ob_is_double_type(type1)
&& max_scale > SCALE_UNKNOWN_YET && max_scale < OB_NOT_FIXED_SCALE) {
func_ptr = FIXED_DOUBLE_CMP_FUNCS[max_scale][null_pos_idx];
} else if (!is_string_type(type1) || !is_string_type(type2)) {
func_ptr = NULLSAFE_TYPE_CMP_FUNCS[type1][type2][null_pos_idx];
} else {
int64_t calc_with_end_space_idx =
@ -263,6 +299,19 @@ struct DatumStrHashCalculator<cs_type, calc_end_space, T, true> : public DefHash
}
};
template <ObScale SCALE, typename T>
struct DatumFixedDoubleHashCalculator : public DefHashMethod<T>
{
static uint64_t calc_datum_hash(const ObDatum &datum, const uint64_t seed)
{
// format fixed double to string first, then calc hash value of the string
const double d_val = datum.get_double();
char buf[OB_CAST_TO_VARCHAR_MAX_LENGTH] = {0};
int64_t length = ob_fcvt(d_val, static_cast<int>(SCALE), sizeof(buf) - 1, buf, NULL);
return T::hash(buf, static_cast<int32_t>(length), seed);
}
};
template <typename T, bool IS_VEC>
struct VectorIter
{
@ -417,13 +466,37 @@ struct InitBasicStrFuncArray
}
};
static ObExprBasicFuncs FIXED_DOUBLE_BASIC_FUNCS[OB_NOT_FIXED_SCALE];
template <int X>
struct InitFixedDoubleBasicFuncArray
{
template <typename T>
using Hash = DefHashFunc<DatumFixedDoubleHashCalculator<static_cast<ObScale>(X), T>>;
static void init_array()
{
auto &basic_funcs = FIXED_DOUBLE_BASIC_FUNCS;
basic_funcs[X].default_hash_ = Hash<ObDefaultHash>::hash;
basic_funcs[X].default_hash_batch_= Hash<ObDefaultHash>::hash_batch;
basic_funcs[X].murmur_hash_ = Hash<ObMurmurHash>::hash;
basic_funcs[X].murmur_hash_batch_ = Hash<ObMurmurHash>::hash_batch;
basic_funcs[X].xx_hash_ = Hash<ObXxHash>::hash;
basic_funcs[X].xx_hash_batch_ = Hash<ObXxHash>::hash_batch;
basic_funcs[X].wy_hash_ = Hash<ObWyHash>::hash;
basic_funcs[X].wy_hash_batch_ = Hash<ObWyHash>::hash_batch;
basic_funcs[X].null_first_cmp_ = ObNullSafeFixedDoubleCmp<static_cast<ObScale>(X), true>::cmp;
basic_funcs[X].null_last_cmp_ = ObNullSafeFixedDoubleCmp<static_cast<ObScale>(X), false>::cmp;
}
};
bool g_basic_funcs_array_inited = ObArrayConstIniter<ObMaxType, InitBasicFuncArray>::init();
bool g_basic_str_array_inited = Ob2DArrayConstIniter<CS_TYPE_MAX, 2, InitBasicStrFuncArray>::init();
bool g_fixed_double_basic_func_array_inited =
ObArrayConstIniter<OB_NOT_FIXED_SCALE, InitFixedDoubleBasicFuncArray>::init();
ObExprBasicFuncs* ObDatumFuncs::get_basic_func(const ObObjType type,
const ObCollationType cs_type,
const bool is_oracle_mode)
const ObScale scale,
const bool is_oracle_mode)
{
ObExprBasicFuncs *res = NULL;
if ((type >= ObNullType && type < ObMaxType)) {
@ -437,6 +510,9 @@ ObExprBasicFuncs* ObDatumFuncs::get_basic_func(const ObObjType type,
bool calc_end_space = false;
bool is_lob_locator = true;
res = &EXPR_BASIC_STR_FUNCS[cs_type][calc_end_space][is_lob_locator];
} else if (!is_oracle_mode && ob_is_double_type(type) &&
scale > SCALE_UNKNOWN_YET && scale < OB_NOT_FIXED_SCALE) {
res = &FIXED_DOUBLE_BASIC_FUNCS[scale];
} else {
res = &EXPR_BASIC_FUNCS[type];
}
@ -475,6 +551,12 @@ REG_SER_FUNC_ARRAY(OB_SFA_DATUM_NULLSAFE_STR_CMP,
NULLSAFE_STR_CMP_FUNCS,
sizeof(NULLSAFE_STR_CMP_FUNCS) / sizeof(void*));
static_assert(OB_NOT_FIXED_SCALE * 2 == sizeof(FIXED_DOUBLE_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_FIXED_DOUBLE_NULLSAFE_CMP,
FIXED_DOUBLE_CMP_FUNCS,
sizeof(FIXED_DOUBLE_CMP_FUNCS) / sizeof(void *));
// When new function add to ObExprBasicFuncs, EXPR_BASIC_FUNCS should split into
// multi arrays for register.
struct ExprBasicFuncSerPart1
@ -510,6 +592,8 @@ static ExprBasicFuncSerPart1 EXPR_BASIC_FUNCS_PART1[ObMaxType];
static ExprBasicFuncSerPart2 EXPR_BASIC_FUNCS_PART2[ObMaxType];
static ExprBasicFuncSerPart1 EXPR_BASIC_STR_FUNCS_PART1[CS_TYPE_MAX][2][2];
static ExprBasicFuncSerPart2 EXPR_BASIC_STR_FUNCS_PART2[CS_TYPE_MAX][2][2];
static ExprBasicFuncSerPart1 EXPR_BASIC_FIXED_DOUBLE_FUNCS_PART1[OB_NOT_FIXED_SCALE];
static ExprBasicFuncSerPart2 EXPR_BASIC_FIXED_DOUBLE_FUNCS_PART2[OB_NOT_FIXED_SCALE];
bool split_basic_func_for_ser(void)
{
@ -523,6 +607,10 @@ bool split_basic_func_for_ser(void)
reinterpret_cast<ExprBasicFuncSerPart2 *>(EXPR_BASIC_STR_FUNCS_PART2)[i].from(
reinterpret_cast<ObExprBasicFuncs *>(EXPR_BASIC_STR_FUNCS)[i]);
}
for (int64_t i = 0; i < sizeof(FIXED_DOUBLE_BASIC_FUNCS)/sizeof(ObExprBasicFuncs); i++) {
EXPR_BASIC_FIXED_DOUBLE_FUNCS_PART1[i].from(FIXED_DOUBLE_BASIC_FUNCS[i]);
EXPR_BASIC_FIXED_DOUBLE_FUNCS_PART2[i].from(FIXED_DOUBLE_BASIC_FUNCS[i]);
}
return true;
}
bool g_split_basic_func_for_ser = split_basic_func_for_ser();
@ -547,5 +635,14 @@ REG_SER_FUNC_ARRAY(OB_SFA_EXPR_STR_BASIC_PART2,
EXPR_BASIC_STR_FUNCS_PART2,
sizeof(EXPR_BASIC_STR_FUNCS_PART2) / sizeof(void *));
static_assert(OB_NOT_FIXED_SCALE * 10 == sizeof(FIXED_DOUBLE_BASIC_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_FIXED_DOUBLE_BASIC_PART1,
EXPR_BASIC_FIXED_DOUBLE_FUNCS_PART1,
sizeof(EXPR_BASIC_FIXED_DOUBLE_FUNCS_PART1) / sizeof(void *));
REG_SER_FUNC_ARRAY(OB_SFA_FIXED_DOUBLE_BASIC_PART2,
EXPR_BASIC_FIXED_DOUBLE_FUNCS_PART2,
sizeof(EXPR_BASIC_FIXED_DOUBLE_FUNCS_PART2) / sizeof(void *));
} // end namespace sql
} // end namespace oceanbase

View File

@ -32,6 +32,7 @@ public:
const ObObjType type2,
const ObCmpNullPos null_pos,
const ObCollationType cs_type,
const ObScale max_scale,
const bool is_oracle_mode);
static bool is_string_type(const ObObjType type);
static bool is_json(const ObObjType type);
@ -39,8 +40,17 @@ public:
static bool is_varying_len_char_type(const ObObjType type, const ObCollationType cs_type) {
return (type == ObNVarchar2Type || (type == ObVarcharType && cs_type != CS_TYPE_BINARY));
}
static ObScale max_scale(const ObScale s1, const ObScale s2)
{
ObScale max_scale = SCALE_UNKNOWN_YET;
if (s1 != SCALE_UNKNOWN_YET && s2 != SCALE_UNKNOWN_YET) {
max_scale = MAX(s1, s2);
}
return max_scale;
}
static sql::ObExprBasicFuncs* get_basic_func(const ObObjType type,
const ObCollationType cs_type,
const ObScale scale = SCALE_UNKNOWN_YET,
const bool is_oracle_mode = lib::is_oracle_mode());
};

View File

@ -203,6 +203,15 @@ int check_convert_str_err(const char *str,
const int32_t len,
const int err,
const ObCollationType &in_cs_type);
// decimal(aka NumberType) cast to double/float precision increment. If it is an unsigned decimal,
// don’t need to increment precision, otherwise increment 1 to cover sign bit. If scale is
// equal to 0, don’t need to increment precision, otherwise increment 1 to cover dot bit.
inline int16_t decimal_to_double_precision_inc(const ObObjType type, const ObScale s)
{
return ((type == ObUNumberType) ? 0 : 1) + ((s > 0) ? 1 : 0);
}
} // end namespace common
} // end namespace oceanbase

View File

@ -1121,6 +1121,7 @@ int ObStaticEngineCG::generate_spec(
expr->datum_meta_.type_,
NULL_LAST,//这里null last还是first无所谓
expr->datum_meta_.cs_type_,
expr->datum_meta_.scale_,
lib::is_oracle_mode());
ObHashFunc hash_func;
hash_func.hash_func_ = expr->basic_funcs_->murmur_hash_;
@ -1254,6 +1255,7 @@ int ObStaticEngineCG::generate_hash_set_spec(ObLogSet &op, ObHashSetSpec &spec)
expr->datum_meta_.type_,
field_collation.null_pos_,
field_collation.cs_type_,
expr->datum_meta_.scale_,
lib::is_oracle_mode());
ObHashFunc hash_func;
hash_func.hash_func_ = expr->basic_funcs_->murmur_hash_;
@ -1423,6 +1425,7 @@ int ObStaticEngineCG::generate_merge_set_spec(ObLogSet &op, ObMergeSetSpec &spec
expr->datum_meta_.type_,
field_collation.null_pos_,
field_collation.cs_type_,
expr->datum_meta_.scale_,
lib::is_oracle_mode());
if (OB_ISNULL(cmp_func.cmp_func_)) {
ret = OB_ERR_UNEXPECTED;
@ -1595,6 +1598,7 @@ int ObStaticEngineCG::fill_sort_funcs(
expr->datum_meta_.type_,
sort_collation.null_pos_,
sort_collation.cs_type_,
expr->datum_meta_.scale_,
lib::is_oracle_mode());
if (OB_ISNULL(cmp_func.cmp_func_)) {
ret = OB_ERR_UNEXPECTED;
@ -3759,6 +3763,7 @@ int ObStaticEngineCG::generate_pump_exprs(ObLogJoin &op, ObNLConnectBySpecBase &
expr->datum_meta_.type_,
NULL_LAST,//这里null last还是first无所谓
expr->datum_meta_.cs_type_,
expr->datum_meta_.scale_,
lib::is_oracle_mode());
if (OB_ISNULL(cmp_func.cmp_func_)) {
ret = OB_ERR_UNEXPECTED;
@ -4002,8 +4007,9 @@ int ObStaticEngineCG::generate_join_spec(ObLogJoin &op, ObJoinSpec &spec)
ObDatumMeta &r = equal_cond_info.expr_->args_[1]->datum_meta_;
CK(l.cs_type_ == r.cs_type_);
if (OB_SUCC(ret)) {
const ObScale scale = ObDatumFuncs::max_scale(l.scale_, r.scale_);
equal_cond_info.ns_cmp_func_ = ObDatumFuncs::get_nullsafe_cmp_func(l.type_,
r.type_, default_null_pos(), l.cs_type_, is_oracle_mode());
r.type_, default_null_pos(), l.cs_type_, scale, is_oracle_mode());
CK(OB_NOT_NULL(equal_cond_info.ns_cmp_func_));
OZ(calc_equal_cond_opposite(op, *raw_expr, equal_cond_info.is_opposite_));
OZ(mj_spec.equal_cond_infos_.push_back(equal_cond_info));
@ -5118,6 +5124,7 @@ int ObStaticEngineCG::fill_aggr_info(ObAggFunRawExpr &raw_expr,
expr->datum_meta_.type_,
field_collation.null_pos_,
field_collation.cs_type_,
expr->datum_meta_.scale_,
lib::is_oracle_mode());
if (OB_ISNULL(cmp_func.cmp_func_)) {
ret = OB_ERR_UNEXPECTED;
@ -5619,6 +5626,7 @@ int ObStaticEngineCG::fil_sort_info(const ObIArray<OrderItem> &sort_keys,
expr->datum_meta_.type_,
field_collation.null_pos_,
field_collation.cs_type_,
expr->datum_meta_.scale_,
lib::is_oracle_mode());
if (OB_ISNULL(cmp_func.cmp_func_)) {
ret = OB_ERR_UNEXPECTED;

View File

@ -1100,7 +1100,8 @@ int ObStaticEngineExprCG::cg_expr_basic_funcs(const ObIArray<ObRawExpr *> &raw_e
LOG_WARN("rt expr is null", K(ret), K(*raw_exprs.at(i)));
} else {
rt_expr->basic_funcs_ = ObDatumFuncs::get_basic_func(rt_expr->datum_meta_.type_,
rt_expr->datum_meta_.cs_type_);
rt_expr->datum_meta_.cs_type_,
rt_expr->datum_meta_.scale_);
CK(NULL != rt_expr->basic_funcs_);
}
}

View File

@ -693,6 +693,7 @@ int ObHashGroupByOp::init_distinct_info(bool is_part)
expr->datum_meta_.type_,
NULL_LAST,//这里null last还是first无所谓
expr->datum_meta_.cs_type_,
expr->datum_meta_.scale_,
lib::is_oracle_mode());
hash_func.hash_func_ = expr->basic_funcs_->murmur_hash_;
hash_func.batch_hash_func_ = expr->basic_funcs_->murmur_hash_batch_;

View File

@ -185,7 +185,8 @@ OB_DEF_DESERIALIZE(ObExpr)
}
if (OB_SUCC(ret)) {
basic_funcs_ = ObDatumFuncs::get_basic_func(datum_meta_.type_, datum_meta_.cs_type_);
basic_funcs_ = ObDatumFuncs::get_basic_func(datum_meta_.type_, datum_meta_.cs_type_,
datum_meta_.scale_);
CK(NULL != basic_funcs_);
}
if (is_batch_result()) {

View File

@ -283,6 +283,9 @@ int ObExprAbs::calc_result_type1(ObExprResType &type, ObExprResType &type1,
if (lib::is_oracle_mode() && (type1.is_varchar_or_char() || type1.is_number_float())) {
type.set_precision(PRECISION_UNKNOWN_YET);
type.set_scale(ORA_NUMBER_SCALE_UNKNOWN_YET);
} else if (lib::is_mysql_mode() && type.is_double() && type1.get_scale() != SCALE_UNKNOWN_YET) {
type.set_scale(type1.get_scale());
type.set_precision(static_cast<ObPrecision>(ObMySQLUtil::float_length(type1.get_scale())));
} else {
type.set_accuracy(type1.get_accuracy());
}

View File

@ -69,11 +69,15 @@ int ObExprAdd::calc_result_type2(ObExprResType &type,
} else {
ObScale scale1 = static_cast<ObScale>(MAX(type1.get_scale(), 0));
ObScale scale2 = static_cast<ObScale>(MAX(type2.get_scale(), 0));
int64_t inter_part_length1 = type1.get_precision() - type1.get_scale();
int64_t inter_part_length2 = type2.get_precision() - type2.get_scale();
scale = MAX(scale1, scale2);
precision = static_cast<ObPrecision>(MAX(inter_part_length1, inter_part_length2)
+ CARRY_OFFSET + scale);
if (lib::is_mysql_mode() && type.is_double()) {
precision = ObMySQLUtil::float_length(scale);
} else {
int64_t inter_part_length1 = type1.get_precision() - type1.get_scale();
int64_t inter_part_length2 = type2.get_precision() - type2.get_scale();
precision = static_cast<ObPrecision>(MAX(inter_part_length1, inter_part_length2)
+ CARRY_OFFSET + scale);
}
}
type.set_scale(scale);

View File

@ -92,6 +92,7 @@ int ObExprBetween::cg_expr(ObExprCGCtx &expr_cg_ctx,
raw_expr.get_result_type().get_calc_collation_type();
if (OB_ISNULL(cmp_func_1 = ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
left_meta.type_, val_meta.type_,
left_meta.scale_, val_meta.scale_,
is_oracle_mode(),
cmp_cs_type))) {
ret = OB_ERR_UNEXPECTED;
@ -99,6 +100,7 @@ int ObExprBetween::cg_expr(ObExprCGCtx &expr_cg_ctx,
K(is_oracle_mode()), K(rt_expr));
} else if (OB_ISNULL(cmp_func_2 = ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
val_meta.type_, right_meta.type_,
val_meta.scale_, right_meta.scale_,
is_oracle_mode(),
cmp_cs_type))) {
ret = OB_ERR_UNEXPECTED;

View File

@ -332,13 +332,25 @@ int ObExprCast::calc_result_type2(ObExprResType &type,
// however, ob use -1 as default precision, so it is a valid value
type.set_collation_type(dst_type.get_collation_type());
ObPrecision float_precision = dst_type.get_precision();
if (float_precision < -1 || float_precision > OB_MAX_DOUBLE_FLOAT_PRECISION) {
ObScale float_scale = dst_type.get_scale();
if (OB_UNLIKELY(float_scale > OB_MAX_DOUBLE_FLOAT_SCALE)) {
ret = OB_ERR_TOO_BIG_SCALE;
LOG_USER_ERROR(OB_ERR_TOO_BIG_SCALE, float_scale, "CAST", OB_MAX_DOUBLE_FLOAT_SCALE);
LOG_WARN("scale of float overflow", K(ret), K(float_scale), K(float_precision));
} else if (float_precision < -1 ||
(SCALE_UNKNOWN_YET == float_scale && float_precision > OB_MAX_DOUBLE_FLOAT_PRECISION)) {
ret = OB_ERR_TOO_BIG_PRECISION;
LOG_USER_ERROR(OB_ERR_TOO_BIG_PRECISION, float_precision, "CAST", OB_MAX_DOUBLE_FLOAT_PRECISION);
} else if (float_precision <= OB_MAX_FLOAT_PRECISION) {
type.set_type(ObFloatType);
} else if (SCALE_UNKNOWN_YET == float_scale) {
if (float_precision <= OB_MAX_FLOAT_PRECISION) {
type.set_type(ObFloatType);
} else {
type.set_type(ObDoubleType);
}
} else {
type.set_type(ObDoubleType);
type.set_type(ObFloatType);
type.set_precision(float_precision);
type.set_scale(float_scale);
}
} else {
type.set_type(dst_type.get_type());

View File

@ -24,6 +24,12 @@ namespace sql
{
using namespace common;
#define IS_FIXED_DOUBLE \
!is_oracle_mode && \
ob_is_double_type(type1) && ob_is_double_type(type2) && \
SCALE_UNKNOWN_YET < scale1 && SCALE_UNKNOWN_YET < scale2 && \
MAX(scale1, scale2) <= OB_MAX_DOUBLE_FLOAT_SCALE \
template<ObCmpOp cmp_op>
constexpr int get_cmp_ret(const int)
{
@ -176,6 +182,37 @@ struct ObRelationalStrFunc<true, CS_TYPE, WITH_END_SPACE, CMP_OP>
// }
};
template<bool, ObScale SCALE, ObCmpOp CMP_OP>
struct ObRelationFixedDoubleFunc{};
template<ObScale SCALE, ObCmpOp CMP_OP>
struct ObRelationFixedDoubleFunc<false, SCALE, CMP_OP> : ObDummyRelationalFunc {};
template<ObScale SCALE, ObCmpOp CMP_OP>
struct ObRelationFixedDoubleFunc<true, SCALE, 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::ObFixedDoubleCmp<SCALE>::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);
}
inline static int eval_batch(BATCH_EVAL_FUNC_ARG_DECL)
{
return def_relational_eval_batch_func<DatumCmp>(BATCH_EVAL_FUNC_ARG_LIST);
}
};
// define null, extend, string evaluate batch functions.
template<ObCmpOp CMP_OP>
struct ObRelationalExtraFunc
@ -250,6 +287,10 @@ 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_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];
static ObDatumCmpFuncType DATUM_FIXED_DOUBLE_CMP_FUNCS[OB_NOT_FIXED_SCALE];
template<int X>
struct ExtraExprCmpIniter
{
@ -378,6 +419,42 @@ int g_init_tc_ret = Ob2DArrayConstIniter<ObMaxTC, ObMaxTC, TCExprCmpFuncIniter>:
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();
template<int X>
struct FixedDoubleCmpFuncIniter
{
using Def = datum_cmp::ObFixedDoubleCmp<static_cast<ObScale>(X)>;
template<ObCmpOp cmp_op>
using EvalCmp = ObRelationFixedDoubleFunc<Def::defined_, static_cast<ObScale>(X), cmp_op>;
static void init_array()
{
auto &funcs = EVAL_FIXED_DOUBLE_CMP_FUNCS;
funcs[X][CO_LE] = Def::defined_ ? &EvalCmp<CO_LE>::eval : NULL;
funcs[X][CO_LT] = Def::defined_ ? &EvalCmp<CO_LT>::eval : NULL;
funcs[X][CO_EQ] = Def::defined_ ? &EvalCmp<CO_EQ>::eval : NULL;
funcs[X][CO_GE] = Def::defined_ ? &EvalCmp<CO_GE>::eval : NULL;
funcs[X][CO_GT] = Def::defined_ ? &EvalCmp<CO_GT>::eval : NULL;
funcs[X][CO_NE] = Def::defined_ ? &EvalCmp<CO_NE>::eval : NULL;
funcs[X][CO_CMP] = Def::defined_ ? &EvalCmp<CO_CMP>::eval : NULL;
auto &batch_funcs = EVAL_BATCH_FIXED_DOUBLE_CMP_FUNCS;
batch_funcs[X][CO_LE] = Def::defined_ ? &EvalCmp<CO_LE>::eval_batch : NULL;
batch_funcs[X][CO_LT] = Def::defined_ ? &EvalCmp<CO_LT>::eval_batch : NULL;
batch_funcs[X][CO_EQ] = Def::defined_ ? &EvalCmp<CO_EQ>::eval_batch : NULL;
batch_funcs[X][CO_GE] = Def::defined_ ? &EvalCmp<CO_GE>::eval_batch : NULL;
batch_funcs[X][CO_GT] = Def::defined_ ? &EvalCmp<CO_GT>::eval_batch : NULL;
batch_funcs[X][CO_NE] = Def::defined_ ? &EvalCmp<CO_NE>::eval_batch : NULL;
// CO_CMP only used in T_FUN_SYS_STRCMP, set to NULL
batch_funcs[X][CO_CMP] = NULL;
DATUM_FIXED_DOUBLE_CMP_FUNCS[X] = Def::defined_ ? &Def::cmp : NULL;
}
};
int g_init_fixed_double_ret =
ObArrayConstIniter<OB_NOT_FIXED_SCALE, FixedDoubleCmpFuncIniter>::init();
static int64_t fill_type_with_tc_eval_func(void)
{
int64_t cnt = 0;
@ -408,6 +485,8 @@ int64_t g_fill_type_with_tc_eval_func = fill_type_with_tc_eval_func();
ObExpr::EvalFunc ObExprCmpFuncsHelper::get_eval_expr_cmp_func(const ObObjType type1,
const ObObjType type2,
const ObScale scale1,
const ObScale scale2,
const ObCmpOp cmp_op,
const bool is_oracle_mode,
const ObCollationType cs_type)
@ -423,6 +502,8 @@ 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 (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)) {
func_ptr = EVAL_TYPE_CMP_FUNCS[type1][type2][cmp_op];
} else {
@ -437,6 +518,8 @@ ObExpr::EvalFunc ObExprCmpFuncsHelper::get_eval_expr_cmp_func(const ObObjType ty
ObExpr::EvalBatchFunc ObExprCmpFuncsHelper::get_eval_batch_expr_cmp_func(
const ObObjType type1,
const ObObjType type2,
const ObScale scale1,
const ObScale scale2,
const ObCmpOp cmp_op,
const bool is_oracle_mode,
const ObCollationType cs_type)
@ -452,6 +535,8 @@ 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 (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)) {
func_ptr = EVAL_BATCH_TYPE_CMP_FUNCS[type1][type2][cmp_op];
} else {
@ -467,6 +552,8 @@ ObExpr::EvalBatchFunc ObExprCmpFuncsHelper::get_eval_batch_expr_cmp_func(
DatumCmpFunc ObExprCmpFuncsHelper::get_datum_expr_cmp_func(const ObObjType type1,
const ObObjType type2,
const ObScale scale1,
const ObScale scale2,
const bool is_oracle_mode,
const ObCollationType cs_type)
{
@ -476,7 +563,9 @@ 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 (!ObDatumFuncs::is_string_type(type1) || !ObDatumFuncs::is_string_type(type2)) {
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];
if (NULL == func_ptr) {
func_ptr = DATUM_TC_CMP_FUNCS[tc1][tc2];
@ -553,5 +642,27 @@ REG_SER_FUNC_ARRAY(OB_SFA_DATUM_CMP_STR,
DATUM_STR_CMP_FUNCS,
sizeof(DATUM_STR_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 *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_FIXED_DOUBLE_CMP_EVAL,
EVAL_FIXED_DOUBLE_CMP_FUNCS,
sizeof(EVAL_FIXED_DOUBLE_CMP_FUNCS) / sizeof(void *));
static_assert(
OB_NOT_FIXED_SCALE * CO_MAX == sizeof(EVAL_BATCH_FIXED_DOUBLE_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_FIXED_DOUBLE_CMP_EVAL_BATCH,
EVAL_BATCH_FIXED_DOUBLE_CMP_FUNCS,
sizeof(EVAL_BATCH_FIXED_DOUBLE_CMP_FUNCS) / sizeof(void *));
static_assert(
OB_NOT_FIXED_SCALE == sizeof(DATUM_FIXED_DOUBLE_CMP_FUNCS) / sizeof(void *),
"unexpected size");
REG_SER_FUNC_ARRAY(OB_SFA_DATUM_FIXED_DOUBLE_CMP,
DATUM_FIXED_DOUBLE_CMP_FUNCS,
sizeof(DATUM_FIXED_DOUBLE_CMP_FUNCS) / sizeof(void *));
} // end namespace common;
} // end namespace oceanbase

View File

@ -33,6 +33,8 @@ public:
static sql::ObExpr::EvalFunc get_eval_expr_cmp_func(
const common::ObObjType type1,
const common::ObObjType type2,
const common::ObScale scale1,
const common::ObScale scale2,
const common::ObCmpOp cmp_op,
const bool is_oracle_mode,
const common::ObCollationType cs_type);
@ -40,6 +42,8 @@ public:
static sql::ObExpr::EvalBatchFunc get_eval_batch_expr_cmp_func(
const common::ObObjType type1,
const common::ObObjType type2,
const common::ObScale scale1,
const common::ObScale scale2,
const common::ObCmpOp cmp_op,
const bool is_oracle_mode,
const common::ObCollationType cs_type);
@ -47,6 +51,8 @@ public:
static DatumCmpFunc get_datum_expr_cmp_func(
const common::ObObjType type1,
const common::ObObjType type2,
const common::ObScale scale1,
const common::ObScale scale2,
const bool is_oracle_mode,
const common::ObCollationType cs_type);
};

View File

@ -17,6 +17,7 @@
#include "sql/session/ob_sql_session_info.h"
#include "sql/engine/ob_exec_context.h"
#include "sql/engine/expr/ob_batch_eval_util.h"
#include "share/object/ob_obj_cast_util.h"
namespace oceanbase
{
@ -56,7 +57,7 @@ int ObExprDiv::calc_result_type2(ObExprResType &type,
OC( (ObArithExprOperator::calc_result_type2)(type, type1, type2, type_ctx));
if (OB_SUCC(ret)) {
const ObObjTypeClass result_tc = type.get_type_class();
if (ObNumberTC == result_tc || ObDoubleTC == result_tc || ObFloatTC == result_tc) {
if (ObNumberTC == result_tc) {
if (is_oracle_mode()) {
type.set_scale(ORA_NUMBER_SCALE_UNKNOWN_YET);
type.set_precision(PRECISION_UNKNOWN_YET);
@ -92,6 +93,34 @@ int ObExprDiv::calc_result_type2(ObExprResType &type,
"new_scale1", ROUND_UP(scale1), "new_scale2", ROUND_UP(scale2),
K(div_precision_increment));
}
} else if (ObDoubleTC == result_tc || ObFloatTC == result_tc) {
if (is_oracle_mode()) {
type.set_scale(ORA_NUMBER_SCALE_UNKNOWN_YET);
type.set_precision(PRECISION_UNKNOWN_YET);
} else {
ObScale scale = SCALE_UNKNOWN_YET;
ObPrecision precision = PRECISION_UNKNOWN_YET;
if (SCALE_UNKNOWN_YET != type1.get_scale() && SCALE_UNKNOWN_YET != type2.get_scale()) {
ObScale scale1 = static_cast<ObScale>(MAX(type1.get_scale(), 0));
ObScale scale2 = static_cast<ObScale>(MAX(type2.get_scale(), 0));
scale = MAX(scale1, scale2) + div_precision_increment;
if (scale > OB_MAX_DOUBLE_FLOAT_SCALE) {
scale = SCALE_UNKNOWN_YET;
}
}
if (PRECISION_UNKNOWN_YET != type1.get_precision() &&
PRECISION_UNKNOWN_YET != type2.get_precision() &&
SCALE_UNKNOWN_YET != scale) {
ObPrecision p1 = ObMySQLUtil::float_length(scale);
ObPrecision p2 = type1.get_precision() - type1.get_scale() + scale;
if (ObNumberTC == type1.get_type_class()) {
p2 += decimal_to_double_precision_inc(type1.get_type(), type1.get_scale());
}
precision = MIN(p1, p2);
}
type.set_scale(scale);
type.set_precision(precision);
}
} else if (ObIntervalTC == type.get_type_class()) {
type.set_scale(ObAccuracy::MAX_ACCURACY2[ORACLE_MODE][type.get_type()].get_scale());
type.set_precision(ObAccuracy::MAX_ACCURACY2[ORACLE_MODE][type.get_type()].get_precision());

View File

@ -100,7 +100,11 @@ int ObExprCeilFloor::calc_result_type1(ObExprResType &type,
//no need to test ret here
// scale
type.set_scale(0);
type.set_precision(type1.get_precision());
if (lib::is_mysql_mode() && type.is_double()) {
type.set_precision(17); // float length of 0
} else {
type.set_precision(type1.get_precision());
}
}
ObExprOperator::calc_result_flag1(type, type1);

View File

@ -177,18 +177,23 @@ int ObExprFuncRound::set_res_scale_prec(ObExprTypeCtx &type_ctx, ObExprResType *
}
}
if (OB_SUCC(ret)) {
if (!is_oracle_mode() && ob_is_number_tc(res_type)) {
ObPrecision tmp_res_prec = -1;
if (1 == param_num) {
tmp_res_prec = static_cast<ObPrecision>(params[0].get_precision() -
params[0].get_scale() + 1);
if (!is_oracle_mode()) {
if (ob_is_number_tc(res_type)) {
ObPrecision tmp_res_prec = -1;
if (1 == param_num) {
tmp_res_prec = static_cast<ObPrecision>(params[0].get_precision() -
params[0].get_scale() + 1);
res_prec = tmp_res_prec >= 0 ? tmp_res_prec : res_prec;
res_scale = 0;
} else {
tmp_res_prec = static_cast<ObPrecision>(params[0].get_precision() -
params[0].get_scale() + res_scale + 1);
}
res_prec = tmp_res_prec >= 0 ? tmp_res_prec : res_prec;
res_scale = 0;
} else {
tmp_res_prec = static_cast<ObPrecision>(params[0].get_precision() -
params[0].get_scale() + res_scale + 1);
} else if (ob_is_real_type(res_type)) {
res_prec = (SCALE_UNKNOWN_YET == res_scale) ?
PRECISION_UNKNOWN_YET : ObMySQLUtil::float_length(res_scale);
}
res_prec = tmp_res_prec >= 0 ? tmp_res_prec : res_prec;
}
type.set_scale(res_scale);
type.set_precision(res_prec);

View File

@ -80,6 +80,10 @@ int ObExprIfNull::calc_result_type2(ObExprResType &type,
} else {
type.set_scale(-1);
}
if (lib::is_mysql_mode() && ob_is_real_type(type.get_type()) &&
SCALE_UNKNOWN_YET != type.get_scale()) {
type.set_precision(static_cast<ObPrecision>(ObMySQLUtil::float_length(type.get_scale())));
}
type.set_length(MAX(type1.get_length(), type2.get_length()));
type1.set_calc_meta(type.get_obj_meta());
type1.set_calc_accuracy(type.get_accuracy());

View File

@ -836,9 +836,11 @@ int ObExprInOrNotIn::cg_expr_without_row(ObIAllocator &allocator,
ObObjType left_type = rt_expr.args_[0]->datum_meta_.type_;
ObCollationType left_cs = rt_expr.args_[0]->datum_meta_.cs_type_;
ObObjType right_type = rt_expr.args_[1]->args_[0]->datum_meta_.type_;
ObScale scale1 = rt_expr.args_[0]->datum_meta_.scale_;
ObScale scale2 = rt_expr.args_[1]->datum_meta_.scale_;
rt_expr.inner_functions_ = func_buf;
DatumCmpFunc func_ptr = ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
left_type, right_type, lib::is_oracle_mode(), left_cs);
left_type, right_type, scale1, scale2, lib::is_oracle_mode(), left_cs);
for (int i = 0; i < rt_expr.inner_func_cnt_; i++) {
rt_expr.inner_functions_[i] = (void *)func_ptr;
}
@ -880,6 +882,8 @@ int ObExprInOrNotIn::cg_expr_with_row(ObIAllocator &allocator,
ObSEArray<ObObjType, 8> left_types;
ObSEArray<ObCollationType, 8> left_cs_arr;
ObSEArray<ObObjType, 8> right_types;
ObSEArray<ObScale, 8> left_scales;
ObSEArray<ObScale, 8> right_scales;
#define LEFT_ROW rt_expr.args_[0]
#define LEFT_ROW_ELE(i) rt_expr.args_[0]->args_[i]
@ -895,12 +899,16 @@ int ObExprInOrNotIn::cg_expr_with_row(ObIAllocator &allocator,
} else if (OB_FAIL(left_cs_arr.push_back(
LEFT_ROW_ELE(i)->datum_meta_.cs_type_))) {
LOG_WARN("failed to push back element", K(ret));
} else if (OB_FAIL(left_scales.push_back(LEFT_ROW_ELE(i)->datum_meta_.scale_))) {
LOG_WARN("failed to push back element", K(ret));
} else { /* do nothing */ }
} // end for
for (int i = 0; OB_SUCC(ret) && i < RIGHT_ROW(0)->arg_cnt_; i++) {
if (OB_FAIL(right_types.push_back(RIGHT_ROW_ELE(0, i)->datum_meta_.type_))) {
LOG_WARN("failed to push back element", K(ret));
} else if (OB_FAIL(right_scales.push_back(RIGHT_ROW_ELE(0, i)->datum_meta_.scale_))) {
LOG_WARN("failed to push back element", K(ret));
}
}
if (OB_SUCC(ret)) {
@ -913,8 +921,8 @@ int ObExprInOrNotIn::cg_expr_with_row(ObIAllocator &allocator,
} else {
for (int i = 0; i < left_types.count(); i++) {
DatumCmpFunc func_ptr = ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
left_types.at(i), right_types.at(i), lib::is_oracle_mode(),
left_cs_arr.at(i));
left_types.at(i), right_types.at(i), left_scales.at(i), right_scales.at(i),
lib::is_oracle_mode(), left_cs_arr.at(i));
func_buf[i] = (void *)func_ptr;
} // end for
if (!is_param_all_const()) {
@ -982,7 +990,8 @@ int ObExprInOrNotIn::cg_expr_with_subquery(common::ObIAllocator &allocator,
}
if (OB_SUCC(ret)) {
funcs[i] = (void *)ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
l.get_type(), r.get_type(), lib::is_oracle_mode(), l.get_collation_type());
l.get_type(), r.get_type(), l.get_scale(), r.get_scale(),
lib::is_oracle_mode(), l.get_collation_type());
CK(NULL != funcs[i]);
}
}

View File

@ -190,7 +190,8 @@ int ObExprInterval::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr,
// do not care NULL_FIRST or NULL_LAST, will ignore null in calc_interval_expr()
rt_expr.inner_functions_[0] = reinterpret_cast<void*>(
ObDatumFuncs::get_nullsafe_cmp_func(arg_type, arg_type, default_null_pos(),
CS_TYPE_BINARY, false));
CS_TYPE_BINARY,
rt_expr.args_[0]->datum_meta_.scale_, false));
if (OB_ISNULL(rt_expr.inner_functions_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("cmp_func is NULL", K(ret), K(arg_type));

View File

@ -316,6 +316,7 @@ int ObExprLeastGreatest::cg_expr(ObExprCGCtx &op_cg_ctx,
cmp_meta.get_type(),
NULL_LAST,
cmp_meta.get_collation_type(),
info->cmp_meta_.scale_,
lib::is_oracle_mode());
if (OB_ISNULL(cmp_func)) {
ret = OB_INVALID_ARGUMENT;

View File

@ -84,11 +84,15 @@ int ObExprMinus::calc_result_type2(ObExprResType &type,
} else {
ObScale scale1 = static_cast<ObScale>(MAX(type1.get_scale(), 0));
ObScale scale2 = static_cast<ObScale>(MAX(type2.get_scale(), 0));
int64_t inter_part_length1 = type1.get_precision() - type1.get_scale();
int64_t inter_part_length2 = type2.get_precision() - type2.get_scale();
scale = MAX(scale1, scale2);
precision = static_cast<ObPrecision>(MAX(inter_part_length1, inter_part_length2)
+ CARRY_OFFSET + scale);
if (lib::is_mysql_mode() && type.is_double()) {
precision = ObMySQLUtil::float_length(scale);
} else {
int64_t inter_part_length1 = type1.get_precision() - type1.get_scale();
int64_t inter_part_length2 = type2.get_precision() - type2.get_scale();
precision = static_cast<ObPrecision>(MAX(inter_part_length1, inter_part_length2)
+ CARRY_OFFSET + scale);
}
}
type.set_scale(scale);

View File

@ -54,7 +54,11 @@ int ObExprMod::calc_result_type2(ObExprResType &type,
type.set_scale(SCALE_UNKNOWN_YET);
} else {
type.set_scale(MAX(scale1, scale2));
type.set_precision(MAX(type1.get_precision(),type2.get_precision()));
if (lib::is_mysql_mode() && type.is_double()) {
type.set_precision(ObMySQLUtil::float_length(type.get_scale()));
} else {
type.set_precision(MAX(type1.get_precision(),type2.get_precision()));
}
}
}
return ret;

View File

@ -66,8 +66,8 @@ int ObExprMul::calc_result_type2(ObExprResType &type,
if (SCALE_UNKNOWN_YET == type1.get_scale() || SCALE_UNKNOWN_YET == type2.get_scale()) {
type.set_scale(SCALE_UNKNOWN_YET);
} else {
if (lib::is_oracle_mode()) {
type.set_scale(MIN(static_cast<ObScale>(scale1 + scale2), OB_MAX_NUMBER_SCALE));
if (lib::is_mysql_mode() && type.is_double()) {
type.set_scale(MAX(scale1, scale2));
} else {
type.set_scale(MIN(static_cast<ObScale>(scale1 + scale2), OB_MAX_DECIMAL_SCALE));
}
@ -79,8 +79,12 @@ int ObExprMul::calc_result_type2(ObExprResType &type,
type.set_precision(PRECISION_UNKNOWN_YET);
} else {
// estimated precision
type.set_precision(static_cast<ObPrecision>((precision1 - scale1)
+ (precision2 - scale2) + type.get_scale()));
if (lib::is_mysql_mode() && type.is_double()) {
type.set_precision(ObMySQLUtil::float_length(type.get_scale()));
} else {
type.set_precision(static_cast<ObPrecision>((precision1 - scale1)
+ (precision2 - scale2) + type.get_scale()));
}
}
}
return ret;

View File

@ -214,7 +214,8 @@ int ObExprNeg::calc_result_type1(ObExprResType &type, ObExprResType &type1, ObEx
if (type1.get_type() == ObUNumberType) {
type.set_precision(static_cast<int16_t>(type1.get_precision()));
} else {
type.set_precision(static_cast<int16_t>(type1.get_precision() + NEG_PRECISION_OFFSET));
type.set_precision(static_cast<int16_t>(
MIN(type1.get_precision() + NEG_PRECISION_OFFSET, OB_MAX_INTEGER_DISPLAY_WIDTH)));
}
}
}

View File

@ -93,6 +93,7 @@ int ObExprNotBetween::cg_expr(ObExprCGCtx &expr_cg_ctx,
raw_expr.get_result_type().get_calc_collation_type();
if (OB_ISNULL(cmp_func_1 = ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
val_meta.type_, left_meta.type_,
val_meta.scale_, left_meta.scale_,
is_oracle_mode(),
cmp_cs_type))) {
ret = OB_ERR_UNEXPECTED;
@ -100,6 +101,7 @@ int ObExprNotBetween::cg_expr(ObExprCGCtx &expr_cg_ctx,
K(is_oracle_mode()), K(rt_expr));
} else if (OB_ISNULL(cmp_func_2 = ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
right_meta.type_, val_meta.type_,
right_meta.scale_, val_meta.scale_,
is_oracle_mode(),
cmp_cs_type))) {
ret = OB_ERR_UNEXPECTED;

View File

@ -114,7 +114,7 @@ int ObExprNullSafeEqual::cg_expr(
if (OB_SUCC(ret)) {
funcs[0] = (void *)ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
l.type_, r.type_, lib::is_oracle_mode(), l.cs_type_);
l.type_, r.type_, l.scale_, r.scale_, lib::is_oracle_mode(), l.cs_type_);
CK(NULL != funcs[0]);
rt_expr.inner_functions_ = funcs;
rt_expr.inner_func_cnt_ = 1;

View File

@ -74,7 +74,9 @@ int ObExprNullif::se_deduce_type(ObExprResType &type,
int ret = OB_SUCCESS;
type.set_meta(type1.get_obj_meta());
type.set_accuracy(type1.get_accuracy());
if (ob_is_string_type(type.get_type()) || ob_is_enumset_tc(type.get_type())) {
if (ob_is_real_type(type.get_type()) && SCALE_UNKNOWN_YET != type1.get_scale()) {
type.set_precision(static_cast<ObPrecision>(ObMySQLUtil::float_length(type1.get_scale())));
} else if (ob_is_string_type(type.get_type()) || ob_is_enumset_tc(type.get_type())) {
ObCollationLevel res_cs_level = CS_LEVEL_INVALID;
ObCollationType res_cs_type = CS_TYPE_INVALID;
OZ(ObCharset::aggregate_collation(type1.get_collation_level(), type1.get_collation_type(),
@ -198,6 +200,8 @@ int ObExprNullif::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr,
cmp_func = ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
rt_expr.args_[0]->datum_meta_.type_,
rt_expr.args_[1]->datum_meta_.type_,
rt_expr.args_[0]->datum_meta_.scale_,
rt_expr.args_[1]->datum_meta_.scale_,
lib::is_oracle_mode(),
rt_expr.args_[0]->datum_meta_.cs_type_);
}
@ -211,6 +215,8 @@ int ObExprNullif::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr,
if (OB_ISNULL(cmp_func = ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
cmp_meta.get_type(),
cmp_meta.get_type(),
cmp_meta.get_scale(),
cmp_meta.get_scale(),
lib::is_oracle_mode(),
cmp_meta.get_collation_type()))){
ret = OB_INVALID_ARGUMENT;

View File

@ -1351,7 +1351,9 @@ int ObExprOperator::aggregate_numeric_accuracy_for_merge(ObExprResType &type,
ObScale scale = 0;
int16_t max_integer_digits = -1;
int16_t max_decimal_digits = -1;
int16_t max_scale_for_real = -1;
bool has_real_type = false;
bool has_unknow_scale = false;
for (int64_t i = 0; i < param_num && OB_SUCC(ret); ++i) {
precision = PRECISION_UNKNOWN_YET;
scale = SCALE_UNKNOWN_YET;
@ -1368,6 +1370,8 @@ int ObExprOperator::aggregate_numeric_accuracy_for_merge(ObExprResType &type,
a union c will result to 1.5 and 1923
*/
has_real_type = true;
precision = types[i].get_precision();
scale = types[i].get_scale();
} else {
/*
create table sb(a int(3));//3 ? display width ? precision? length?
@ -1397,12 +1401,25 @@ int ObExprOperator::aggregate_numeric_accuracy_for_merge(ObExprResType &type,
max_decimal_digits = scale;
}
}
if (OB_SUCC(ret)) {
if (SCALE_UNKNOWN_YET == scale) {
has_unknow_scale = true;
} else {
max_scale_for_real = MAX(max_scale_for_real, scale);
}
}
}
if (OB_FAIL(ret)) {
} else if (ob_is_real_type(type.get_type()) && has_real_type) {
type.set_precision(PRECISION_UNKNOWN_YET);
type.set_scale(SCALE_UNKNOWN_YET);
if (is_oracle_mode || has_unknow_scale || max_scale_for_real > OB_MAX_DOUBLE_FLOAT_SCALE) {
type.set_precision(PRECISION_UNKNOWN_YET);
type.set_scale(SCALE_UNKNOWN_YET);
} else {
precision = static_cast<ObPrecision>(ObMySQLUtil::float_length(scale));
type.set_precision(precision);
type.set_scale(max_scale_for_real);
}
} else {
if (max_integer_digits + max_decimal_digits >= 0) {
precision = static_cast<ObPrecision>(max_integer_digits + max_decimal_digits);
@ -1829,6 +1846,8 @@ bool ObRelationalExprOperator::can_cmp_without_cast(ObExprResType type1,
} else {
auto func_ptr = ObExprCmpFuncsHelper::get_eval_expr_cmp_func(type1.get_type(),
type2.get_type(),
type1.get_scale(),
type2.get_scale(),
cmp_op,
lib::is_oracle_mode(),
CS_TYPE_BINARY);
@ -2149,6 +2168,19 @@ int ObRelationalExprOperator::deduce_cmp_type(const ObExprOperator &expr,
} else if (ObRawType == cmp_type.get_calc_type()) {
type1.set_calc_collation_type(CS_TYPE_BINARY);
type2.set_calc_collation_type(CS_TYPE_BINARY);
} else if (is_mysql_mode() && ObDoubleType == cmp_type.get_calc_type()) {
if (ob_is_numeric_tc(type1.get_type_class()) && ob_is_numeric_tc(type2.get_type_class()) &&
SCALE_UNKNOWN_YET != type1.get_scale() && SCALE_UNKNOWN_YET != type2.get_scale()) {
const ObScale scale = MAX(type1.get_scale(), type2.get_scale());
const ObPrecision precision = MAX(type1.get_precision(), type2.get_precision());
ObAccuracy calc_acc(precision, scale);
type1.set_calc_accuracy(calc_acc);
type2.set_calc_accuracy(calc_acc);
} else {
ObAccuracy calc_acc(PRECISION_UNKNOWN_YET, SCALE_UNKNOWN_YET);
type1.set_calc_accuracy(calc_acc);
type2.set_calc_accuracy(calc_acc);
}
}
}
return ret;
@ -3280,7 +3312,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(), lib::is_oracle_mode(), l.get_collation_type());
l.get_type(), r.get_type(), l.get_scale(), r.get_scale(),
lib::is_oracle_mode(), l.get_collation_type());
CK(NULL != funcs[i]);
}
}
@ -3888,6 +3921,19 @@ int ObVectorExprOperator::calc_result_type2_(ObExprResType &type,
} else if (ObRawType == cmp_type.get_calc_type()) {
type1.set_calc_collation_type(CS_TYPE_BINARY);
type2.set_calc_collation_type(CS_TYPE_BINARY);
} else if (is_mysql_mode() && ObDoubleType == cmp_type.get_calc_type()) {
if (ob_is_numeric_tc(type1.get_type_class()) && ob_is_numeric_tc(type2.get_type_class()) &&
SCALE_UNKNOWN_YET != type1.get_scale() && SCALE_UNKNOWN_YET != type2.get_scale()) {
const ObScale scale = MAX(type1.get_scale(), type2.get_scale());
const ObPrecision precision = MAX(type1.get_precision(), type2.get_precision());
ObAccuracy calc_acc(precision, scale);
type1.set_calc_accuracy(calc_acc);
type2.set_calc_accuracy(calc_acc);
} else {
ObAccuracy calc_acc(PRECISION_UNKNOWN_YET, SCALE_UNKNOWN_YET);
type1.set_calc_accuracy(calc_acc);
type2.set_calc_accuracy(calc_acc);
}
}
}
return ret;
@ -4766,8 +4812,18 @@ int ObMinMaxExprOperator::calc_result_meta_for_comparison(
//兼容mysql行为对类型进行提升。
type.set_type(ObIntType);
}
type.set_scale(result_scale);
type.set_precision(static_cast<ObPrecision>(max_precision + max_scale)); // esti, not accurate
if (lib::is_mysql_mode() && ob_is_real_type(type.get_type())) {
if (SCALE_UNKNOWN_YET != result_scale && OB_MAX_DOUBLE_FLOAT_SCALE >= result_scale) {
type.set_scale(result_scale);
type.set_precision(static_cast<ObPrecision>(ObMySQLUtil::float_length(result_scale)));
} else {
type.set_scale(SCALE_UNKNOWN_YET);
type.set_precision(PRECISION_UNKNOWN_YET);
}
} else {
type.set_scale(result_scale);
type.set_precision(static_cast<ObPrecision>(max_precision + max_scale)); // esti, not accurate
}
}
}
@ -5739,6 +5795,8 @@ int ObRelationalExprOperator::cg_datum_cmp_expr(const ObRawExpr &raw_expr,
const ObCmpOp cmp_op = get_cmp_op(raw_expr.get_expr_type());
const ObObjType input_type1 = rt_expr.args_[0]->datum_meta_.type_;
const ObObjType input_type2 = rt_expr.args_[1]->datum_meta_.type_;
const ObScale input_scale1 = rt_expr.args_[0]->datum_meta_.scale_;
const ObScale input_scale2 = rt_expr.args_[1]->datum_meta_.scale_;
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)) {
@ -5746,9 +5804,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, cmp_op, lib::is_oracle_mode(), cs_type);
input_type1, input_type2, input_scale1, input_scale2, cmp_op, lib::is_oracle_mode(),
cs_type);
rt_expr.eval_batch_func_ = ObExprCmpFuncsHelper::get_eval_batch_expr_cmp_func(
input_type1, input_type2, cmp_op, lib::is_oracle_mode(), cs_type);
input_type1, input_type2, input_scale1, input_scale2, cmp_op, lib::is_oracle_mode(),
cs_type);
}
CK(NULL != rt_expr.eval_func_);
CK(NULL != rt_expr.eval_batch_func_);
@ -5808,17 +5868,20 @@ int ObRelationalExprOperator::cg_row_cmp_expr(const int row_dimension,
{
const ObObjType type1 = left_row->args_[i]->datum_meta_.type_;
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 ObCollationType cs_type = left_row->args_[i]->datum_meta_.cs_type_;
if (ObDatumFuncs::is_string_type(type1) && ObDatumFuncs::is_string_type(type2)) {
CK(left_row->args_[i]->datum_meta_.cs_type_
== right_row->args_[i]->datum_meta_.cs_type_);
rt_expr.inner_functions_[i] = (void*)ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
type1, type2,
scale1, scale2,
lib::is_oracle_mode(),
cs_type);
} else {
rt_expr.inner_functions_[i] = (void *)ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
type1, type2, lib::is_oracle_mode(), cs_type);
type1, type2, scale1, scale2, lib::is_oracle_mode(), cs_type);
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));

View File

@ -1208,7 +1208,7 @@ public:
common::ObCharset::charset_type_by_coll(type2.get_collation_type());
} else {
auto func_ptr = ObExprCmpFuncsHelper::get_eval_expr_cmp_func(
type1.get_type(), type2.get_type(), cmp_op,
type1.get_type(), type2.get_type(), type1.get_scale(), type2.get_scale(), cmp_op,
lib::is_oracle_mode(), common::CS_TYPE_MAX);
need_no_cast = (func_ptr != nullptr);
}

View File

@ -485,6 +485,7 @@ int ObExprOracleDecode::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_e
rt_expr.inner_functions_[0] = reinterpret_cast<void*>(
ObDatumFuncs::get_nullsafe_cmp_func(cmp_meta.type_, cmp_meta.type_,
default_null_pos(), cmp_meta.cs_type_,
cmp_meta.scale_,
lib::is_oracle_mode()));
}
return ret;

View File

@ -242,6 +242,8 @@ int ObExprOracleNullif::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_e
CK(OB_NOT_NULL(cmp_func = ObExprCmpFuncsHelper::get_datum_expr_cmp_func(
left_meta.type_,
right_meta.type_,
left_meta.scale_,
right_meta.scale_,
lib::is_oracle_mode(),
cmp_cs_type)));
OX(rt_expr.inner_func_cnt_ = 1);

View File

@ -616,7 +616,7 @@ static ObObjType RELATIONAL_CMP_TYPE[ObMaxType][ObMaxType] =
ObDoubleType, /* UMediumIntType */
ObDoubleType, /* UInt32Type */
ObDoubleType, /* UIntType */
ObFloatType, /* FloatType */
ObDoubleType, /* FloatType */
ObDoubleType, /* DoubleType */
ObDoubleType, /* UFloatType */
ObDoubleType, /* UDoubleType */
@ -724,7 +724,7 @@ static ObObjType RELATIONAL_CMP_TYPE[ObMaxType][ObMaxType] =
ObDoubleType, /* UIntType */
ObDoubleType, /* FloatType */
ObDoubleType, /* DoubleType */
ObUFloatType, /* UFloatType */
ObDoubleType, /* UFloatType */
ObDoubleType, /* UDoubleType */
ObDoubleType, /* NumberType */
ObDoubleType, /* UNumberType */

View File

@ -65,6 +65,12 @@ typedef void (*ser_eval_batch_function)(ObBatchEvalFuncTag &);
OB_SFA_SQL_EXPR_EVAL_BATCH, \
OB_SFA_EXPR_BASIC_PART2, \
OB_SFA_EXPR_STR_BASIC_PART2, \
OB_SFA_FIXED_DOUBLE_NULLSAFE_CMP, \
OB_SFA_FIXED_DOUBLE_BASIC_PART1, \
OB_SFA_FIXED_DOUBLE_BASIC_PART2, \
OB_SFA_FIXED_DOUBLE_CMP_EVAL, \
OB_SFA_FIXED_DOUBLE_CMP_EVAL_BATCH, \
OB_SFA_DATUM_FIXED_DOUBLE_CMP, \
OB_SFA_MAX
enum ObSerFuncArrayID {

View File

@ -3518,7 +3518,8 @@ int ObDDLResolver::cast_default_value(ObObj &default_value,
} else if (lib::is_mysql_mode() &&
(ObFloatTC == column_schema.get_data_type_class() ||
ObDoubleTC == column_schema.get_data_type_class()) &&
(column_schema.get_data_precision() > 0 && column_schema.get_data_scale() == 0)) {
(column_schema.get_data_precision() != PRECISION_UNKNOWN_YET &&
column_schema.get_data_scale() != SCALE_UNKNOWN_YET)) {
const ObObj *res_obj = &default_value;
const common::ObAccuracy &accuracy = column_schema.get_accuracy();
if (OB_FAIL(common::obj_accuracy_check(cast_ctx, accuracy,

View File

@ -14,6 +14,7 @@
#include "lib/container/ob_iarray.h"
#include "lib/container/ob_fixed_array.h"
#include "share/object/ob_obj_cast.h"
#include "share/object/ob_obj_cast_util.h"
#include "sql/resolver/expr/ob_raw_expr_deduce_type.h"
#include "sql/resolver/expr/ob_raw_expr_util.h"
#include "sql/resolver/ob_stmt.h"
@ -1295,8 +1296,27 @@ int ObRawExprDeduceType::visit(ObAggFunRawExpr &expr)
scale_increment_recover = result_type.get_scale();
result_type.set_scale(static_cast<ObScale>(result_type.get_scale() + scale_increment));
}
} else if (ob_is_float_tc(obj_type) || ob_is_double_tc(obj_type) || ob_is_json(obj_type)
|| ob_is_string_type(obj_type) || ob_is_enumset_tc(obj_type)) {
} else if (ob_is_float_tc(obj_type) || ob_is_double_tc(obj_type)) {
result_type.set_double();
if (result_type.get_scale() >= 0) {
scale_increment_recover = result_type.get_scale();
result_type.set_scale(static_cast<ObScale>(result_type.get_scale() + scale_increment));
if (T_FUN_AVG == expr.get_expr_type()) {
result_type.set_precision(
static_cast<ObPrecision>(result_type.get_precision() + scale_increment));
} else {
result_type.set_precision(
static_cast<ObPrecision>(ObMySQLUtil::float_length(result_type.get_scale())));
}
}
// recheck precision and scale overflow
if (result_type.get_precision() > OB_MAX_DOUBLE_FLOAT_DISPLAY_WIDTH ||
result_type.get_scale() > OB_MAX_DOUBLE_FLOAT_SCALE) {
result_type.set_scale(SCALE_UNKNOWN_YET);
result_type.set_precision(PRECISION_UNKNOWN_YET);
}
} else if (ob_is_json(obj_type) || ob_is_string_type(obj_type) ||
ob_is_enumset_tc(obj_type)) {
result_type.set_double();
// todo jiuren
// todo blob and text@hanhui
@ -1312,7 +1332,8 @@ int ObRawExprDeduceType::visit(ObAggFunRawExpr &expr)
result_type.set_scale(static_cast<ObScale>(scale_increment));
} else {
scale_increment_recover = result_type.get_scale();
result_type.set_scale(static_cast<ObScale>(result_type.get_scale() + scale_increment));
result_type.set_scale(static_cast<ObScale>(
MIN(OB_MAX_DOUBLE_FLOAT_SCALE, result_type.get_scale() + scale_increment)));
}
result_type.set_precision(static_cast<ObPrecision>(result_type.get_precision() + scale_increment));
}
@ -1452,19 +1473,9 @@ int ObRawExprDeduceType::visit(ObAggFunRawExpr &expr)
}
break;
}
case T_FUN_GROUPING: {
if (!lib::is_oracle_mode()) {
result_type.set_int();
expr.set_result_type(result_type);
} else {
result_type.set_number();
result_type.set_scale(0);
result_type.set_precision(OB_MAX_NUMBER_PRECISION);
expr.set_result_type(result_type);
}
break;
}
case T_FUN_GROUPING_ID: {
case T_FUN_GROUPING:
case T_FUN_GROUPING_ID:
case T_FUN_GROUP_ID: {
if (!lib::is_oracle_mode()) {
result_type.set_int();
expr.set_result_type(result_type);
@ -1482,18 +1493,6 @@ int ObRawExprDeduceType::visit(ObAggFunRawExpr &expr)
}
break;
}
case T_FUN_GROUP_ID: {
if (!lib::is_oracle_mode()) {
result_type.set_int();
expr.set_result_type(result_type);
} else {
result_type.set_number();
result_type.set_scale(0);
result_type.set_precision(OB_MAX_NUMBER_PRECISION);
expr.set_result_type(result_type);
}
break;
}
case T_FUN_APPROX_COUNT_DISTINCT_SYNOPSIS:
case T_FUN_APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE: {
result_type.set_varchar();
@ -2987,6 +2986,24 @@ int ObRawExprDeduceType::try_add_cast_expr_above_for_deduce_type(ObRawExpr &expr
&& ObDateTimeTC == child_res_type.get_type_class()
&& ObDateTimeTC == dst_type.get_calc_meta().get_type_class()) {
cast_dst_type.set_accuracy(child_res_type.get_accuracy());
} else if (lib::is_mysql_mode() && ObDoubleTC == dst_type.get_calc_meta().get_type_class()) {
if (ob_is_numeric_tc(child_res_type.get_type_class())) {
// passing scale and precision when casting float/double/decimal to double
ObScale s = child_res_type.get_calc_accuracy().get_scale();
ObPrecision p = child_res_type.get_calc_accuracy().get_precision();
if (ObNumberTC == child_res_type.get_type_class() &&
SCALE_UNKNOWN_YET != s && PRECISION_UNKNOWN_YET != p) {
p += decimal_to_double_precision_inc(child_res_type.get_type(), s);
cast_dst_type.set_scale(s);
cast_dst_type.set_precision(p);
} else if (s != SCALE_UNKNOWN_YET && PRECISION_UNKNOWN_YET != p &&
s <= OB_MAX_DOUBLE_FLOAT_SCALE && p >= s) {
cast_dst_type.set_accuracy(child_res_type.get_calc_accuracy());
}
} else {
cast_dst_type.set_scale(SCALE_UNKNOWN_YET);
cast_dst_type.set_precision(PRECISION_UNKNOWN_YET);
}
}
// 这里仅设置部分情况的accuracy,其他情况的accuracy信息交给cast类型推导设置

View File

@ -6611,6 +6611,14 @@ int ObRawExprUtils::check_need_cast_expr(const ObExprResType &src_type,
} else if ((ob_is_string_or_lob_type(in_type) && in_type == out_type && in_cs_type == out_cs_type)
|| (!ob_is_string_or_lob_type(in_type) && in_type == out_type)) {
need_cast = false;
if (lib::is_mysql_mode() && ob_is_double_type(in_type) &&
src_type.get_scale() != dst_type.get_scale() &&
src_type.get_precision() != PRECISION_UNKNOWN_YET) {
// for the conversion between doubles with increased scale in mysql mode,
// it is necessary to explicitly add the cast expression
need_cast = (SCALE_UNKNOWN_YET == dst_type.get_scale()) ||
(src_type.get_scale() < dst_type.get_scale());
}
} else if (ob_is_enumset_tc(out_type)) {
//no need add cast, will add column_conv later
need_cast = false;

View File

@ -4968,19 +4968,18 @@ int ObResolverUtils::resolve_data_type(const ParseNode &type_node,
data_type.set_precision(precision);
data_type.set_scale(scale);
} else {
// OB does NOT support float/double(M,D) type if D is NOT zero
// See https://work.aone.alibaba-inc.com/issue/35557185 for detail
if (OB_UNLIKELY(OB_DECIMAL_NOT_SPECIFIED != scale && 0 != scale)) {
ret = OB_UNSUPPORTED_DEPRECATED_FEATURE;
LOG_USER_ERROR(OB_UNSUPPORTED_DEPRECATED_FEATURE, "MySQL");
LOG_WARN("Not supported, deprecated MySQL feature", K(ret), K(scale), K(precision));
if (OB_UNLIKELY(scale > OB_MAX_DOUBLE_FLOAT_SCALE)) {
ret = OB_ERR_TOO_BIG_SCALE;
LOG_USER_ERROR(OB_ERR_TOO_BIG_SCALE, scale, ident_name.ptr(), OB_MAX_DOUBLE_FLOAT_SCALE);
LOG_WARN("scale of double overflow", K(ret), K(scale), K(precision));
} else if (OB_UNLIKELY(OB_DECIMAL_NOT_SPECIFIED == scale &&
precision > OB_MAX_DOUBLE_FLOAT_PRECISION)) {
ret = OB_ERR_COLUMN_SPEC;
LOG_USER_ERROR(OB_ERR_COLUMN_SPEC, ident_name.length(), ident_name.ptr());
LOG_WARN("precision of double overflow", K(ret), K(scale), K(precision));
} else if (OB_UNLIKELY(OB_DECIMAL_NOT_SPECIFIED != scale &&
precision > OB_MAX_DOUBLE_FLOAT_DISPLAY_WIDTH)) {
precision > OB_MAX_DOUBLE_FLOAT_DISPLAY_WIDTH ||
(0 == scale && 0 == precision))) {
ret = OB_ERR_TOO_BIG_DISPLAYWIDTH;
LOG_USER_ERROR(OB_ERR_TOO_BIG_DISPLAYWIDTH,
ident_name.ptr(),

View File

@ -101,7 +101,7 @@ int ObColumnEqualEncoder::traverse(bool &suitable)
// to avoid overflow, we have to limit the max excepction count
const int64_t max_exc_cnt = std::min(MAX_EXC_CNT, rows_->count() * EXC_THRESHOLD_PCT / 100 + 1);
sql::ObExprBasicFuncs *basic_funcs = ObDatumFuncs::get_basic_func(
column_type_.get_type(), column_type_.get_collation_type());
column_type_.get_type(), column_type_.get_collation_type(), column_type_.get_scale());
ObCmpFunc cmp_func;
cmp_func.cmp_func_ = lib::is_oracle_mode()
? basic_funcs->null_last_cmp_ : basic_funcs->null_first_cmp_;

View File

@ -145,7 +145,7 @@ int ObDictEncoder::build_dict()
} else {
if (need_sort_) {
sql::ObExprBasicFuncs *basic_funcs = ObDatumFuncs::get_basic_func(
column_type_.get_type(), column_type_.get_collation_type());
column_type_.get_type(), column_type_.get_collation_type(), column_type_.get_scale());
ObCmpFunc cmp_func;
cmp_func.cmp_func_ = lib::is_oracle_mode()
? basic_funcs->null_last_cmp_ : basic_funcs->null_first_cmp_;

View File

@ -119,7 +119,8 @@ int ObEncodingHashTableBuilder::build(const ObColDatums &col_datums, const ObCol
const bool need_binary_hash =
(store_class == ObTextSC || store_class == ObJsonSC || store_class == ObLobSC || store_class == ObGeometrySC);
sql::ObExprBasicFuncs *basic_funcs = ObDatumFuncs::get_basic_func(
col_desc.col_type_.get_type(), col_desc.col_type_.get_collation_type());
col_desc.col_type_.get_type(), col_desc.col_type_.get_collation_type(),
col_desc.col_type_.get_scale());
ObHashFunc hash_func;
hash_func.hash_func_ = basic_funcs->murmur_hash_;
const uint64_t mask = (bucket_num_ - 1);

View File

@ -635,6 +635,7 @@ int ObStorageDatumUtils::init(const ObIArray<share::schema::ObColDesc> &col_desc
bool is_ascending = true || col_desc.col_order_ == ObOrderType::ASC;
sql::ObExprBasicFuncs *basic_funcs = ObDatumFuncs::get_basic_func(col_desc.col_type_.get_type(),
col_desc.col_type_.get_collation_type(),
col_desc.col_type_.get_scale(),
is_oracle_mode);
if (OB_UNLIKELY(nullptr == basic_funcs
|| nullptr == basic_funcs->null_last_cmp_

View File

@ -4827,6 +4827,12 @@ int ObLSTabletService::table_refresh_row(
LOG_WARN("get row from single row col count not equal.", K(ret), K(row.get_count()), K(new_row->get_count()));
} else {
LOG_DEBUG("get new row success.", K(row), KPC(new_row));
// passing fixed double scale from row to new_row
for (int64_t i = 0; OB_SUCC(ret) && i < new_row->get_count(); ++i) {
if (row.cells_[i].is_fixed_double()) {
new_row->cells_[i].set_scale(row.cells_[i].get_scale());
}
}
if (OB_FAIL(ob_write_row(run_ctx.lob_allocator_, *new_row, row))) {
LOG_WARN("failed to deep copy new row", K(ret));
} else {

View File

@ -146,16 +146,16 @@ floor(-161)
-161
select ceil(null);
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def ceil(null) 5 23 0 Y 32768 0 63
def ceil(null) 5 17 0 Y 32768 0 63
ceil(null)
NULL
select floor(null);
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def floor(null) 5 23 0 Y 32768 0 63
def floor(null) 5 17 0 Y 32768 0 63
floor(null)
NULL
select floor(1+null*5);
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def floor(1+null*5) 5 23 0 Y 32768 0 63
def floor(1+null*5) 5 17 0 Y 32768 0 63
floor(1+null*5)
NULL

View File

@ -40,12 +40,12 @@ round(a + 0.4)
drop table t1;
select floor(null);
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def floor(null) 5 23 0 Y 32768 0 63
def floor(null) 5 17 0 Y 32768 0 63
floor(null)
NULL
select ceil(null);
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def ceil(null) 5 23 0 Y 32768 0 63
def ceil(null) 5 17 0 Y 32768 0 63
ceil(null)
NULL
select floor(-123);
@ -251,7 +251,7 @@ insert into tbl1 values(6,'now2','haha3',-10.4256,'2014-05-04 12:00:00',0.253);
insert into tbl1 values(7,'now3','haha4',0.6256,'2014-05-04 12:00:00',1.677);
select floor(i4),floor(i5) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def floor(i4) 5 23 3 Y 32768 0 63
def floor(i4) 5 17 3 Y 32768 0 63
def floor(i5) 8 5 3 Y 32768 0 63
floor(i4) floor(i5)
1 -11
@ -263,31 +263,31 @@ floor(i4) floor(i5)
0 1
select max(floor(i4)),max(floor(i5)) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def max(floor(i4)) 5 23 1 Y 32768 0 63
def max(floor(i4)) 5 17 1 Y 32768 0 63
def max(floor(i5)) 8 5 1 Y 32768 0 63
max(floor(i4)) max(floor(i5))
5 3
select min(floor(i4)),min(floor(i5)) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def min(floor(i4)) 5 23 3 Y 32768 0 63
def min(floor(i4)) 5 17 3 Y 32768 0 63
def min(floor(i5)) 8 5 3 Y 32768 0 63
min(floor(i4)) min(floor(i5))
-11 -11
select max(ceil(i4)),max(ceil(i5)) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def max(ceil(i4)) 5 23 1 Y 32768 0 63
def max(ceil(i4)) 5 17 1 Y 32768 0 63
def max(ceil(i5)) 8 5 1 Y 32768 0 63
max(ceil(i4)) max(ceil(i5))
6 4
select min(ceil(i4)),min(ceil(i5)) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def min(ceil(i4)) 5 23 3 Y 32768 0 63
def min(ceil(i4)) 5 17 3 Y 32768 0 63
def min(ceil(i5)) 8 5 3 Y 32768 0 63
min(ceil(i4)) min(ceil(i5))
-10 -10
select avg(ceil(i4)),avg(ceil(i5)) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def avg(ceil(i4)) 5 23 6 Y 32768 4 63
def avg(ceil(i4)) 5 21 6 Y 32768 4 63
def avg(ceil(i5)) 246 11 7 Y 32768 4 63
avg(ceil(i4)) avg(ceil(i5))
0.2857 -0.2857
@ -299,7 +299,7 @@ avg(ceil(i5)) avg(floor(i5))
-0.2857 -1.2857
select sum(ceil(i4)),sum(ceil(i5)) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def sum(ceil(i4)) 5 23 1 Y 32768 0 63
def sum(ceil(i4)) 5 17 1 Y 32768 0 63
def sum(ceil(i5)) 246 6 2 Y 32768 0 63
sum(ceil(i4)) sum(ceil(i5))
2 -2
@ -317,13 +317,13 @@ ceil(count(ceil(i4))) floor(count(ceil(i5)))
7 7
select ceil(avg(ceil(i4))),floor(avg(ceil(i5))) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def ceil(avg(ceil(i4))) 5 23 1 Y 32768 0 63
def ceil(avg(ceil(i4))) 5 17 1 Y 32768 0 63
def floor(avg(ceil(i5))) 8 9 2 Y 32768 0 63
ceil(avg(ceil(i4))) floor(avg(ceil(i5)))
1 -1
select ceil(avg(ceil(i4))),ceil(avg(ceil(i5))) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def ceil(avg(ceil(i4))) 5 23 1 Y 32768 0 63
def ceil(avg(ceil(i4))) 5 17 1 Y 32768 0 63
def ceil(avg(ceil(i5))) 8 9 1 Y 32768 0 63
ceil(avg(ceil(i4))) ceil(avg(ceil(i5)))
1 0
@ -426,7 +426,7 @@ i1 v2 i3 i4 d4 i5
6 now2 haha3 -10.4256 2014-05-04 12:00:00.000000 0.253
select floor(i4) abc from tbl1 order by abc desc;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def abc 5 23 3 Y 32768 0 63
def abc 5 17 3 Y 32768 0 63
abc
5
1
@ -437,7 +437,7 @@ abc
-11
select floor(v2) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def floor(v2) 5 23 1 Y 32768 0 63
def floor(v2) 5 17 1 Y 32768 0 63
floor(v2)
0
0
@ -456,7 +456,7 @@ Warning 1292 Truncated incorrect DOUBLE value: 'now2'
Warning 1292 Truncated incorrect DOUBLE value: 'now3'
select floor(i3) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def floor(i3) 5 23 1 Y 32768 0 63
def floor(i3) 5 17 1 Y 32768 0 63
floor(i3)
0
0
@ -475,7 +475,7 @@ Warning 1292 Truncated incorrect DOUBLE value: 'haha3'
Warning 1292 Truncated incorrect DOUBLE value: 'haha4'
select floor(d4) from tbl1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def floor(d4) 5 25 14 Y 32768 0 63
def floor(d4) 5 17 14 Y 32768 0 63
floor(d4)
20140504120000
20140504120000
@ -491,8 +491,8 @@ insert into tbl2 values(2,'2.5');
insert into tbl2 values(3,'-3.2');
select floor(v2),ceil(v2) from tbl2;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def floor(v2) 5 23 2 Y 32768 0 63
def ceil(v2) 5 23 2 Y 32768 0 63
def floor(v2) 5 17 2 Y 32768 0 63
def ceil(v2) 5 17 2 Y 32768 0 63
floor(v2) ceil(v2)
1 1
2 3

View File

@ -75,6 +75,7 @@ TEST(ObTestDatumCmp, defined_nullsafe_func_by_type)
static_cast<ObObjType>(j),
NULL_FIRST,
CS_TYPE_COLLATION_FREE,
SCALE_UNKNOWN_YET,
false)) {
of_result << "defined\n";
} else {
@ -104,6 +105,8 @@ TEST(ObTestDatumCmp, defined_expr_func_by_type)
<< "> : ";
if (NULL != ObExprCmpFuncsHelper::get_datum_expr_cmp_func(static_cast<ObObjType>(i),
static_cast<ObObjType>(j),
SCALE_UNKNOWN_YET,
SCALE_UNKNOWN_YET,
false,
CS_TYPE_COLLATION_FREE)) {
of_result << "defined\n";

View File

@ -68,6 +68,7 @@ void TestPkeyRangeSliceCalc::SetUp()
ObObjType::ObIntType,
ObCmpNullPos::NULL_LAST,
ObCollationType::CS_TYPE_BINARY,
SCALE_UNKNOWN_YET,
false/*is_orace_mode*/);
ASSERT_EQ(OB_SUCCESS, sort_cmp_funcs_.push_back(cmp_func));
int_datum_.int_ = &tmp_int_;

View File

@ -254,6 +254,7 @@ public:
tmp_type,
field_collation.null_pos_,
field_collation.cs_type_,
SCALE_UNKNOWN_YET,
lib::is_oracle_mode());
ObHashFunc hash_func;
if (0 == i) {
@ -351,6 +352,7 @@ public:
tmp_type,
field_collation.null_pos_,
field_collation.cs_type_,
SCALE_UNKNOWN_YET,
lib::is_oracle_mode());
if (OB_FAIL(spec.sort_cmp_funs_.push_back(cmp_func))) {
LOG_WARN("failed to push back sort function", K(ret));

View File

@ -298,6 +298,7 @@ public:
tmp_type,
field_collation.null_pos_,
field_collation.cs_type_,
SCALE_UNKNOWN_YET,
lib::is_oracle_mode());
ObHashFunc hash_func;
if (0 == i) {
@ -420,6 +421,7 @@ public:
tmp_type,
field_collation.null_pos_,
field_collation.cs_type_,
SCALE_UNKNOWN_YET,
lib::is_oracle_mode());
if (OB_FAIL(spec.sort_cmp_funs_.push_back(cmp_func))) {
LOG_WARN("failed to push back sort function", K(ret));
@ -530,6 +532,7 @@ public:
tmp_type,
field_collation.null_pos_,
field_collation.cs_type_,
SCALE_UNKNOWN_YET,
lib::is_oracle_mode());
ObHashFunc hash_func;
if (0 == i) {
@ -646,6 +649,7 @@ public:
tmp_type,
field_collation.null_pos_,
field_collation.cs_type_,
SCALE_UNKNOWN_YET,
lib::is_oracle_mode());
if (OB_FAIL(spec.cmp_funcs_.push_back(cmp_func))) {
LOG_WARN("failed to push back sort function", K(ret));

View File

@ -265,6 +265,7 @@ public:
tmp_type,
field_collation.null_pos_,
field_collation.cs_type_,
SCALE_UNKNOWN_YET,
lib::is_oracle_mode());
if (OB_FAIL(spec.sort_cmp_funs_.push_back(cmp_func))) {
LOG_WARN("failed to push back sort function", K(ret));
@ -359,6 +360,7 @@ public:
tmp_type,
field_collation.null_pos_,
field_collation.cs_type_,
SCALE_UNKNOWN_YET,
lib::is_oracle_mode());
if (OB_FAIL(spec.cmp_funcs_.push_back(cmp_func))) {
LOG_WARN("failed to push back sort function", K(ret));

View File

@ -200,7 +200,7 @@ create index idx_t_idx_c126 on t_idx(c126) LOCAL;
create index idx_t_idx_c127 on t_idx(c127) LOCAL;
create index idx_t_idx_c128 on t_idx(c128) LOCAL;
create index idx_t_idx_c129 on t_idx(c129) LOCAL;
create table yuming(c1 float, c2 float, primary key(c1, c2));
create table yuming(c1 float(10, 5), c2 float(10, 5), primary key(c1, c2));
create table query_range(c1 int, c2 int, c3 int, c4 int, c5 int, primary key(c1, c2, c3));
CREATE TABLE query_range1(c1 int(31) NOT NULL, `c2` decimal(5,1) DEFAULT NULL, `c3` int(123) DEFAULT NULL, `c4` int(6) DEFAULT NULL, `c5` int(19) NOT NULL, `c6` int(105) DEFAULT NULL, `c7` tinyint(112) NOT NULL, `c8` decimal(26,6) NOT NULL, `c9` decimal(14,4) NOT NULL, `c10` varbinary(18) DEFAULT NULL, `c11` decimal(35,8) NOT NULL, `c12` int(3) NOT NULL, PRIMARY KEY (`c9`, `c11`, `c8`, `c1`, `c12`, `c7`, `c5`), KEY `i_BX` (`c2`) BLOCK_SIZE 16384);