diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java index 5a88ab8e7e..904d57777a 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/Analyzer.java @@ -1880,7 +1880,7 @@ public class Analyzer { } if (compatibleType.equals(Type.VARCHAR)) { if (exprs.get(0).getType().isDateType()) { - compatibleType = Type.DATETIME; + compatibleType = DateLiteral.getDefaultDateType(Type.DATETIME); } } // Add implicit casts if necessary. diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateFunctionStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateFunctionStmt.java index 74f9c29ad7..d5f7253d6c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateFunctionStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateFunctionStmt.java @@ -523,7 +523,9 @@ public class CreateFunctionStmt extends DdlStmt { .put(PrimitiveType.VARCHAR, Sets.newHashSet(String.class)) .put(PrimitiveType.STRING, Sets.newHashSet(String.class)) .put(PrimitiveType.DATE, Sets.newHashSet(LocalDate.class)) + .put(PrimitiveType.DATEV2, Sets.newHashSet(LocalDate.class)) .put(PrimitiveType.DATETIME, Sets.newHashSet(LocalDateTime.class)) + .put(PrimitiveType.DATETIMEV2, Sets.newHashSet(LocalDateTime.class)) .put(PrimitiveType.LARGEINT, Sets.newHashSet(BigInteger.class)) .put(PrimitiveType.DECIMALV2, Sets.newHashSet(BigDecimal.class)) .build(); @@ -617,15 +619,19 @@ public class CreateFunctionStmt extends DdlStmt { typeBuilder.setId(Types.PGenericType.TypeId.BITMAP); break; case DATE: - case DATEV2: typeBuilder.setId(Types.PGenericType.TypeId.DATE); break; + case DATEV2: + typeBuilder.setId(Types.PGenericType.TypeId.DATEV2); + break; case DATETIME: - case DATETIMEV2: case TIME: - case TIMEV2: typeBuilder.setId(Types.PGenericType.TypeId.DATETIME); break; + case DATETIMEV2: + case TIMEV2: + typeBuilder.setId(Types.PGenericType.TypeId.DATETIMEV2); + break; case DECIMALV2: typeBuilder.setId(Types.PGenericType.TypeId.DECIMAL128) .getDecimalTypeBuilder() diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java index e5953ea44d..88898f6c64 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DateLiteral.java @@ -230,11 +230,7 @@ public class DateLiteral extends LiteralExpr { this.year = year; this.month = month; this.day = day; - try { - this.type = DateLiteral.getDefaultDateType(Type.DATE); - } catch (AnalysisException e) { - this.type = Type.DATE; - } + this.type = DateLiteral.getDefaultDateType(Type.DATE); } public DateLiteral(long year, long month, long day, Type type) { @@ -256,11 +252,7 @@ public class DateLiteral extends LiteralExpr { this.year = year; this.month = month; this.day = day; - try { - this.type = DateLiteral.getDefaultDateType(Type.DATETIME); - } catch (AnalysisException e) { - this.type = Type.DATETIME; - } + this.type = DateLiteral.getDefaultDateType(Type.DATETIME); } public DateLiteral(long year, long month, long day, long hour, long minute, long second, long microsecond) { @@ -1444,7 +1436,7 @@ public class DateLiteral extends LiteralExpr { } } - public static Type getDefaultDateType(Type type) throws AnalysisException { + public static Type getDefaultDateType(Type type) { switch (type.getPrimitiveType()) { case DATE: if (Config.use_date_v2_by_default) { @@ -1460,9 +1452,8 @@ public class DateLiteral extends LiteralExpr { } case DATEV2: case DATETIMEV2: - return type; default: - throw new AnalysisException("Invalid date type: " + type); + return type; } } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/OutFileClause.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/OutFileClause.java index 7f8b1436a0..6cc2ef11d5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/OutFileClause.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/OutFileClause.java @@ -233,14 +233,16 @@ public class OutFileClause { case TINYINT: case SMALLINT: case INT: + case DATEV2: if (!type.equals("int32")) { - throw new AnalysisException("project field type is TINYINT/SMALLINT/INT, should use int32, " - + "but the definition type of column " + i + " is " + type); + throw new AnalysisException("project field type is TINYINT/SMALLINT/INT/DATEV2," + + "should use int32, " + "but the definition type of column " + i + " is " + type); } break; case BIGINT: case DATE: case DATETIME: + case DATETIMEV2: if (!type.equals("int64")) { throw new AnalysisException("project field type is BIGINT/DATE/DATETIME, should use int64, " + "but the definition type of column " + i + " is " + type); @@ -300,11 +302,13 @@ public class OutFileClause { case TINYINT: case SMALLINT: case INT: + case DATEV2: column.add("int32"); break; case BIGINT: case DATE: case DATETIME: + case DATETIMEV2: column.add("int64"); break; case FLOAT: diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPartitionsStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPartitionsStmt.java index 368619fcc6..7de6993be8 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPartitionsStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ShowPartitionsStmt.java @@ -45,6 +45,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; public class ShowPartitionsStmt extends ShowStmt { private static final Logger LOG = LogManager.getLogger(ShowPartitionsStmt.class); @@ -193,7 +194,8 @@ public class ShowPartitionsStmt extends ShowStmt { throw new AnalysisException("Where clause : LastConsistencyCheckTime =|>=|<=|>|<|!= " + "\"2019-12-22|2019-12-22 22:22:00\""); } - subExpr.setChild(1, (subExpr.getChild(1)).castTo(Type.DATETIME)); + subExpr.setChild(1, (subExpr.getChild(1)).castTo( + Objects.requireNonNull(DateLiteral.getDefaultDateType(Type.DATETIME)))); } else if (!leftKey.equalsIgnoreCase(FILTER_PARTITION_ID) && !leftKey.equalsIgnoreCase(FILTER_BUCKETS) && !leftKey.equalsIgnoreCase(FILTER_REPLICATION_NUM)) { throw new AnalysisException("Only the columns of PartitionId/PartitionName/" diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java index 3f8a143f73..16f6fc4e74 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/TimestampArithmeticExpr.java @@ -23,6 +23,7 @@ import org.apache.doris.catalog.PrimitiveType; import org.apache.doris.catalog.ScalarType; import org.apache.doris.catalog.Type; import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.Config; import org.apache.doris.common.ErrorCode; import org.apache.doris.common.ErrorReport; import org.apache.doris.thrift.TExprNode; @@ -111,6 +112,16 @@ public class TimestampArithmeticExpr extends Expr { if (t1 == PrimitiveType.DATE) { return Type.DATE; } + if (t1 == PrimitiveType.DATETIMEV2) { + return Type.DATETIMEV2; + } + if (t1 == PrimitiveType.DATEV2) { + return Type.DATEV2; + } + if (Config.use_date_v2_by_default + && PrimitiveType.isImplicitCast(t1, PrimitiveType.DATETIMEV2)) { + return Type.DATETIMEV2; + } if (PrimitiveType.isImplicitCast(t1, PrimitiveType.DATETIME)) { return Type.DATETIME; } @@ -129,7 +140,7 @@ public class TimestampArithmeticExpr extends Expr { } Type dateType = fixType(); if (dateType.isDate() && timeUnit.isDateTime()) { - dateType = Type.DATETIME; + dateType = DateLiteral.getDefaultDateType(Type.DATETIME); } // The first child must return a timestamp or null. if (!getChild(0).getType().isDateType() && !getChild(0).getType().isNull()) { @@ -183,6 +194,9 @@ public class TimestampArithmeticExpr extends Expr { if (dateType.isDate() && timeUnit.isDateTime()) { dateType = Type.DATETIME; } + if (dateType.isDateV2() && timeUnit.isDateTime()) { + dateType = Type.DATETIMEV2; + } // The first child must return a timestamp or null. if (!getChild(0).getType().isDateType() && !getChild(0).getType().isNull()) { if (!dateType.isValid()) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/HiveMetaStoreClientHelper.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/HiveMetaStoreClientHelper.java index d6dfd77337..4fabab3742 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/HiveMetaStoreClientHelper.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/HiveMetaStoreClientHelper.java @@ -683,8 +683,10 @@ public class HiveMetaStoreClientHelper { case DECIMALV2: return TypeInfoFactory.decimalTypeInfo; case DATE: + case DATEV2: return TypeInfoFactory.dateTypeInfo; case DATETIME: + case DATETIMEV2: return TypeInfoFactory.timestampTypeInfo; case CHAR: return TypeInfoFactory.charTypeInfo; @@ -761,9 +763,9 @@ public class HiveMetaStoreClientHelper { case "bigint": return Type.BIGINT; case "date": - return Type.DATE; + return DateLiteral.getDefaultDateType(Type.DATE); case "timestamp": - return Type.DATETIME; + return DateLiteral.getDefaultDateType(Type.DATETIME); case "float": return Type.FLOAT; case "double": diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java index 7f01110cba..eef63d23ea 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/PrimitiveType.java @@ -17,6 +17,7 @@ package org.apache.doris.catalog; +import org.apache.doris.common.Config; import org.apache.doris.mysql.MysqlColType; import org.apache.doris.thrift.TPrimitiveType; @@ -69,6 +70,7 @@ public enum PrimitiveType { private static final int DATE_INDEX_LEN = 3; + private static final int DATEV2_INDEX_LEN = 4; private static final int DATETIME_INDEX_LEN = 8; private static final int VARCHAR_INDEX_LEN = 20; private static final int STRING_INDEX_LEN = 20; @@ -922,8 +924,9 @@ public enum PrimitiveType { public int getOlapColumnIndexSize() { switch (this) { case DATE: - case DATEV2: return DATE_INDEX_LEN; + case DATEV2: + return DATEV2_INDEX_LEN; case DATETIME: case DATETIMEV2: return DATETIME_INDEX_LEN; @@ -940,4 +943,15 @@ public enum PrimitiveType { return this.getSlotSize(); } } + + public static PrimitiveType getDatePrimitiveType(PrimitiveType type) { + switch (type) { + case DATE: + return Config.use_date_v2_by_default ? DATEV2 : DATE; + case DATETIME: + return Config.use_date_v2_by_default ? DATETIMEV2 : DATETIME; + default: + return type; + } + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java index ef04f1e58e..bcbcef619c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java @@ -63,9 +63,12 @@ public class SchemaTable extends Table { .column("INDEX_LENGTH", ScalarType.createType(PrimitiveType.BIGINT)) .column("DATA_FREE", ScalarType.createType(PrimitiveType.BIGINT)) .column("AUTO_INCREMENT", ScalarType.createType(PrimitiveType.BIGINT)) - .column("CREATE_TIME", ScalarType.createType(PrimitiveType.DATETIME)) - .column("UPDATE_TIME", ScalarType.createType(PrimitiveType.DATETIME)) - .column("CHECK_TIME", ScalarType.createType(PrimitiveType.DATETIME)) + .column("CREATE_TIME", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) + .column("UPDATE_TIME", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) + .column("CHECK_TIME", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) .column("TABLE_COLLATION", ScalarType.createVarchar(MY_CS_NAME_SIZE)) .column("CHECKSUM", ScalarType.createType(PrimitiveType.BIGINT)) .column("CREATE_OPTIONS", ScalarType.createVarchar(255)) @@ -134,8 +137,10 @@ public class SchemaTable extends Table { .column("SQL_DATA_ACCESS", ScalarType.createVarchar(NAME_CHAR_LEN)) .column("SQL_PATH", ScalarType.createVarchar(NAME_CHAR_LEN)) .column("SECURITY_TYPE", ScalarType.createVarchar(NAME_CHAR_LEN)) - .column("CREATED", ScalarType.createType(PrimitiveType.DATETIME)) - .column("LAST_ALTERED", ScalarType.createType(PrimitiveType.DATETIME)) + .column("CREATED", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) + .column("LAST_ALTERED", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) .column("SQL_MODE", ScalarType.createVarchar(NAME_CHAR_LEN)) .column("ROUTINE_COMMENT", ScalarType.createVarchar(NAME_CHAR_LEN)) .column("DEFINER", ScalarType.createVarchar(NAME_CHAR_LEN)) @@ -303,8 +308,10 @@ public class SchemaTable extends Table { .column("INDEX_LENGTH", ScalarType.createType(PrimitiveType.BIGINT)) .column("DATA_FREE", ScalarType.createType(PrimitiveType.BIGINT)) .column("CREATE_TIME", ScalarType.createType(PrimitiveType.BIGINT)) - .column("UPDATE_TIME", ScalarType.createType(PrimitiveType.DATETIME)) - .column("CHECK_TIME", ScalarType.createType(PrimitiveType.DATETIME)) + .column("UPDATE_TIME", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) + .column("CHECK_TIME", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) .column("CHECKSUM", ScalarType.createType(PrimitiveType.BIGINT)) .column("PARTITION_COMMENT", ScalarType.createStringType()) .column("NODEGROUP", ScalarType.createVarchar(256)) @@ -338,7 +345,8 @@ public class SchemaTable extends Table { .column("ACTION_REFERENCE_NEW_TABLE", ScalarType.createVarchar(64)) .column("ACTION_REFERENCE_OLD_ROW", ScalarType.createVarchar(3)) .column("ACTION_REFERENCE_NEW_ROW", ScalarType.createVarchar(3)) - .column("CREATED", ScalarType.createType(PrimitiveType.DATETIME)) + .column("CREATED", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) .column("SQL_MODE", ScalarType.createVarchar(8192)) .column("DEFINER", ScalarType.createVarchar(77)) .column("CHARACTER_SET_CLIENT", ScalarType.createVarchar(32)) @@ -355,17 +363,23 @@ public class SchemaTable extends Table { .column("EVENT_BODY", ScalarType.createVarchar(8)) .column("EVENT_DEFINITION", ScalarType.createVarchar(512)) .column("EVENT_TYPE", ScalarType.createVarchar(9)) - .column("EXECUTE_AT", ScalarType.createType(PrimitiveType.DATETIME)) + .column("EXECUTE_AT", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) .column("INTERVAL_VALUE", ScalarType.createVarchar(256)) .column("INTERVAL_FIELD", ScalarType.createVarchar(18)) .column("SQL_MODE", ScalarType.createVarchar(8192)) - .column("STARTS", ScalarType.createType(PrimitiveType.DATETIME)) - .column("ENDS", ScalarType.createType(PrimitiveType.DATETIME)) + .column("STARTS", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) + .column("ENDS", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) .column("STATUS", ScalarType.createVarchar(18)) .column("ON_COMPLETION", ScalarType.createVarchar(12)) - .column("CREATED", ScalarType.createType(PrimitiveType.DATETIME)) - .column("LAST_ALTERED", ScalarType.createType(PrimitiveType.DATETIME)) - .column("LAST_EXECUTED", ScalarType.createType(PrimitiveType.DATETIME)) + .column("CREATED", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) + .column("LAST_ALTERED", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) + .column("LAST_EXECUTED", ScalarType.createType(PrimitiveType + .getDatePrimitiveType(PrimitiveType.DATETIME))) .column("EVENT_COMMENT", ScalarType.createVarchar(64)) .column("ORIGINATOR", ScalarType.createType(PrimitiveType.INT)) .column("CHARACTER_SET_CLIENT", ScalarType.createVarchar(32)) diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java index 3a77e2381e..98cbbb83d5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Type.java @@ -20,7 +20,6 @@ package org.apache.doris.catalog; import org.apache.doris.analysis.DateLiteral; import org.apache.doris.analysis.Expr; import org.apache.doris.analysis.StringLiteral; -import org.apache.doris.common.AnalysisException; import org.apache.doris.common.DdlException; import org.apache.doris.common.Pair; import org.apache.doris.thrift.TColumnType; @@ -1312,32 +1311,27 @@ public abstract class Type { } private static Type getDateComparisonResultType(ScalarType t1, ScalarType t2) { - try { - if (t1.isDate() && t2.isDate()) { - return DateLiteral.getDefaultDateType(Type.DATE); - } else if ((t1.isDateV2() && t2.isDate()) || t1.isDate() && t2.isDateV2()) { - return Type.DATEV2; - } else if (t1.isDateV2() && t2.isDateV2()) { - return Type.DATEV2; - } else if (t1.isDatetime() && t2.isDatetime()) { - return DateLiteral.getDefaultDateType(Type.DATETIME); - } else if (t1.isDatetime() && t2.isDatetimeV2()) { - return t2; - } else if (t1.isDatetimeV2() && t2.isDatetime()) { - return t1; - } else if (t1.isDatetimeV2() && t2.isDatetimeV2()) { - return t1.decimalScale() > t2.decimalScale() ? t1 : t2; - } else if (t1.isDatetimeV2()) { - return t1; - } else if (t2.isDatetimeV2()) { - return t2; - } else { - return DateLiteral.getDefaultDateType(Type.DATETIME); - } - } catch (AnalysisException ignored) { - LOG.error("Invalid date type: {} and {}", t1, t2); + if (t1.isDate() && t2.isDate()) { + return DateLiteral.getDefaultDateType(Type.DATE); + } else if ((t1.isDateV2() && t2.isDate()) || t1.isDate() && t2.isDateV2()) { + return Type.DATEV2; + } else if (t1.isDateV2() && t2.isDateV2()) { + return Type.DATEV2; + } else if (t1.isDatetime() && t2.isDatetime()) { + return DateLiteral.getDefaultDateType(Type.DATETIME); + } else if (t1.isDatetime() && t2.isDatetimeV2()) { + return t2; + } else if (t1.isDatetimeV2() && t2.isDatetime()) { + return t1; + } else if (t1.isDatetimeV2() && t2.isDatetimeV2()) { + return t1.decimalScale() > t2.decimalScale() ? t1 : t2; + } else if (t1.isDatetimeV2()) { + return t1; + } else if (t2.isDatetimeV2()) { + return t2; + } else { + return DateLiteral.getDefaultDateType(Type.DATETIME); } - return null; } public Type getMaxResolutionType() { diff --git a/fe/fe-core/src/main/java/org/apache/doris/external/hive/util/HiveUtil.java b/fe/fe-core/src/main/java/org/apache/doris/external/hive/util/HiveUtil.java index 03d0d5ebec..57c83e6392 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/external/hive/util/HiveUtil.java +++ b/fe/fe-core/src/main/java/org/apache/doris/external/hive/util/HiveUtil.java @@ -17,6 +17,7 @@ package org.apache.doris.external.hive.util; +import org.apache.doris.analysis.DateLiteral; import org.apache.doris.catalog.ArrayType; import org.apache.doris.catalog.Column; import org.apache.doris.catalog.Type; @@ -152,9 +153,9 @@ public final class HiveUtil { case VARCHAR: return Type.VARCHAR; case DATE: - return Type.DATE; + return DateLiteral.getDefaultDateType(Type.DATE); case TIMESTAMP: - return Type.DATETIME; + return DateLiteral.getDefaultDateType(Type.DATETIME); case DECIMAL: return Type.DECIMALV2; default: diff --git a/fe/fe-core/src/main/java/org/apache/doris/external/iceberg/util/TypeToDorisType.java b/fe/fe-core/src/main/java/org/apache/doris/external/iceberg/util/TypeToDorisType.java index 87774fc40b..c2eda3779e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/external/iceberg/util/TypeToDorisType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/external/iceberg/util/TypeToDorisType.java @@ -20,7 +20,6 @@ package org.apache.doris.external.iceberg.util; import org.apache.doris.analysis.DateLiteral; import org.apache.doris.catalog.ScalarType; import org.apache.doris.catalog.Type; -import org.apache.doris.common.AnalysisException; import org.apache.iceberg.Schema; import org.apache.iceberg.types.TypeUtil; @@ -80,17 +79,9 @@ public class TypeToDorisType extends TypeUtil.SchemaVisitor { Types.DecimalType decimal = (Types.DecimalType) primitive; return ScalarType.createDecimalV2Type(decimal.precision(), decimal.scale()); case DATE: - try { - return DateLiteral.getDefaultDateType(Type.DATE); - } catch (AnalysisException e) { - return Type.DATE; - } + return DateLiteral.getDefaultDateType(Type.DATE); case TIMESTAMP: - try { - return DateLiteral.getDefaultDateType(Type.DATETIME); - } catch (AnalysisException e) { - return Type.DATETIME; - } + return DateLiteral.getDefaultDateType(Type.DATETIME); case STRING: return Type.STRING; // use varchar diff --git a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java index f95cde929e..02d0b25922 100755 --- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java +++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FEFunctions.java @@ -130,6 +130,78 @@ public class FEFunctions { return new StringLiteral(result); } + @FEFunction(name = "timediff", argTypes = { "DATETIMEV2", "DATETIMEV2" }, returnType = "TIME") + public static FloatLiteral timeDiffV2(LiteralExpr first, LiteralExpr second) throws AnalysisException { + long firstTimestamp = ((DateLiteral) first).unixTimestamp(TimeUtils.getTimeZone()); + long secondTimestamp = ((DateLiteral) second).unixTimestamp(TimeUtils.getTimeZone()); + return new FloatLiteral((double) (firstTimestamp - secondTimestamp) / 1000, + FloatLiteral.getDefaultTimeType(Type.TIME)); + } + + @FEFunction(name = "datediff", argTypes = { "DATETIMEV2", "DATETIMEV2" }, returnType = "INT") + public static IntLiteral dateDiffV2(LiteralExpr first, LiteralExpr second) throws AnalysisException { + DateLiteral firstDate = ((DateLiteral) first); + DateLiteral secondDate = ((DateLiteral) second); + // DATEDIFF function only uses the date part for calculations and ignores the time part + firstDate.castToDate(); + secondDate.castToDate(); + long datediff = (firstDate.unixTimestamp(TimeUtils.getTimeZone()) + - secondDate.unixTimestamp(TimeUtils.getTimeZone())) / 1000 / 60 / 60 / 24; + return new IntLiteral(datediff, Type.INT); + } + + @FEFunction(name = "date_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral dateAddV2(LiteralExpr date, LiteralExpr day) throws AnalysisException { + return daysAddV2(date, day); + } + + @FEFunction(name = "adddate", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral addDateV2(LiteralExpr date, LiteralExpr day) throws AnalysisException { + return daysAddV2(date, day); + } + + @FEFunction(name = "years_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral yearsAddV2(LiteralExpr date, LiteralExpr year) throws AnalysisException { + DateLiteral dateLiteral = (DateLiteral) date; + return dateLiteral.plusYears((int) year.getLongValue()); + } + + @FEFunction(name = "months_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral monthsAddV2(LiteralExpr date, LiteralExpr month) throws AnalysisException { + DateLiteral dateLiteral = (DateLiteral) date; + return dateLiteral.plusMonths((int) month.getLongValue()); + } + + @FEFunction(name = "days_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral daysAddV2(LiteralExpr date, LiteralExpr day) throws AnalysisException { + DateLiteral dateLiteral = (DateLiteral) date; + return dateLiteral.plusDays((int) day.getLongValue()); + } + + @FEFunction(name = "hours_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral hoursAddV2(LiteralExpr date, LiteralExpr hour) throws AnalysisException { + DateLiteral dateLiteral = (DateLiteral) date; + return dateLiteral.plusHours((int) hour.getLongValue()); + } + + @FEFunction(name = "minutes_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral minutesAddV2(LiteralExpr date, LiteralExpr minute) throws AnalysisException { + DateLiteral dateLiteral = (DateLiteral) date; + return dateLiteral.plusMinutes((int) minute.getLongValue()); + } + + @FEFunction(name = "seconds_add", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral secondsAddV2(LiteralExpr date, LiteralExpr second) throws AnalysisException { + DateLiteral dateLiteral = (DateLiteral) date; + return dateLiteral.plusSeconds((int) second.getLongValue()); + } + + @FEFunction(name = "date_format", argTypes = { "DATETIMEV2", "VARCHAR" }, returnType = "VARCHAR") + public static StringLiteral dateFormatV2(LiteralExpr date, StringLiteral fmtLiteral) throws AnalysisException { + String result = ((DateLiteral) date).dateFormat(fmtLiteral.getStringValue()); + return new StringLiteral(result); + } + @FEFunction(name = "str_to_date", argTypes = { "VARCHAR", "VARCHAR" }, returnType = "DATETIME") public static DateLiteral dateParse(StringLiteral date, StringLiteral fmtLiteral) throws AnalysisException { DateLiteral dateLiteral = new DateLiteral(); @@ -216,6 +288,74 @@ public class FEFunctions { return new IntLiteral(unixTime, Type.INT); } + @FEFunction(name = "date_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral dateSubV2(LiteralExpr date, LiteralExpr day) throws AnalysisException { + return dateAddV2(date, new IntLiteral(-(int) day.getLongValue())); + } + + @FEFunction(name = "years_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral yearsSubV2(LiteralExpr date, LiteralExpr year) throws AnalysisException { + return yearsAddV2(date, new IntLiteral(-(int) year.getLongValue())); + } + + @FEFunction(name = "months_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral monthsSubV2(LiteralExpr date, LiteralExpr month) throws AnalysisException { + return monthsAddV2(date, new IntLiteral(-(int) month.getLongValue())); + } + + @FEFunction(name = "days_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral daysSubV2(LiteralExpr date, LiteralExpr day) throws AnalysisException { + return daysAddV2(date, new IntLiteral(-(int) day.getLongValue())); + } + + @FEFunction(name = "hours_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral hoursSubV2(LiteralExpr date, LiteralExpr hour) throws AnalysisException { + return hoursAddV2(date, new IntLiteral(-(int) hour.getLongValue())); + } + + @FEFunction(name = "minutes_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral minutesSubV2(LiteralExpr date, LiteralExpr minute) throws AnalysisException { + return minutesAddV2(date, new IntLiteral(-(int) minute.getLongValue())); + } + + @FEFunction(name = "seconds_sub", argTypes = { "DATETIMEV2", "INT" }, returnType = "DATETIME") + public static DateLiteral secondsSubV2(LiteralExpr date, LiteralExpr second) throws AnalysisException { + return secondsAddV2(date, new IntLiteral(-(int) second.getLongValue())); + } + + @FEFunction(name = "year", argTypes = { "DATETIMEV2" }, returnType = "INT") + public static IntLiteral yearV2(LiteralExpr arg) throws AnalysisException { + return new IntLiteral(((DateLiteral) arg).getYear(), Type.INT); + } + + @FEFunction(name = "month", argTypes = { "DATETIMEV2" }, returnType = "INT") + public static IntLiteral monthV2(LiteralExpr arg) throws AnalysisException { + return new IntLiteral(((DateLiteral) arg).getMonth(), Type.INT); + } + + @FEFunction(name = "day", argTypes = { "DATETIMEV2" }, returnType = "INT") + public static IntLiteral dayV2(LiteralExpr arg) throws AnalysisException { + return new IntLiteral(((DateLiteral) arg).getDay(), Type.INT); + } + + @FEFunction(name = "unix_timestamp", argTypes = { "DATETIMEV2" }, returnType = "INT") + public static IntLiteral unixTimestampV2(LiteralExpr arg) throws AnalysisException { + long unixTime = ((DateLiteral) arg).unixTimestamp(TimeUtils.getTimeZone()) / 1000; + // date before 1970-01-01 or after 2038-01-19 03:14:07 should return 0 for unix_timestamp() function + unixTime = unixTime < 0 ? 0 : unixTime; + unixTime = unixTime > Integer.MAX_VALUE ? 0 : unixTime; + return new IntLiteral(unixTime, Type.INT); + } + + @FEFunction(name = "unix_timestamp", argTypes = { "DATEV2" }, returnType = "INT") + public static IntLiteral unixTimestamp2V2(LiteralExpr arg) throws AnalysisException { + long unixTime = ((DateLiteral) arg).unixTimestamp(TimeUtils.getTimeZone()) / 1000; + // date before 1970-01-01 or after 2038-01-19 03:14:07 should return 0 for unix_timestamp() function + unixTime = unixTime < 0 ? 0 : unixTime; + unixTime = unixTime > Integer.MAX_VALUE ? 0 : unixTime; + return new IntLiteral(unixTime, Type.INT); + } + @FEFunction(name = "from_unixtime", argTypes = { "INT" }, returnType = "VARCHAR") public static StringLiteral fromUnixTime(LiteralExpr unixTime) throws AnalysisException { // if unixTime < 0, we should return null, throw a exception and let BE process @@ -337,6 +477,70 @@ public class FEFunctions { return null; } + @FEFunction(name = "yearweek", argTypes = { "DATEV2" }, returnType = "INT") + public static IntLiteral yearWeekV2(LiteralExpr arg) throws AnalysisException { + if (arg instanceof IntLiteral) { + return (IntLiteral) arg; + } + return null; + } + + @FEFunction(name = "yearweek", argTypes = { "DATEV2", "INT" }, returnType = "INT") + public static IntLiteral yearWeekModV2(LiteralExpr arg) throws AnalysisException { + if (arg instanceof IntLiteral) { + return (IntLiteral) arg; + } + return null; + } + + @FEFunction(name = "week", argTypes = { "DATEV2" }, returnType = "INT") + public static IntLiteral weekV2(LiteralExpr arg) throws AnalysisException { + if (arg instanceof IntLiteral) { + return (IntLiteral) arg; + } + return null; + } + + @FEFunction(name = "week", argTypes = { "DATEV2", "INT" }, returnType = "INT") + public static IntLiteral weekModeV2(LiteralExpr arg) throws AnalysisException { + if (arg instanceof IntLiteral) { + return (IntLiteral) arg; + } + return null; + } + + @FEFunction(name = "hour", argTypes = {"DATETIMEV2"}, returnType = "INT") + public static IntLiteral hourV2(LiteralExpr arg) throws AnalysisException { + if (arg instanceof DateLiteral) { + return new IntLiteral(((DateLiteral) arg).getHour()); + } + return null; + } + + @FEFunction(name = "minute", argTypes = {"DATETIMEV2"}, returnType = "INT") + public static IntLiteral minuteV2(LiteralExpr arg) throws AnalysisException { + if (arg instanceof DateLiteral) { + return new IntLiteral(((DateLiteral) arg).getMinute()); + } + return null; + } + + @FEFunction(name = "second", argTypes = {"DATETIMEV2"}, returnType = "INT") + public static IntLiteral secondV2(LiteralExpr arg) throws AnalysisException { + if (arg instanceof DateLiteral) { + return new IntLiteral(((DateLiteral) arg).getSecond()); + } + return null; + } + + @FEFunction(name = "timestamp", argTypes = {"DATETIMEV2"}, returnType = "DATETIME") + public static DateLiteral timestampV2(LiteralExpr arg) throws AnalysisException { + if (arg instanceof DateLiteral) { + return (DateLiteral) arg; + } + return null; + } + /** ------------------------------------------------------------------------------ */ @@ -565,7 +769,10 @@ public class FEFunctions { @FEFunction(name = "nvl", argTypes = {"BIGINT", "BIGINT"}, returnType = "BIGINT"), @FEFunction(name = "nvl", argTypes = {"DATETIME", "DATETIME"}, returnType = "DATETIME"), @FEFunction(name = "nvl", argTypes = { "DATE", "DATETIME" }, returnType = "DATETIME"), - @FEFunction(name = "nvl", argTypes = { "DATETIME", "DATE" }, returnType = "DATETIME") + @FEFunction(name = "nvl", argTypes = { "DATETIME", "DATE" }, returnType = "DATETIME"), + @FEFunction(name = "nvl", argTypes = {"DATETIMEV2", "DATETIMEV2"}, returnType = "DATETIME"), + @FEFunction(name = "nvl", argTypes = { "DATEV2", "DATETIMEV2" }, returnType = "DATETIME"), + @FEFunction(name = "nvl", argTypes = { "DATETIMEV2", "DATEV2" }, returnType = "DATETIME") }) public static LiteralExpr nvl(LiteralExpr first, LiteralExpr second) throws AnalysisException { return first instanceof NullLiteral ? second : first; @@ -580,6 +787,8 @@ public class FEFunctions { @FEFunction(name = "array", argTypes = {"LARGEINT"}, returnType = "ARRAY"), @FEFunction(name = "array", argTypes = {"DATETIME"}, returnType = "ARRAY"), @FEFunction(name = "array", argTypes = {"DATE"}, returnType = "ARRAY"), + @FEFunction(name = "array", argTypes = {"DATETIMEV2"}, returnType = "ARRAY"), + @FEFunction(name = "array", argTypes = {"DATEV2"}, returnType = "ARRAY"), @FEFunction(name = "array", argTypes = {"FLOAT"}, returnType = "ARRAY"), @FEFunction(name = "array", argTypes = {"DOUBLE"}, returnType = "ARRAY"), @FEFunction(name = "array", argTypes = {"DECIMALV2"}, returnType = "ARRAY"), diff --git a/gensrc/proto/types.proto b/gensrc/proto/types.proto index 7655255e47..b8230372b5 100644 --- a/gensrc/proto/types.proto +++ b/gensrc/proto/types.proto @@ -100,6 +100,7 @@ message PGenericType { BYTES = 26; NOTHING = 27; DATEV2 = 28; + DATETIMEV2 = 29; UNKNOWN = 999; } required TypeId id = 2;