align_date4cmp bug fixs

This commit is contained in:
obdev
2023-09-20 16:07:40 +00:00
committed by ob-robot
parent aab361bf86
commit c2bee5f2d3
2 changed files with 184 additions and 62 deletions

View File

@ -17,6 +17,8 @@
#include "common/object/ob_obj_compare.h" #include "common/object/ob_obj_compare.h"
#include "lib/timezone/ob_time_convert.h" #include "lib/timezone/ob_time_convert.h"
#include "sql/resolver/expr/ob_raw_expr.h" #include "sql/resolver/expr/ob_raw_expr.h"
#include "sql/engine/expr/ob_expr_util.h"
#include "sql/engine/expr/ob_expr_lob_utils.h"
namespace oceanbase namespace oceanbase
{ {
@ -105,6 +107,7 @@ int ObExprAlignDate4Cmp::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_
LOG_WARN("the arg of expr_align_date4cmp is null.", K(ret), K(rt_expr)); LOG_WARN("the arg of expr_align_date4cmp is null.", K(ret), K(rt_expr));
} else { } else {
rt_expr.eval_func_ = eval_align_date4cmp; rt_expr.eval_func_ = eval_align_date4cmp;
rt_expr.extra_ = raw_expr.get_extra();
} }
return ret; return ret;
} }
@ -129,18 +132,21 @@ int ObExprAlignDate4Cmp::eval_align_date4cmp(const ObExpr &expr, ObEvalCtx &ctx,
} else { } else {
date_arg_obj_type = expr.args_[0]->datum_meta_.type_; date_arg_obj_type = expr.args_[0]->datum_meta_.type_;
res_type = ObObjType(res_type_datum->get_int()); res_type = ObObjType(res_type_datum->get_int());
if(OB_FAIL(datum_to_ob_time(date_datum, date_arg_obj_type, date_arg_type, ob_time))) { if(OB_FAIL(datum_to_ob_time(expr, date_datum, date_arg_obj_type, date_arg_type, ob_time))) {
LOG_WARN("datum_to_ob_time fail.", K(ret), K(date_datum), K(date_arg_obj_type)); LOG_WARN("datum_to_ob_time fail.", K(ret), K(date_datum), K(date_arg_obj_type));
} }
} }
bool offset = false; bool offset = false;
const bool is_zero_on_warn = CM_IS_ZERO_ON_WARN(expr.extra_); const bool is_zero_on_warn = CM_IS_ZERO_ON_WARN(expr.extra_);
const bool is_no_zero_date = CM_IS_NO_ZERO_DATE(expr.extra_);
const bool is_warn_on_fail = CM_IS_WARN_ON_FAIL(expr.extra_);
if (OB_SUCC(ret)) { if (OB_SUCC(ret)) {
switch(date_arg_type) { switch(date_arg_type) {
case VALID_DATE: { case VALID_DATE: {
const bool is_valid_time = true; const bool is_valid_time = true;
if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset, is_zero_on_warn))) { if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset,
is_zero_on_warn, is_no_zero_date, is_warn_on_fail))) {
LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type)); LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type));
} }
break; break;
@ -151,7 +157,8 @@ int ObExprAlignDate4Cmp::eval_align_date4cmp(const ObExpr &expr, ObEvalCtx &ctx,
// if cmp_type == T_OP_EQ or T_OP_NSEQ or T_OP_NE, // if cmp_type == T_OP_EQ or T_OP_NSEQ or T_OP_NE,
// return null or 0 depending on is_zero_on_warn. // return null or 0 depending on is_zero_on_warn.
if (cmp_type == T_OP_EQ || cmp_type == T_OP_NSEQ || cmp_type == T_OP_NE) { if (cmp_type == T_OP_EQ || cmp_type == T_OP_NSEQ || cmp_type == T_OP_NE) {
if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset, is_zero_on_warn))) { if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset,
is_zero_on_warn, is_no_zero_date, is_warn_on_fail))) {
LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type)); LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type));
} }
} else { } else {
@ -159,10 +166,12 @@ int ObExprAlignDate4Cmp::eval_align_date4cmp(const ObExpr &expr, ObEvalCtx &ctx,
offset = (cmp_type == T_OP_GT || cmp_type == T_OP_LE) ? false : true; offset = (cmp_type == T_OP_GT || cmp_type == T_OP_LE) ? false : true;
set_valid_time_floor(ob_time); set_valid_time_floor(ob_time);
is_valid_time = true; is_valid_time = true;
if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset, is_zero_on_warn))) { if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset,
is_zero_on_warn, is_no_zero_date, is_warn_on_fail))) {
LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type)); LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type));
} }
} else if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset, is_zero_on_warn))) { } else if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset,
is_zero_on_warn, is_no_zero_date, is_warn_on_fail))) {
LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type)); LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type));
} }
} }
@ -170,7 +179,8 @@ int ObExprAlignDate4Cmp::eval_align_date4cmp(const ObExpr &expr, ObEvalCtx &ctx,
} }
case NON_DATE: { case NON_DATE: {
const bool is_valid_time = false; const bool is_valid_time = false;
if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset, is_zero_on_warn))) { if (OB_FAIL(set_res(res, ob_time, res_type, is_valid_time, offset,
is_zero_on_warn, is_no_zero_date, is_warn_on_fail))) {
LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type)); LOG_WARN("set_res fail.", K(ret), K(ob_time), K(res_type));
} }
break; break;
@ -179,14 +189,18 @@ int ObExprAlignDate4Cmp::eval_align_date4cmp(const ObExpr &expr, ObEvalCtx &ctx,
res.set_null(); res.set_null();
break; break;
} }
case ZERO_DATE: {
if (OB_FAIL(set_zero_res(res, ob_time, res_type, is_no_zero_date))) {
LOG_WARN("set_zero_res fail.", K(ret), K(ob_time), K(res_type));
}
}
} }
} }
return ret; return ret;
} }
void ObExprAlignDate4Cmp::set_valid_time_floor(ObTime &ob_time)
void ObExprAlignDate4Cmp::set_valid_time_floor(ObTime& ob_time)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if(IS_LEAP_YEAR(ob_time.parts_[DT_YEAR])) { if(IS_LEAP_YEAR(ob_time.parts_[DT_YEAR])) {
@ -203,7 +217,7 @@ void ObExprAlignDate4Cmp::set_valid_time_floor(ObTime& ob_time)
ob_time.parts_[DT_DATE] = ObTimeConverter::ob_time_to_date(ob_time); ob_time.parts_[DT_DATE] = ObTimeConverter::ob_time_to_date(ob_time);
} }
bool ObExprAlignDate4Cmp::day_over_limit(const ObTime& ob_time) bool ObExprAlignDate4Cmp::day_over_limit(const ObTime &ob_time)
{ {
bool res = true; bool res = true;
if(IS_LEAP_YEAR(ob_time.parts_[DT_YEAR])) { if(IS_LEAP_YEAR(ob_time.parts_[DT_YEAR])) {
@ -214,51 +228,109 @@ bool ObExprAlignDate4Cmp::day_over_limit(const ObTime& ob_time)
return res; return res;
} }
int ObExprAlignDate4Cmp::integer_to_ob_time(const int64_t& date, ObExprAlignDate4Cmp::DateArgType ObExprAlignDate4Cmp::validate_time(ObTime &ob_time)
DateArgType& date_arg_type, {
ObTime& ob_time) DateArgType date_arg_type = VALID_DATE;
const int32_t *parts = ob_time.parts_;
if (!HAS_TYPE_ORACLE(ob_time.mode_)
&& 0 == parts[DT_YEAR] && 0 == parts[DT_MON] && 0 == parts[DT_MDAY] && 0 == parts[DT_HOUR]
&& 0 == parts[DT_MIN] && 0 == parts[DT_SEC] && 0 == parts[DT_USEC]) {
date_arg_type = ZERO_DATE;
} else {
const int64_t *part_min = (HAS_TYPE_ORACLE(ob_time.mode_) ? TZ_PART_MIN : DT_PART_MIN);
const int64_t *part_max = (HAS_TYPE_ORACLE(ob_time.mode_) ? TZ_PART_MAX : DT_PART_MAX);
for (int i = 0; i < DATETIME_PART_CNT; ++i) {
if (!(part_min[i] <= parts[i] && parts[i] <= part_max[i])) {
date_arg_type = INVALID_DATE;
}
}
int is_leap = IS_LEAP_YEAR(parts[DT_YEAR]);
if (parts[DT_MDAY] > 31 ||
parts[DT_MDAY] > DAYS_OF_MON[is_leap][parts[DT_MON]]) {
date_arg_type = INVALID_DATE;
}
}
return date_arg_type;
}
int ObExprAlignDate4Cmp::integer_to_ob_time(const int64_t &date,
DateArgType &date_arg_type,
ObTime &ob_time)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObDateSqlMode date_sql_mode; if (date == 0) {
// First try to perform a lenient type conversion. date_arg_type = ZERO_DATE;
// If it fails, it means the value is not convertible to time.
date_sql_mode.allow_invalid_dates_ = true;
date_sql_mode.no_zero_date_ = false;
if (OB_FAIL(ObTimeConverter::int_to_ob_time_with_date(date, ob_time, true, date_sql_mode))) {
date_arg_type = NON_DATE;
ret = OB_SUCCESS;
} else { } else {
// Then perform a strict type conversion check. ObDateSqlMode date_sql_mode;
// If successful, it indicates a VALID_DATE; // First try to perform a lenient type conversion.
// if unsuccessful, it indicates an INVALID_DATE. // If it fails, it means the value is not convertible to time.
date_sql_mode.allow_invalid_dates_ = false; date_sql_mode.allow_invalid_dates_ = true;
date_sql_mode.no_zero_date_ = true; date_sql_mode.no_zero_date_ = false;
if (OB_SUCC(ObTimeConverter::validate_datetime(ob_time, false, date_sql_mode))) { if (OB_FAIL(ObTimeConverter::int_to_ob_time_with_date(date, ob_time, true, date_sql_mode))) {
date_arg_type = VALID_DATE; date_arg_type = NON_DATE;
} else {
date_arg_type = INVALID_DATE;
ret = OB_SUCCESS; ret = OB_SUCCESS;
} else {
// Then perform a strict type conversion check.
date_arg_type = validate_time(ob_time);
} }
} }
return ret; return ret;
} }
int ObExprAlignDate4Cmp::double_to_ob_time(const double& date, DateArgType& date_arg_type, ObTime& ob_time) { static const int64_t MAX_DOUBLE_STRICT_PRINT_SIZE = 512;
return integer_to_ob_time((int64_t)date, date_arg_type, ob_time);
template <typename IN_TYPE>
static int common_floating_number(const IN_TYPE in_val,
const ob_gcvt_arg_type arg_type,
ObIAllocator &alloc,
number::ObNumber &number)
{
int ret = OB_SUCCESS;
char buf[MAX_DOUBLE_STRICT_PRINT_SIZE];
MEMSET(buf, 0, MAX_DOUBLE_STRICT_PRINT_SIZE);
int64_t length = 0;
if (OB_GCVT_ARG_DOUBLE == arg_type) {
length = ob_gcvt_opt(in_val, arg_type, static_cast<int32_t>(sizeof(buf) - 1),
buf, NULL, lib::is_oracle_mode(), TRUE);
} else {
length = ob_gcvt(in_val, OB_GCVT_ARG_DOUBLE, sizeof(buf) - 1, buf, NULL);
}
ObString str(sizeof(buf), static_cast<int32_t>(length), buf);
ObScale res_scale; // useless
ObPrecision res_precision;
ret = number.from_sci_opt(str.ptr(), str.length(), alloc,
&res_precision, &res_scale);
return ret;
} }
int ObExprAlignDate4Cmp::number_to_ob_time(const number::ObNumber& date, DateArgType& date_arg_type, ObTime& ob_time) { int ObExprAlignDate4Cmp::double_to_ob_time(const double &date, DateArgType &date_arg_type, ObTime &ob_time) {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
int64_t date_int = 0; ObNumStackOnceAlloc tmp_alloc;
if (OB_FAIL(date.extract_valid_int64_with_trunc(date_int))) { number::ObNumber number;
LOG_WARN("extract_valid_int64_with_trunc fail.", K(ret), K(date)); if (OB_FAIL(common_floating_number(date, OB_GCVT_ARG_DOUBLE, tmp_alloc, number))) {
} else if (OB_FAIL(integer_to_ob_time(date_int, date_arg_type, ob_time))) { ret = OB_SUCCESS;
LOG_WARN("cast integer to ob_time fail.", K(ret), K(date_int)); date_arg_type = NON_DATE;
} else if (OB_FAIL(number_to_ob_time(number, date_arg_type, ob_time))) {
LOG_WARN("number to ob_time failed", K(ret), K(number));
} }
return ret; return ret;
} }
int ObExprAlignDate4Cmp::str_to_ob_time(const ObString& date, DateArgType& date_arg_type, ObTime& ob_time) { int ObExprAlignDate4Cmp::number_to_ob_time(const number::ObNumber &date, DateArgType &date_arg_type, ObTime &ob_time) {
int ret = OB_SUCCESS;
int64_t int_part = 0;
int64_t dec_part = 0;
if (!date.is_int_parts_valid_int64(int_part, dec_part)) {
date_arg_type = NON_DATE;
} else if (OB_FAIL(integer_to_ob_time(int_part, date_arg_type, ob_time))) {
LOG_WARN("cast integer to ob_time fail.", K(ret), K(int_part));
} else {
ob_time.parts_[DT_USEC] = (dec_part + 500) / 1000;
}
return ret;
}
int ObExprAlignDate4Cmp::str_to_ob_time(const ObString &date, DateArgType &date_arg_type, ObTime &ob_time) {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObDateSqlMode date_sql_mode; ObDateSqlMode date_sql_mode;
date_sql_mode.allow_invalid_dates_ = true; date_sql_mode.allow_invalid_dates_ = true;
@ -267,28 +339,30 @@ int ObExprAlignDate4Cmp::str_to_ob_time(const ObString& date, DateArgType& date_
date_arg_type = NON_DATE; date_arg_type = NON_DATE;
ret = OB_SUCCESS; ret = OB_SUCCESS;
} else { } else {
date_sql_mode.allow_invalid_dates_ = false; date_arg_type = validate_time(ob_time);
date_sql_mode.no_zero_date_ = true;
if (OB_SUCC(ObTimeConverter::validate_datetime(ob_time, false, date_sql_mode))) {
date_arg_type = VALID_DATE;
} else {
date_arg_type = INVALID_DATE;
ret = OB_SUCCESS;
}
} }
return ret; return ret;
} }
int ObExprAlignDate4Cmp::datum_to_ob_time(const ObDatum* date_datum, const ObObjType& date_arg_obj_type, DateArgType& date_arg_type, ObTime& ob_time) int ObExprAlignDate4Cmp::datum_to_ob_time(const ObExpr &expr,
const ObDatum* date_datum,
const ObObjType& date_arg_obj_type,
DateArgType &date_arg_type,
ObTime &ob_time)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
if (date_datum->is_null()) { if (date_datum->is_null()) {
date_arg_type = NULL_DATE; date_arg_type = NULL_DATE;
} else if (ob_is_string_type(date_arg_obj_type)) { } else if (ob_is_string_type(date_arg_obj_type)) {
if (OB_FAIL(str_to_ob_time(date_datum->get_string(), date_arg_type, ob_time))) { ObArenaAllocator lob_allocator(ObModIds::OB_LOB_ACCESS_BUFFER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID());
ObString str = date_datum->get_string();
if (OB_FAIL(ObTextStringHelper::read_real_string_data(&lob_allocator, date_arg_obj_type,
CS_TYPE_BINARY, expr.args_[0]->obj_meta_.has_lob_header(), str))) {
LOG_WARN("fail to get real string data", K(ret), K(date_datum));
} else if (OB_FAIL(str_to_ob_time(str, date_arg_type, ob_time))) {
LOG_WARN("str_to_ob_time fail.", K(ret), K(date_datum)); LOG_WARN("str_to_ob_time fail.", K(ret), K(date_datum));
} }
} else { } else { // numeric
switch(date_arg_obj_type) { switch(date_arg_obj_type) {
case ObNullType: { case ObNullType: {
date_arg_type = NULL_DATE; date_arg_type = NULL_DATE;
@ -299,8 +373,7 @@ int ObExprAlignDate4Cmp::datum_to_ob_time(const ObDatum* date_datum, const ObObj
case ObMediumIntType: case ObMediumIntType:
case ObInt32Type: case ObInt32Type:
case ObIntType: { case ObIntType: {
if (OB_FAIL(integer_to_ob_time(static_cast<int64_t>(date_datum->get_uint()), if (OB_FAIL(integer_to_ob_time(date_datum->get_int(), date_arg_type, ob_time))) {
date_arg_type, ob_time))) {
LOG_WARN("integer_to_ob_time fail.", K(ret), K(date_datum)); LOG_WARN("integer_to_ob_time fail.", K(ret), K(date_datum));
} }
break; break;
@ -310,7 +383,8 @@ int ObExprAlignDate4Cmp::datum_to_ob_time(const ObDatum* date_datum, const ObObj
case ObUMediumIntType: case ObUMediumIntType:
case ObUInt32Type: case ObUInt32Type:
case ObUInt64Type: { case ObUInt64Type: {
if (OB_FAIL(integer_to_ob_time(date_datum->get_int(), date_arg_type, ob_time))) { if (OB_FAIL(integer_to_ob_time(static_cast<int64_t>(date_datum->get_uint()),
date_arg_type, ob_time))) {
LOG_WARN("integer_to_ob_time fail.", K(ret), K(date_datum)); LOG_WARN("integer_to_ob_time fail.", K(ret), K(date_datum));
} }
break; break;
@ -344,7 +418,6 @@ int ObExprAlignDate4Cmp::datum_to_ob_time(const ObDatum* date_datum, const ObObj
} }
} }
} }
return ret; return ret;
} }
@ -352,7 +425,9 @@ int ObExprAlignDate4Cmp::set_res(ObDatum &res, ObTime &ob_time,
const ObObjType &res_type, const ObObjType &res_type,
const bool is_valid_time, const bool is_valid_time,
const bool offset, const bool offset,
const bool is_zero_on_warn) const bool is_zero_on_warn,
const bool is_no_zero_date,
const bool is_warn_on_fail)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
switch(res_type) { switch(res_type) {
@ -362,8 +437,10 @@ int ObExprAlignDate4Cmp::set_res(ObDatum &res, ObTime &ob_time,
} }
case ObDateTimeType: { case ObDateTimeType: {
if (!is_valid_time) { if (!is_valid_time) {
if (is_zero_on_warn) { if (!is_warn_on_fail) {
res.set_datetime(0); ret = OB_INVALID_DATE_FORMAT;
} else if (is_zero_on_warn && !is_no_zero_date) {
res.set_datetime(ObTimeConverter::ZERO_DATETIME);
} else { } else {
res.set_null(); res.set_null();
} }
@ -380,8 +457,10 @@ int ObExprAlignDate4Cmp::set_res(ObDatum &res, ObTime &ob_time,
} }
case ObDateType: { case ObDateType: {
if (!is_valid_time) { if (!is_valid_time) {
if (is_zero_on_warn) { if (!is_warn_on_fail) {
res.set_date(0); ret = OB_INVALID_DATE_FORMAT;
} else if (is_zero_on_warn && !is_no_zero_date) {
res.set_date(ObTimeConverter::ZERO_DATE);
} else { } else {
res.set_null(); res.set_null();
} }
@ -397,11 +476,45 @@ int ObExprAlignDate4Cmp::set_res(ObDatum &res, ObTime &ob_time,
break; break;
} }
} }
return ret; return ret;
} }
bool ObExprAlignDate4Cmp::is_align_date4cmp_support_obj_type(const ObObjType& obj_type) { int ObExprAlignDate4Cmp::set_zero_res(ObDatum &res, ObTime &ob_time,
const ObObjType &res_type,
bool is_no_zero_date)
{
int ret = OB_SUCCESS;
switch(res_type) {
case ObNullType: {
res.set_null();
break;
}
case ObDateTimeType: {
if (is_no_zero_date) {
res.set_null();
} else {
res.set_datetime(ObTimeConverter::ZERO_DATETIME + ob_time.parts_[DT_USEC]);
}
break;
}
case ObDateType: {
if (is_no_zero_date) {
res.set_null();
} else {
res.set_date(ObTimeConverter::ZERO_DATE);
}
break;
}
default: {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("unexpected res type.", K(ret), K(res_type));
break;
}
}
return ret;
}
bool ObExprAlignDate4Cmp::is_align_date4cmp_support_obj_type(const ObObjType &obj_type) {
bool res = false; bool res = false;
if (ObNullType <= obj_type && obj_type <= ObUNumberType) { if (ObNullType <= obj_type && obj_type <= ObUNumberType) {
res = true; res = true;

View File

@ -52,6 +52,7 @@ public:
INVALID_DATE = 2, INVALID_DATE = 2,
NON_DATE = 3, NON_DATE = 3,
NULL_DATE = 4, NULL_DATE = 4,
ZERO_DATE = 5,
}; };
private: private:
@ -60,19 +61,27 @@ private:
static bool day_over_limit(const ObTime &ob_time); static bool day_over_limit(const ObTime &ob_time);
static void set_valid_time_floor(ObTime &ob_time); static void set_valid_time_floor(ObTime &ob_time);
static DateArgType validate_time(ObTime &ob_time);
static int integer_to_ob_time(const int64_t &date, DateArgType &date_arg_type, ObTime &ob_time); static int integer_to_ob_time(const int64_t &date, DateArgType &date_arg_type, ObTime &ob_time);
static int double_to_ob_time(const double &date, DateArgType &date_arg_type, ObTime &ob_time); static int double_to_ob_time(const double &date, DateArgType &date_arg_type, ObTime &ob_time);
static int number_to_ob_time(const number::ObNumber &date, DateArgType &date_arg_type, ObTime &ob_time); static int number_to_ob_time(const number::ObNumber &date, DateArgType &date_arg_type, ObTime &ob_time);
static int str_to_ob_time(const ObString &date, DateArgType &date_arg_type, ObTime &ob_time); static int str_to_ob_time(const ObString &date, DateArgType &date_arg_type, ObTime &ob_time);
static int datum_to_ob_time(const ObDatum *date_datum, static int datum_to_ob_time(const ObExpr &expr,
const ObDatum *date_datum,
const ObObjType &date_arg_obj_type, const ObObjType &date_arg_obj_type,
DateArgType &date_arg_type, DateArgType &date_arg_type,
ObTime &ob_time); ObTime &ob_time);
static bool is_zero_time(ObTime &ob_time);
static int set_res(ObDatum &res, ObTime &ob_time, static int set_res(ObDatum &res, ObTime &ob_time,
const ObObjType &res_type, const ObObjType &res_type,
const bool is_valid_time, const bool is_valid_time,
const bool offset, const bool offset,
const bool is_zero_on_warn); const bool is_zero_on_warn,
const bool is_no_zero_date,
const bool is_warn_on_fail);
static int set_zero_res(ObDatum &res, ObTime &ob_time,
const ObObjType &res_type,
bool is_no_zero_date);
}; };
} }
} }