@ -93,28 +93,36 @@ void VLiteral::init(const TExprNode& node) {
|
||||
}
|
||||
case TYPE_DATE: {
|
||||
VecDateTimeValue value;
|
||||
value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size());
|
||||
value.cast_to_date();
|
||||
field = Int64(*reinterpret_cast<__int64_t*>(&value));
|
||||
if (value.from_date_str(node.date_literal.value.c_str(),
|
||||
node.date_literal.value.size())) {
|
||||
value.cast_to_date();
|
||||
field = Int64(*reinterpret_cast<__int64_t*>(&value));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_DATEV2: {
|
||||
DateV2Value<DateV2ValueType> value;
|
||||
value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size());
|
||||
field = value.to_date_int_val();
|
||||
if (value.from_date_str(node.date_literal.value.c_str(),
|
||||
node.date_literal.value.size())) {
|
||||
field = value.to_date_int_val();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_DATETIMEV2: {
|
||||
DateV2Value<DateTimeV2ValueType> value;
|
||||
value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size());
|
||||
field = value.to_date_int_val();
|
||||
if (value.from_date_str(node.date_literal.value.c_str(),
|
||||
node.date_literal.value.size())) {
|
||||
field = value.to_date_int_val();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_DATETIME: {
|
||||
VecDateTimeValue value;
|
||||
value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size());
|
||||
value.to_datetime();
|
||||
field = Int64(*reinterpret_cast<__int64_t*>(&value));
|
||||
if (value.from_date_str(node.date_literal.value.c_str(),
|
||||
node.date_literal.value.size())) {
|
||||
value.to_datetime();
|
||||
field = Int64(*reinterpret_cast<__int64_t*>(&value));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_STRING:
|
||||
|
||||
@ -627,6 +627,13 @@ public class DateLiteral extends LiteralExpr {
|
||||
}
|
||||
msg.node_type = TExprNodeType.DATE_LITERAL;
|
||||
msg.date_literal = new TDateLiteral(getStringValue());
|
||||
try {
|
||||
checkValueValid();
|
||||
} catch (AnalysisException e) {
|
||||
// If date value is invalid, set this to null
|
||||
msg.node_type = TExprNodeType.NULL_LITERAL;
|
||||
msg.setIsNullable(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -775,6 +782,11 @@ public class DateLiteral extends LiteralExpr {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isLeapYear() {
|
||||
return ((year % 4) == 0) && ((year % 100 != 0) || ((year % 400) == 0 && year > 0));
|
||||
}
|
||||
|
||||
// Validation check should be same as DateV2Value<T>::is_invalid in BE
|
||||
@Override
|
||||
public void checkValueValid() throws AnalysisException {
|
||||
if (year < 0 || year > 9999) {
|
||||
@ -783,8 +795,10 @@ public class DateLiteral extends LiteralExpr {
|
||||
if (month < 1 || month > 12) {
|
||||
throw new AnalysisException("DateLiteral has invalid month value: " + month);
|
||||
}
|
||||
if (day < 1 || day > 31) {
|
||||
throw new AnalysisException("DateLiteral has invalid day value: " + day);
|
||||
if (day < 1 || day > DAYS_IN_MONTH[(int) month]) {
|
||||
if (!(month == 2 && day == 29 && isLeapYear())) {
|
||||
throw new AnalysisException("DateLiteral has invalid day value: " + day);
|
||||
}
|
||||
}
|
||||
if (type.isDatetimeV2() || type.isDatetime()) {
|
||||
if (hour < 0 || hour > 24) {
|
||||
|
||||
@ -98,7 +98,18 @@ public enum ExpressionFunctions {
|
||||
FEFunctionInvoker invoker = getFunction(signature);
|
||||
if (invoker != null) {
|
||||
try {
|
||||
return invoker.invoke(constExpr.getChildrenWithoutCast());
|
||||
if (fn.getReturnType().isDateType()) {
|
||||
Expr dateLiteral = invoker.invoke(constExpr.getChildrenWithoutCast());
|
||||
Preconditions.checkArgument(dateLiteral instanceof DateLiteral);
|
||||
try {
|
||||
((DateLiteral) dateLiteral).checkValueValid();
|
||||
} catch (AnalysisException e) {
|
||||
return NullLiteral.create(dateLiteral.getType());
|
||||
}
|
||||
return dateLiteral;
|
||||
} else {
|
||||
return invoker.invoke(constExpr.getChildrenWithoutCast());
|
||||
}
|
||||
} catch (AnalysisException e) {
|
||||
LOG.debug("failed to invoke", e);
|
||||
return constExpr;
|
||||
|
||||
@ -194,6 +194,11 @@ public class StringLiteral extends LiteralExpr {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
try {
|
||||
newLiteral.checkValueValid();
|
||||
} catch (AnalysisException e) {
|
||||
return NullLiteral.create(newLiteral.getType());
|
||||
}
|
||||
return newLiteral;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
-- This file is automatically generated. You should know what you did if you want to edit this
|
||||
-- !sql1 --
|
||||
\N
|
||||
|
||||
-- !sql2 --
|
||||
\N
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
suite("test_invalid_date") {
|
||||
def tbName = "test_invalid_date"
|
||||
sql "DROP TABLE IF EXISTS ${tbName}"
|
||||
sql """
|
||||
CREATE TABLE IF NOT EXISTS ${tbName} (
|
||||
c0 int,
|
||||
c1 char(10),
|
||||
c2 date,
|
||||
c3 datev2
|
||||
)
|
||||
UNIQUE KEY(c0)
|
||||
DISTRIBUTED BY HASH(c0) BUCKETS 5 properties("replication_num" = "1");
|
||||
"""
|
||||
sql "insert into ${tbName} values(1, 'test1', '2000-01-01', '2000-01-01')"
|
||||
|
||||
qt_sql1 "select str_to_date('202301', '%Y%m');"
|
||||
qt_sql2 "select str_to_date('202301', '%Y%m') from ${tbName}"
|
||||
sql "DROP TABLE ${tbName}"
|
||||
}
|
||||
Reference in New Issue
Block a user