align_date4cmp bug fixs
This commit is contained in:
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user