[FEAT MERGE] Support float/double(m, d) in mysql mode
This commit is contained in:
parent
d967637528
commit
26f2754db2
18
deps/oblib/src/common/object/ob_obj_compare.cpp
vendored
18
deps/oblib/src/common/object/ob_obj_compare.cpp
vendored
@ -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);\
|
||||
}\
|
||||
|
30
deps/oblib/src/common/object/ob_obj_compare.h
vendored
30
deps/oblib/src/common/object/ob_obj_compare.h
vendored
@ -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.
|
||||
|
24
deps/oblib/src/common/object/ob_obj_funcs.h
vendored
24
deps/oblib/src/common/object/ob_obj_funcs.h
vendored
@ -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> \
|
||||
{ \
|
||||
|
2
deps/oblib/src/common/object/ob_object.h
vendored
2
deps/oblib/src/common/object/ob_object.h
vendored
@ -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();
|
||||
}
|
||||
|
17
deps/oblib/src/common/rowkey/ob_rowkey.cpp
vendored
17
deps/oblib/src/common/rowkey/ob_rowkey.cpp
vendored
@ -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_);
|
||||
|
1
deps/oblib/src/lib/ob_define.h
vendored
1
deps/oblib/src/lib/ob_define.h
vendored
@ -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
|
||||
|
9
deps/oblib/src/rpc/obmysql/ob_mysql_util.h
vendored
9
deps/oblib/src/rpc/obmysql/ob_mysql_util.h
vendored
@ -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
|
||||
|
||||
|
@ -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>
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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_);
|
||||
}
|
||||
}
|
||||
|
@ -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_;
|
||||
|
@ -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()) {
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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类型推导设置
|
||||
|
@ -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;
|
||||
|
@ -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(),
|
||||
|
@ -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_;
|
||||
|
@ -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_;
|
||||
|
@ -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);
|
||||
|
@ -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_
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
@ -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_;
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user