[Function] Let "str_to_date" return correct type (#5004)
The return type of str_to_date depends on whether the time part is included in the format.
If included, it is DATETIME, otherwise it is DATE.
If the format parameter is not constant, the return type will be DATETIME.
The above judgment has been completed in the FE query planning stage,
so here we directly set the value type to the return type set in the query plan.
For example:
A table with one column k1 varchar, and has 2 lines:
"%Y-%m-%d"
"%Y-%m-%d %H:%i:%s"
Query:
SELECT str_to_date("2020-09-01", k1) from tbl;
Result will be:
2020-09-01 00:00:00
2020-09-01 00:00:00
Query:
SELECT str_to_date("2020-09-01", "%Y-%m-%d");
Return type is DATE
Query:
SELECT str_to_date("2020-09-01", "%Y-%m-%d %H:%i:%s");
Return type is DATETIME
This commit is contained in:
@ -203,6 +203,26 @@ DateTimeVal TimestampFunctions::str_to_date(FunctionContext* ctx, const StringVa
|
||||
str.len)) {
|
||||
return DateTimeVal::null();
|
||||
}
|
||||
|
||||
/// The return type of str_to_date depends on whether the time part is included in the format.
|
||||
/// If included, it is datetime, otherwise it is date.
|
||||
/// If the format parameter is not constant, the return type will be datetime.
|
||||
/// The above judgment has been completed in the FE query planning stage,
|
||||
/// so here we directly set the value type to the return type set in the query plan.
|
||||
///
|
||||
/// For example:
|
||||
/// A table with one column k1 varchar, and has 2 lines:
|
||||
/// "%Y-%m-%d"
|
||||
/// "%Y-%m-%d %H:%i:%s"
|
||||
/// Query:
|
||||
/// SELECT str_to_date("2020-09-01", k1) from tbl;
|
||||
/// Result will be:
|
||||
/// 2020-09-01 00:00:00
|
||||
/// 2020-09-01 00:00:00
|
||||
if (ctx->impl()->get_return_type().type == doris_udf::FunctionContext::Type::TYPE_DATETIME) {
|
||||
ts_value.to_datetime();
|
||||
}
|
||||
|
||||
DateTimeVal ts_val;
|
||||
ts_value.to_datetime_val(&ts_val);
|
||||
return ts_val;
|
||||
|
||||
@ -102,6 +102,8 @@ public:
|
||||
|
||||
std::string& string_result() { return _string_result; }
|
||||
|
||||
const doris_udf::FunctionContext::TypeDesc& get_return_type() const { return _return_type; }
|
||||
|
||||
private:
|
||||
friend class doris_udf::FunctionContext;
|
||||
friend class ExprContext;
|
||||
|
||||
@ -498,7 +498,7 @@ public class DateLiteral extends LiteralExpr {
|
||||
dateTime.getHourOfDay(),
|
||||
dateTime.getMinuteOfHour(),
|
||||
dateTime.getSecondOfMinute());
|
||||
if(HAS_TIME_PART.matcher(pattern).matches()) {
|
||||
if (HAS_TIME_PART.matcher(pattern).matches()) {
|
||||
dateLiteral.setType(Type.DATETIME);
|
||||
} else {
|
||||
dateLiteral.setType(Type.DATE);
|
||||
@ -506,6 +506,10 @@ public class DateLiteral extends LiteralExpr {
|
||||
return dateLiteral;
|
||||
}
|
||||
|
||||
public static boolean hasTimePart(String format) {
|
||||
return HAS_TIME_PART.matcher(format).matches();
|
||||
}
|
||||
|
||||
//Return the date stored in the dateliteral as pattern format.
|
||||
//eg : "%Y-%m-%d" or "%Y-%m-%d %H:%i:%s"
|
||||
public String dateFormat(String pattern) throws AnalysisException {
|
||||
|
||||
@ -646,7 +646,46 @@ public class FunctionCallExpr extends Expr {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.type = fn.getReturnType();
|
||||
|
||||
/**
|
||||
* The return type of str_to_date depends on whether the time part is included in the format.
|
||||
* If included, it is datetime, otherwise it is date.
|
||||
* If the format parameter is not constant, the return type will be datetime.
|
||||
* The above judgment has been completed in the FE query planning stage,
|
||||
* so here we directly set the value type to the return type set in the query plan.
|
||||
*
|
||||
* For example:
|
||||
* A table with one column k1 varchar, and has 2 lines:
|
||||
* "%Y-%m-%d"
|
||||
* "%Y-%m-%d %H:%i:%s"
|
||||
* Query:
|
||||
* SELECT str_to_date("2020-09-01", k1) from tbl;
|
||||
* Result will be:
|
||||
* 2020-09-01 00:00:00
|
||||
* 2020-09-01 00:00:00
|
||||
*
|
||||
* Query:
|
||||
* SELECT str_to_date("2020-09-01", "%Y-%m-%d");
|
||||
* Return type is DATE
|
||||
*
|
||||
* Query:
|
||||
* SELECT str_to_date("2020-09-01", "%Y-%m-%d %H:%i:%s");
|
||||
* Return type is DATETIME
|
||||
*/
|
||||
if (fn.getFunctionName().getFunction().equals("str_to_date")) {
|
||||
Expr child1Result = getChild(1).getResultValue();
|
||||
if (child1Result instanceof StringLiteral) {
|
||||
if (DateLiteral.hasTimePart(((StringLiteral) child1Result).getStringValue())) {
|
||||
this.type = Type.DATETIME;
|
||||
} else {
|
||||
this.type = Type.DATE;
|
||||
}
|
||||
} else {
|
||||
this.type = Type.DATETIME;
|
||||
}
|
||||
} else {
|
||||
this.type = fn.getReturnType();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -734,3 +773,4 @@ public class FunctionCallExpr extends Expr {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user