[Regression](datev2) Add test cases for datev2/datetimev2 (#11831)

This commit is contained in:
Gabriel
2022-08-19 10:57:55 +08:00
committed by GitHub
parent 089fe01aea
commit 1f9eec5462
72 changed files with 2942 additions and 1320 deletions

View File

@ -431,9 +431,6 @@ public class DateLiteral extends LiteralExpr {
minute = getOrDefault(dateTime, ChronoField.MINUTE_OF_HOUR, 0);
second = getOrDefault(dateTime, ChronoField.SECOND_OF_MINUTE, 0);
microsecond = getOrDefault(dateTime, ChronoField.MICRO_OF_SECOND, 0);
if (type.isDatetimeV2()) {
this.roundFloor(((ScalarType) type).getScalarScale());
}
this.type = type;
} catch (Exception ex) {
throw new AnalysisException("date literal [" + s + "] is invalid: " + ex.getMessage());
@ -526,12 +523,14 @@ public class DateLiteral extends LiteralExpr {
if (type.isDate() || type.isDateV2()) {
return String.format("%04d-%02d-%02d", year, month, day);
} else if (type.isDatetimeV2()) {
long ms = Double.valueOf(microsecond / (int) (Math.pow(10, 6 - ((ScalarType) type).getScalarScale()))
* (Math.pow(10, 6 - ((ScalarType) type).getScalarScale()))).longValue();
String tmp = String.format("%04d-%02d-%02d %02d:%02d:%02d",
year, month, day, hour, minute, second);
if (microsecond == 0) {
if (ms == 0) {
return tmp;
}
return tmp + String.format(".%06d", microsecond);
return tmp + String.format(".%06d", ms);
} else {
return String.format("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second);
}
@ -542,13 +541,23 @@ public class DateLiteral extends LiteralExpr {
long remain = Double.valueOf(microsecond % (Math.pow(10, 6 - newScale))).longValue();
if (remain != 0) {
microsecond = Double.valueOf((microsecond + (Math.pow(10, 6 - newScale)))
/ (Math.pow(10, 6 - newScale)) * (Math.pow(10, 6 - newScale))).longValue();
/ (int) (Math.pow(10, 6 - newScale)) * (Math.pow(10, 6 - newScale))).longValue();
}
if (microsecond > MAX_MICROSECOND) {
microsecond %= microsecond;
DateLiteral result = this.plusSeconds(1);
this.second = result.second;
this.minute = result.minute;
this.hour = result.hour;
this.day = result.day;
this.month = result.month;
this.year = result.year;
}
type = ScalarType.createDatetimeV2Type(newScale);
}
public void roundFloor(int newScale) {
microsecond = Double.valueOf(microsecond / (Math.pow(10, 6 - newScale))
microsecond = Double.valueOf(microsecond / (int) (Math.pow(10, 6 - newScale))
* (Math.pow(10, 6 - newScale))).longValue();
type = ScalarType.createDatetimeV2Type(newScale);
}
@ -580,6 +589,9 @@ public class DateLiteral extends LiteralExpr {
@Override
protected void toThrift(TExprNode msg) {
if (type.isDatetimeV2()) {
this.roundFloor(((ScalarType) type).getScalarScale());
}
msg.node_type = TExprNodeType.DATE_LITERAL;
msg.date_literal = new TDateLiteral(getStringValue());
}
@ -870,11 +882,11 @@ public class DateLiteral extends LiteralExpr {
return new DateLiteral(getTimeFormatter().plusHours(hour), type);
}
public DateLiteral plusMinutes(int minute) throws AnalysisException {
public DateLiteral plusMinutes(int minute) {
return new DateLiteral(getTimeFormatter().plusMinutes(minute), type);
}
public DateLiteral plusSeconds(int second) throws AnalysisException {
public DateLiteral plusSeconds(int second) {
return new DateLiteral(getTimeFormatter().plusSeconds(second), type);
}

View File

@ -20,6 +20,7 @@
package org.apache.doris.analysis;
import org.apache.doris.catalog.Type;
import org.apache.doris.common.AnalysisException;
import com.google.gson.annotations.SerializedName;
@ -42,10 +43,10 @@ public class DefaultValueExprDef {
* generate a FunctionCallExpr
* @return FunctionCallExpr of exprName
*/
public FunctionCallExpr getExpr() {
public FunctionCallExpr getExpr(Type type) {
FunctionCallExpr expr = new FunctionCallExpr(exprName, new FunctionParams(null));
try {
expr.analyzeImplForDefaultValue();
expr.analyzeImplForDefaultValue(type);
} catch (AnalysisException e) {
LOG.warn("analyzeImplForDefaultValue fail: {}", e);
}

View File

@ -827,9 +827,10 @@ public class FunctionCallExpr extends Expr {
* to generate a builtinFunction.
* @throws AnalysisException
*/
public void analyzeImplForDefaultValue() throws AnalysisException {
public void analyzeImplForDefaultValue(Type type) throws AnalysisException {
fn = getBuiltinFunction(fnName.getFunction(), new Type[0], Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
type = ScalarType.getDefaultDateType(fn.getReturnType());
fn.setReturnType(type);
this.type = type;
for (int i = 0; i < children.size(); ++i) {
if (getChild(i).getType().isNull()) {
uncheckedCastChild(Type.BOOLEAN, i);
@ -936,6 +937,9 @@ public class FunctionCallExpr extends Expr {
childTypes[2] = assignmentCompatibleType;
fn = getBuiltinFunction(fnName.getFunction(), childTypes,
Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF);
if (assignmentCompatibleType.isDatetimeV2()) {
fn.setReturnType(assignmentCompatibleType);
}
} else if (AggregateFunction.SUPPORT_ORDER_BY_AGGREGATE_FUNCTION_NAME_SET.contains(
fnName.getFunction().toLowerCase())) {
// order by elements add as child like windows function. so if we get the
@ -995,6 +999,15 @@ public class FunctionCallExpr extends Expr {
throw new AnalysisException(getFunctionNotFoundError(collectChildReturnTypes()));
}
if (fn.getArgs().length == children.size() && fn.getArgs().length == 1) {
if (fn.getArgs()[0].isDatetimeV2() && children.get(0).getType().isDatetimeV2()) {
fn.setArgType(children.get(0).getType(), 0);
if (fn.getReturnType().isDatetimeV2()) {
fn.setReturnType(children.get(0).getType());
}
}
}
if (fnName.getFunction().equalsIgnoreCase("from_unixtime")
|| fnName.getFunction().equalsIgnoreCase("date_format")) {
// if has only one child, it has default time format: yyyy-MM-dd HH:mm:ss.SSSSSS

View File

@ -319,7 +319,7 @@ public class Column implements Writable {
return defaultValueLiteral;
}
if (defaultValueExprDef != null) {
return defaultValueExprDef.getExpr();
return defaultValueExprDef.getExpr(type);
}
Expr result = defaultValueLiteral.castTo(getType());
result.checkValueValid();

View File

@ -180,6 +180,10 @@ public class Function implements Writable {
this.retType = type;
}
public void setArgType(Type type, int i) {
argTypes[i] = type;
}
public Type[] getArgs() {
return argTypes;
}

View File

@ -986,6 +986,12 @@ public class ScalarType extends Type {
PrimitiveType largerType =
(t1.type.ordinal() > t2.type.ordinal() ? t1.type : t2.type);
PrimitiveType result = null;
if (t1.isDatetimeV2() && t2.isDatetimeV2()) {
return t1.scale > t2.scale ? t1 : t2;
}
if ((t1.isDatetimeV2() || t1.isDateV2()) && (t1.isDatetimeV2() || t1.isDateV2())) {
return t1.isDatetimeV2() ? t1 : t2;
}
if (strict) {
result = strictCompatibilityMatrix[smallerType.ordinal()][largerType.ordinal()];
}

View File

@ -1547,6 +1547,8 @@ public abstract class Type {
return t1;
} else if (t2.isDatetimeV2()) {
return t2;
} else if (t2.isDateV2() || t1.isDateV2()) {
return Type.DATETIMEV2;
} else {
return ScalarType.getDefaultDateType(Type.DATETIME);
}

View File

@ -591,10 +591,10 @@ public class DeleteHandler implements Writable {
Type.fromPrimitiveType(column.getDataType())));
} else if (column.getDataType() == PrimitiveType.DATETIMEV2) {
DateLiteral dateLiteral = new DateLiteral(value,
ScalarType.createDecimalType(ScalarType.MAX_DATETIMEV2_SCALE));
ScalarType.createDatetimeV2Type(ScalarType.MAX_DATETIMEV2_SCALE));
value = dateLiteral.getStringValue();
binaryPredicate.setChild(1, LiteralExpr.create(value,
ScalarType.createDecimalType(ScalarType.MAX_DATETIMEV2_SCALE)));
ScalarType.createDatetimeV2Type(ScalarType.MAX_DATETIMEV2_SCALE)));
}
LiteralExpr.create(value, Type.fromPrimitiveType(column.getDataType()));
} catch (AnalysisException e) {

View File

@ -99,44 +99,41 @@ public class RoundLiteralInBinaryPredicatesRule implements ExprRewriteRule {
Expr expr1 = expr.getChild(1);
if (expr0.getType().isDatetimeV2() && expr1 instanceof DateLiteral && expr1.getType().isDatetimeV2()) {
DateLiteral literal = (DateLiteral) expr1;
if (((ScalarType) expr0.getType()).getScalarScale()
< ((ScalarType) expr1.getType()).getScalarScale()) {
switch (op) {
case EQ: {
long originValue = literal.getMicrosecond();
literal.roundCeiling(((ScalarType) expr0.getType()).getScalarScale());
if (literal.getMicrosecond() == originValue) {
expr.setChild(1, literal);
return expr;
} else {
return new BoolLiteral(false);
}
}
case NE: {
long originValue = literal.getMicrosecond();
literal.roundCeiling(((ScalarType) expr0.getType()).getScalarScale());
if (literal.getMicrosecond() == originValue) {
expr.setChild(1, literal);
return expr;
} else {
return new BoolLiteral(true);
}
}
case GT:
case LE: {
literal.roundFloor(((ScalarType) expr0.getType()).getScalarScale());
switch (op) {
case EQ: {
long originValue = literal.getMicrosecond();
literal.roundCeiling(((ScalarType) expr0.getType()).getScalarScale());
if (literal.getMicrosecond() == originValue) {
expr.setChild(1, literal);
return expr;
} else {
return new BoolLiteral(false);
}
case LT:
case GE: {
literal.roundCeiling(((ScalarType) expr0.getType()).getScalarScale());
expr.setChild(1, literal);
return expr;
}
default:
return expr;
}
case NE: {
long originValue = literal.getMicrosecond();
literal.roundCeiling(((ScalarType) expr0.getType()).getScalarScale());
if (literal.getMicrosecond() == originValue) {
expr.setChild(1, literal);
return expr;
} else {
return new BoolLiteral(true);
}
}
case GT:
case LE: {
literal.roundFloor(((ScalarType) expr0.getType()).getScalarScale());
expr.setChild(1, literal);
return expr;
}
case LT:
case GE: {
literal.roundCeiling(((ScalarType) expr0.getType()).getScalarScale());
expr.setChild(1, literal);
return expr;
}
default:
return expr;
}
}
return expr;