[feature-wip](datev2) add FE functions and fix some bugs (#10767)

This commit is contained in:
Gabriel
2022-07-11 19:25:31 +08:00
committed by GitHub
parent 5eb38467ef
commit c51badb1ae
14 changed files with 321 additions and 78 deletions

View File

@ -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.

View File

@ -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()

View File

@ -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;
}
}
}

View File

@ -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:

View File

@ -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/"

View File

@ -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()) {

View File

@ -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":

View File

@ -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;
}
}
}

View File

@ -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))

View File

@ -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() {

View File

@ -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:

View File

@ -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<Type> {
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

View File

@ -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"),