[refactor] (datetimev2) refactor FEFunctions for datev2/datetimev2 (#11296)
This commit is contained in:
@ -244,7 +244,7 @@ terminal String KW_ADD, KW_ADMIN, KW_AFTER, KW_AGGREGATE, KW_ALIAS, KW_ALL, KW_A
|
||||
KW_CANCEL, KW_CASE, KW_CAST, KW_CHAIN, KW_CHAR, KW_CHARSET, KW_CHECK, KW_CLUSTER, KW_CLUSTERS, KW_CLEAN, KW_CURRENT_TIMESTAMP,
|
||||
KW_COLLATE, KW_COLLATION, KW_COLUMN, KW_COLUMNS, KW_COMMENT, KW_COMMIT, KW_COMMITTED, KW_COMPACT,
|
||||
KW_CONFIG, KW_CONNECTION, KW_CONNECTION_ID, KW_CONSISTENT, KW_CONVERT, KW_COUNT, KW_CREATE, KW_CREATION, KW_CROSS, KW_CUBE, KW_CURRENT, KW_CURRENT_USER,
|
||||
KW_DATA, KW_DATABASE, KW_DATABASES, KW_DATE, KW_DATETIME, KW_DAY, KW_DECIMAL, KW_DECOMMISSION, KW_DEFAULT, KW_DESC, KW_DESCRIBE,
|
||||
KW_DATA, KW_DATABASE, KW_DATABASES, KW_DATE, KW_DATETIME, KW_DATEV2, KW_DATETIMEV2, KW_DAY, KW_DECIMAL, KW_DECOMMISSION, KW_DEFAULT, KW_DESC, KW_DESCRIBE,
|
||||
KW_DELETE, KW_UPDATE, KW_DIAGNOSE, KW_DISK, KW_DISTINCT, KW_DISTINCTPC, KW_DISTINCTPCSA, KW_DISTRIBUTED, KW_DISTRIBUTION, KW_DYNAMIC, KW_BUCKETS, KW_DIV, KW_DOUBLE, KW_DROP, KW_DROPP, KW_DUPLICATE,
|
||||
KW_ELSE, KW_ENABLE, KW_ENCRYPTKEY, KW_ENCRYPTKEYS, KW_END, KW_ENGINE, KW_ENGINES, KW_ENTER, KW_ERRORS, KW_EVENTS, KW_EXCEPT, KW_EXCLUDE,
|
||||
KW_EXISTS, KW_EXPORT, KW_EXTENDED, KW_EXTERNAL, KW_EXTRACT,
|
||||
@ -4688,6 +4688,12 @@ type ::=
|
||||
{: RESULT = ScalarType.createTimeV2Type(precision.intValue()); :}
|
||||
| KW_TIME
|
||||
{: RESULT = ScalarType.createTimeType(); :}
|
||||
| KW_DATEV2
|
||||
{: RESULT = ScalarType.createDateV2Type(); :}
|
||||
| KW_DATETIMEV2 LPAREN INTEGER_LITERAL:precision RPAREN
|
||||
{: RESULT = ScalarType.createDatetimeV2Type(precision.intValue()); :}
|
||||
| KW_DATETIMEV2
|
||||
{: RESULT = ScalarType.createDatetimeV2Type(0); :}
|
||||
| KW_BITMAP
|
||||
{: RESULT = Type.BITMAP; :}
|
||||
| KW_QUANTILE_STATE
|
||||
@ -4944,6 +4950,8 @@ non_pred_expr ::=
|
||||
{: RESULT = e; :}
|
||||
| KW_DATE STRING_LITERAL:l
|
||||
{: RESULT = new StringLiteral(l); :}
|
||||
| KW_DATEV2 STRING_LITERAL:l
|
||||
{: RESULT = new StringLiteral(l); :}
|
||||
| KW_TIMESTAMP STRING_LITERAL:l
|
||||
{: RESULT = new StringLiteral(l); :}
|
||||
| KW_EXTRACT LPAREN function_name:fn_name KW_FROM func_arg_list:exprs RPAREN
|
||||
@ -5650,6 +5658,10 @@ keyword ::=
|
||||
{: RESULT = id; :}
|
||||
| KW_DATETIME:id
|
||||
{: RESULT = id; :}
|
||||
| KW_DATEV2:id
|
||||
{: RESULT = id; :}
|
||||
| KW_DATETIMEV2:id
|
||||
{: RESULT = id; :}
|
||||
| KW_DECIMAL:id
|
||||
{: RESULT = id; :}
|
||||
| KW_DIAGNOSE:id
|
||||
|
||||
@ -26,6 +26,7 @@ import org.apache.doris.catalog.Env;
|
||||
import org.apache.doris.catalog.OlapTable;
|
||||
import org.apache.doris.catalog.OlapTable.OlapTableState;
|
||||
import org.apache.doris.catalog.Partition.PartitionState;
|
||||
import org.apache.doris.catalog.ScalarType;
|
||||
import org.apache.doris.catalog.Table;
|
||||
import org.apache.doris.catalog.TableIf;
|
||||
import org.apache.doris.catalog.TableIf.TableType;
|
||||
@ -1835,7 +1836,7 @@ public class Analyzer {
|
||||
}
|
||||
if (compatibleType.equals(Type.VARCHAR)) {
|
||||
if (exprs.get(0).getType().isDateType()) {
|
||||
compatibleType = DateLiteral.getDefaultDateType(Type.DATETIME);
|
||||
compatibleType = ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
}
|
||||
}
|
||||
// Add implicit casts if necessary.
|
||||
|
||||
@ -342,12 +342,12 @@ public class ColumnDef {
|
||||
break;
|
||||
case DATE:
|
||||
case DATEV2:
|
||||
new DateLiteral(defaultValue, DateLiteral.getDefaultDateType(type));
|
||||
new DateLiteral(defaultValue, ScalarType.getDefaultDateType(type));
|
||||
break;
|
||||
case DATETIME:
|
||||
case DATETIMEV2:
|
||||
if (defaultValueExprDef == null) {
|
||||
new DateLiteral(defaultValue, DateLiteral.getDefaultDateType(type));
|
||||
new DateLiteral(defaultValue, ScalarType.getDefaultDateType(type));
|
||||
} else {
|
||||
if (defaultValueExprDef.getExprName().equals(DefaultValue.NOW)) {
|
||||
break;
|
||||
|
||||
@ -260,7 +260,7 @@ public class DateLiteral extends LiteralExpr {
|
||||
this.year = year;
|
||||
this.month = month;
|
||||
this.day = day;
|
||||
this.type = DateLiteral.getDefaultDateType(Type.DATE);
|
||||
this.type = ScalarType.getDefaultDateType(Type.DATE);
|
||||
}
|
||||
|
||||
public DateLiteral(long year, long month, long day, Type type) {
|
||||
@ -279,7 +279,7 @@ public class DateLiteral extends LiteralExpr {
|
||||
this.year = year;
|
||||
this.month = month;
|
||||
this.day = day;
|
||||
this.type = DateLiteral.getDefaultDateType(Type.DATETIME);
|
||||
this.type = ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
}
|
||||
|
||||
public DateLiteral(long year, long month, long day, long hour, long minute, long second, long microsecond) {
|
||||
@ -606,7 +606,7 @@ public class DateLiteral extends LiteralExpr {
|
||||
}
|
||||
|
||||
public void castToDate() {
|
||||
if (Config.use_date_v2_by_default) {
|
||||
if (Config.enable_date_conversion) {
|
||||
this.type = Type.DATEV2;
|
||||
} else {
|
||||
this.type = Type.DATE;
|
||||
@ -669,24 +669,6 @@ public class DateLiteral extends LiteralExpr {
|
||||
this.type = Type.DATETIME;
|
||||
}
|
||||
|
||||
private void fromPackedDatetimeV2(long packedTime) {
|
||||
microsecond = (packedTime % (1L << 24));
|
||||
long ymdhms = (packedTime >> 24);
|
||||
long ymd = ymdhms >> 17;
|
||||
day = ymd % (1 << 5);
|
||||
long ym = ymd >> 5;
|
||||
month = ym % (1 << 4);
|
||||
year = ym >> 4;
|
||||
|
||||
long hms = ymdhms % (1 << 17);
|
||||
second = hms % (1 << 6);
|
||||
minute = (hms >> 6) % (1 << 6);
|
||||
hour = (hms >> 12);
|
||||
// set default date literal type to DATETIME
|
||||
// date literal read from meta will set type by flag bit;
|
||||
this.type = Type.DATETIMEV2;
|
||||
}
|
||||
|
||||
public void readFields(DataInput in) throws IOException {
|
||||
super.readFields(in);
|
||||
short dateLiteralType = in.readShort();
|
||||
@ -696,10 +678,8 @@ public class DateLiteral extends LiteralExpr {
|
||||
} else if (dateLiteralType == DateLiteralType.DATE.value()) {
|
||||
this.type = Type.DATE;
|
||||
} else if (dateLiteralType == DateLiteralType.DATETIMEV2.value()) {
|
||||
fromPackedDatetime(in.readLong());
|
||||
this.type = ScalarType.createDatetimeV2Type(in.readInt());
|
||||
} else if (dateLiteralType == DateLiteralType.DATEV2.value()) {
|
||||
fromPackedDatetime(in.readLong());
|
||||
this.type = Type.DATEV2;
|
||||
} else {
|
||||
throw new IOException("Error date literal type : " + type);
|
||||
@ -1273,9 +1253,9 @@ public class DateLiteral extends LiteralExpr {
|
||||
if (microSecondPartUsed) {
|
||||
this.type = Type.DATETIMEV2;
|
||||
} else if (timePartUsed) {
|
||||
this.type = getDefaultDateType(Type.DATETIME);
|
||||
this.type = ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
} else {
|
||||
this.type = getDefaultDateType(Type.DATE);
|
||||
this.type = ScalarType.getDefaultDateType(Type.DATE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1531,34 +1511,13 @@ public class DateLiteral extends LiteralExpr {
|
||||
microsecond = dateVal[6];
|
||||
|
||||
if (numField == 3) {
|
||||
type = getDefaultDateType(Type.DATE);
|
||||
type = ScalarType.getDefaultDateType(Type.DATE);
|
||||
} else {
|
||||
type = getDefaultDateType(Type.DATETIME);
|
||||
type = ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
}
|
||||
|
||||
if (checkRange() || checkDate()) {
|
||||
throw new AnalysisException("Datetime value is out of range: " + dateStr);
|
||||
}
|
||||
}
|
||||
|
||||
public static Type getDefaultDateType(Type type) {
|
||||
switch (type.getPrimitiveType()) {
|
||||
case DATE:
|
||||
if (Config.use_date_v2_by_default) {
|
||||
return Type.DATEV2;
|
||||
} else {
|
||||
return Type.DATE;
|
||||
}
|
||||
case DATETIME:
|
||||
if (Config.use_date_v2_by_default) {
|
||||
return Type.DATETIMEV2;
|
||||
} else {
|
||||
return Type.DATETIME;
|
||||
}
|
||||
case DATEV2:
|
||||
case DATETIMEV2:
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,17 +116,31 @@ public enum ExpressionFunctions {
|
||||
return null;
|
||||
}
|
||||
for (FEFunctionInvoker invoker : functionInvokers) {
|
||||
if (!invoker.getSignature().returnType.equals(signature.getReturnType())) {
|
||||
// Make functions for date/datetime applicable to datev2/datetimev2
|
||||
if (!(invoker.getSignature().returnType.isDate() && signature.getReturnType().isDateV2())
|
||||
&& !(invoker.getSignature().returnType.isDatetime() && signature.getReturnType().isDatetimeV2())
|
||||
&& !invoker.getSignature().returnType.equals(signature.getReturnType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Type[] argTypes1 = invoker.getSignature().getArgTypes();
|
||||
Type[] argTypes2 = signature.getArgTypes();
|
||||
|
||||
if (!Arrays.equals(argTypes1, argTypes2)) {
|
||||
if (argTypes1.length != argTypes2.length) {
|
||||
continue;
|
||||
}
|
||||
return invoker;
|
||||
boolean match = true;
|
||||
for (int i = 0; i < argTypes1.length; i++) {
|
||||
if (!(argTypes1[i].isDate() && argTypes2[i].isDateV2())
|
||||
&& !(argTypes1[i].isDatetime() && argTypes2[i].isDatetimeV2())
|
||||
&& !argTypes1[i].equals(argTypes2[i])) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
return invoker;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@ public class FloatLiteral extends LiteralExpr {
|
||||
public static Type getDefaultTimeType(Type type) throws AnalysisException {
|
||||
switch (type.getPrimitiveType()) {
|
||||
case TIME:
|
||||
if (Config.use_date_v2_by_default) {
|
||||
if (Config.enable_date_conversion) {
|
||||
return Type.TIMEV2;
|
||||
} else {
|
||||
return Type.TIME;
|
||||
|
||||
@ -1063,9 +1063,9 @@ public class FunctionCallExpr extends Expr {
|
||||
for (int i = 0; i < argTypes.length - orderByElements.size(); ++i) {
|
||||
// For varargs, we must compare with the last type in callArgs.argTypes.
|
||||
int ix = Math.min(args.length - 1, i);
|
||||
if (!argTypes[i].matchesType(args[ix]) && Config.use_date_v2_by_default
|
||||
if (!argTypes[i].matchesType(args[ix]) && Config.enable_date_conversion
|
||||
&& !argTypes[i].isDateType() && (args[ix].isDate() || args[ix].isDatetime())) {
|
||||
uncheckedCastChild(DateLiteral.getDefaultDateType(args[ix]), i);
|
||||
uncheckedCastChild(ScalarType.getDefaultDateType(args[ix]), i);
|
||||
} else if (!argTypes[i].matchesType(args[ix]) && !(
|
||||
argTypes[i].isDateType() && args[ix].isDateType())) {
|
||||
uncheckedCastChild(args[ix], i);
|
||||
@ -1103,19 +1103,19 @@ public class FunctionCallExpr extends Expr {
|
||||
Expr child1Result = getChild(1).getResultValue();
|
||||
if (child1Result instanceof StringLiteral) {
|
||||
if (DateLiteral.hasTimePart(((StringLiteral) child1Result).getStringValue())) {
|
||||
this.type = DateLiteral.getDefaultDateType(Type.DATETIME);
|
||||
this.type = ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
} else {
|
||||
this.type = DateLiteral.getDefaultDateType(Type.DATE);
|
||||
this.type = ScalarType.getDefaultDateType(Type.DATE);
|
||||
}
|
||||
} else {
|
||||
this.type = DateLiteral.getDefaultDateType(Type.DATETIME);
|
||||
this.type = ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
}
|
||||
} else {
|
||||
this.type = fn.getReturnType();
|
||||
}
|
||||
|
||||
Type[] childTypes = collectChildReturnTypes();
|
||||
if ((this.type.isDate() || this.type.isDatetime()) && Config.use_date_v2_by_default
|
||||
if ((this.type.isDate() || this.type.isDatetime()) && Config.enable_date_conversion
|
||||
&& fn.getArgs().length == childTypes.length) {
|
||||
boolean implicitCastToDate = false;
|
||||
for (int i = 0; i < fn.getArgs().length; i++) {
|
||||
@ -1125,8 +1125,8 @@ public class FunctionCallExpr extends Expr {
|
||||
}
|
||||
}
|
||||
if (implicitCastToDate) {
|
||||
this.type = DateLiteral.getDefaultDateType(fn.getReturnType());
|
||||
fn.setReturnType(DateLiteral.getDefaultDateType(fn.getReturnType()));
|
||||
this.type = ScalarType.getDefaultDateType(fn.getReturnType());
|
||||
fn.setReturnType(ScalarType.getDefaultDateType(fn.getReturnType()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -121,7 +121,7 @@ public class ShowAlterStmt extends ShowStmt {
|
||||
+ "\"2019-12-02|2019-12-02 14:54:00\"");
|
||||
}
|
||||
subExpr.setChild(1, (subExpr.getChild(1)).castTo(
|
||||
DateLiteral.getDefaultDateType(Type.DATETIME)));
|
||||
ScalarType.getDefaultDateType(Type.DATETIME)));
|
||||
} else {
|
||||
throw new AnalysisException("The columns of TableName/CreateTime/FinishTime/State are supported.");
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ public class ShowPartitionsStmt extends ShowStmt {
|
||||
+ "\"2019-12-22|2019-12-22 22:22:00\"");
|
||||
}
|
||||
subExpr.setChild(1, (subExpr.getChild(1)).castTo(
|
||||
Objects.requireNonNull(DateLiteral.getDefaultDateType(Type.DATETIME))));
|
||||
Objects.requireNonNull(ScalarType.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/"
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
package org.apache.doris.analysis;
|
||||
|
||||
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.DdlException;
|
||||
@ -175,11 +176,14 @@ public class StringLiteral extends LiteralExpr {
|
||||
public LiteralExpr convertToDate(Type targetType) throws AnalysisException {
|
||||
LiteralExpr newLiteral = null;
|
||||
try {
|
||||
newLiteral = new DateLiteral(value, DateLiteral.getDefaultDateType(targetType));
|
||||
newLiteral = new DateLiteral(value, ScalarType.getDefaultDateType(targetType));
|
||||
} catch (AnalysisException e) {
|
||||
if (targetType.isScalarType(PrimitiveType.DATETIME)) {
|
||||
newLiteral = new DateLiteral(value, DateLiteral.getDefaultDateType(Type.DATE));
|
||||
newLiteral.setType(DateLiteral.getDefaultDateType(Type.DATETIME));
|
||||
newLiteral = new DateLiteral(value, ScalarType.getDefaultDateType(Type.DATE));
|
||||
newLiteral.setType(ScalarType.getDefaultDateType(Type.DATETIME));
|
||||
} else if (targetType.isScalarType(PrimitiveType.DATETIMEV2)) {
|
||||
newLiteral = new DateLiteral(value, Type.DATEV2);
|
||||
newLiteral.setType(targetType);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ public class TimestampArithmeticExpr extends Expr {
|
||||
if (t1 == PrimitiveType.DATEV2) {
|
||||
return Type.DATEV2;
|
||||
}
|
||||
if (Config.use_date_v2_by_default
|
||||
if (Config.enable_date_conversion
|
||||
&& PrimitiveType.isImplicitCast(t1, PrimitiveType.DATETIMEV2)) {
|
||||
return Type.DATETIMEV2;
|
||||
}
|
||||
@ -141,7 +141,7 @@ public class TimestampArithmeticExpr extends Expr {
|
||||
}
|
||||
Type dateType = fixType();
|
||||
if (dateType.isDate() && timeUnit.isDateTime()) {
|
||||
dateType = DateLiteral.getDefaultDateType(Type.DATETIME);
|
||||
dateType = ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
}
|
||||
// The first child must return a timestamp or null.
|
||||
if (!getChild(0).getType().isDateType() && !getChild(0).getType().isNull()) {
|
||||
|
||||
@ -767,9 +767,9 @@ public class HiveMetaStoreClientHelper {
|
||||
case "bigint":
|
||||
return Type.BIGINT;
|
||||
case "date":
|
||||
return DateLiteral.getDefaultDateType(Type.DATE);
|
||||
return ScalarType.getDefaultDateType(Type.DATE);
|
||||
case "timestamp":
|
||||
return DateLiteral.getDefaultDateType(Type.DATETIME);
|
||||
return ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
case "float":
|
||||
return Type.FLOAT;
|
||||
case "double":
|
||||
|
||||
@ -1156,9 +1156,9 @@ public enum PrimitiveType {
|
||||
public static PrimitiveType getDatePrimitiveType(PrimitiveType type) {
|
||||
switch (type) {
|
||||
case DATE:
|
||||
return Config.use_date_v2_by_default ? DATEV2 : DATE;
|
||||
return Config.enable_date_conversion ? DATEV2 : DATE;
|
||||
case DATETIME:
|
||||
return Config.use_date_v2_by_default ? DATETIMEV2 : DATETIME;
|
||||
return Config.enable_date_conversion ? DATETIMEV2 : DATETIME;
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -351,7 +351,7 @@ public class ScalarType extends Type {
|
||||
|
||||
@SuppressWarnings("checkstyle:MissingJavadocMethod")
|
||||
public static ScalarType createDatetimeType() {
|
||||
if (!Config.use_date_v2_by_default) {
|
||||
if (!Config.enable_date_conversion) {
|
||||
return new ScalarType(PrimitiveType.DATETIME);
|
||||
}
|
||||
ScalarType type = new ScalarType(PrimitiveType.DATETIMEV2);
|
||||
@ -362,7 +362,7 @@ public class ScalarType extends Type {
|
||||
|
||||
@SuppressWarnings("checkstyle:MissingJavadocMethod")
|
||||
public static ScalarType createDateType() {
|
||||
if (Config.use_date_v2_by_default) {
|
||||
if (Config.enable_date_conversion) {
|
||||
return new ScalarType(PrimitiveType.DATEV2);
|
||||
} else {
|
||||
return new ScalarType(PrimitiveType.DATE);
|
||||
@ -371,7 +371,7 @@ public class ScalarType extends Type {
|
||||
|
||||
@SuppressWarnings("checkstyle:MissingJavadocMethod")
|
||||
public static ScalarType createTimeType() {
|
||||
if (!Config.use_date_v2_by_default) {
|
||||
if (!Config.enable_date_conversion) {
|
||||
return new ScalarType(PrimitiveType.TIME);
|
||||
}
|
||||
ScalarType type = new ScalarType(PrimitiveType.TIMEV2);
|
||||
@ -380,6 +380,31 @@ public class ScalarType extends Type {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static ScalarType createDateV2Type() {
|
||||
return new ScalarType(PrimitiveType.DATEV2);
|
||||
}
|
||||
|
||||
public static Type getDefaultDateType(Type type) {
|
||||
switch (type.getPrimitiveType()) {
|
||||
case DATE:
|
||||
if (Config.enable_date_conversion) {
|
||||
return Type.DATEV2;
|
||||
} else {
|
||||
return Type.DATE;
|
||||
}
|
||||
case DATETIME:
|
||||
if (Config.enable_date_conversion) {
|
||||
return Type.DATETIMEV2;
|
||||
} else {
|
||||
return Type.DATETIME;
|
||||
}
|
||||
case DATEV2:
|
||||
case DATETIMEV2:
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create a wider decimal type.
|
||||
*/
|
||||
|
||||
@ -17,7 +17,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.DdlException;
|
||||
@ -1529,13 +1528,13 @@ public abstract class Type {
|
||||
|
||||
private static Type getDateComparisonResultType(ScalarType t1, ScalarType t2) {
|
||||
if (t1.isDate() && t2.isDate()) {
|
||||
return DateLiteral.getDefaultDateType(Type.DATE);
|
||||
return ScalarType.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);
|
||||
return ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
} else if (t1.isDatetime() && t2.isDatetimeV2()) {
|
||||
return t2;
|
||||
} else if (t1.isDatetimeV2() && t2.isDatetime()) {
|
||||
@ -1547,7 +1546,7 @@ public abstract class Type {
|
||||
} else if (t2.isDatetimeV2()) {
|
||||
return t2;
|
||||
} else {
|
||||
return DateLiteral.getDefaultDateType(Type.DATETIME);
|
||||
return ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1688,8 +1688,11 @@ public class Config extends ConfigBase {
|
||||
@ConfField(mutable = false, masterOnly = true)
|
||||
public static boolean be_rebalancer_fuzzy_test = false;
|
||||
|
||||
/**
|
||||
* If set to TRUE, FE will convert date/datetime to datev2/datetimev2(0) automatically.
|
||||
*/
|
||||
@ConfField(mutable = true, masterOnly = true)
|
||||
public static boolean use_date_v2_by_default = false;
|
||||
public static boolean enable_date_conversion = false;
|
||||
|
||||
@ConfField(mutable = false, masterOnly = true)
|
||||
public static boolean enable_multi_tags = false;
|
||||
|
||||
@ -669,9 +669,10 @@ public class DynamicPartitionUtil {
|
||||
}
|
||||
|
||||
public static String getPartitionFormat(Column column) throws DdlException {
|
||||
if (column.getDataType().equals(PrimitiveType.DATE)) {
|
||||
if (column.getDataType().equals(PrimitiveType.DATE) || column.getDataType().equals(PrimitiveType.DATEV2)) {
|
||||
return DATE_FORMAT;
|
||||
} else if (column.getDataType().equals(PrimitiveType.DATETIME)) {
|
||||
} else if (column.getDataType().equals(PrimitiveType.DATETIME)
|
||||
|| column.getDataType().equals(PrimitiveType.DATETIMEV2)) {
|
||||
return DATETIME_FORMAT;
|
||||
} else if (PrimitiveType.getIntegerTypes().contains(column.getDataType())) {
|
||||
// TODO: For Integer Type, only support format it as yyyyMMdd now
|
||||
|
||||
@ -158,12 +158,12 @@ public class PropertyAnalyzer {
|
||||
throw new AnalysisException("Invalid storage medium: " + value);
|
||||
}
|
||||
} else if (key.equalsIgnoreCase(PROPERTIES_STORAGE_COOLDOWN_TIME)) {
|
||||
DateLiteral dateLiteral = new DateLiteral(value, DateLiteral.getDefaultDateType(Type.DATETIME));
|
||||
DateLiteral dateLiteral = new DateLiteral(value, ScalarType.getDefaultDateType(Type.DATETIME));
|
||||
cooldownTimeStamp = dateLiteral.unixTimestamp(TimeUtils.getTimeZone());
|
||||
} else if (key.equalsIgnoreCase(PROPERTIES_REMOTE_STORAGE_POLICY)) {
|
||||
remoteStoragePolicy = value;
|
||||
} else if (key.equalsIgnoreCase(PROPERTIES_DATA_BASE_TIME)) {
|
||||
DateLiteral dateLiteral = new DateLiteral(value, DateLiteral.getDefaultDateType(Type.DATETIME));
|
||||
DateLiteral dateLiteral = new DateLiteral(value, ScalarType.getDefaultDateType(Type.DATETIME));
|
||||
dataBaseTimeMs = dateLiteral.unixTimestamp(TimeUtils.getTimeZone());
|
||||
} else if (!hasStoragePolicy && key.equalsIgnoreCase(PROPERTIES_STORAGE_POLICY)) {
|
||||
if (!Strings.isNullOrEmpty(value)) {
|
||||
|
||||
@ -17,9 +17,9 @@
|
||||
|
||||
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.ScalarType;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.Config;
|
||||
@ -154,9 +154,9 @@ public final class HiveUtil {
|
||||
case VARCHAR:
|
||||
return Type.VARCHAR;
|
||||
case DATE:
|
||||
return DateLiteral.getDefaultDateType(Type.DATE);
|
||||
return ScalarType.getDefaultDateType(Type.DATE);
|
||||
case TIMESTAMP:
|
||||
return DateLiteral.getDefaultDateType(Type.DATETIME);
|
||||
return ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
case DECIMAL:
|
||||
return Config.enable_decimalv3 ? Type.DECIMAL128 : Type.DECIMALV2;
|
||||
default:
|
||||
|
||||
@ -17,7 +17,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;
|
||||
|
||||
@ -79,9 +78,9 @@ public class TypeToDorisType extends TypeUtil.SchemaVisitor<Type> {
|
||||
Types.DecimalType decimal = (Types.DecimalType) primitive;
|
||||
return ScalarType.createDecimalType(decimal.precision(), decimal.scale());
|
||||
case DATE:
|
||||
return DateLiteral.getDefaultDateType(Type.DATE);
|
||||
return ScalarType.getDefaultDateType(Type.DATE);
|
||||
case TIMESTAMP:
|
||||
return DateLiteral.getDefaultDateType(Type.DATETIME);
|
||||
return ScalarType.getDefaultDateType(Type.DATETIME);
|
||||
case STRING:
|
||||
return Type.STRING;
|
||||
// use varchar
|
||||
|
||||
@ -32,6 +32,7 @@ import org.apache.doris.catalog.PartitionItem;
|
||||
import org.apache.doris.catalog.PartitionKey;
|
||||
import org.apache.doris.catalog.RangePartitionInfo;
|
||||
import org.apache.doris.catalog.RangePartitionItem;
|
||||
import org.apache.doris.catalog.ScalarType;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.Config;
|
||||
@ -459,7 +460,7 @@ public class PartitionRange {
|
||||
LiteralExpr newLiteral;
|
||||
if (key.keyType == KeyType.DATE) {
|
||||
try {
|
||||
newLiteral = new DateLiteral(key.toString(), DateLiteral.getDefaultDateType(Type.DATE));
|
||||
newLiteral = new DateLiteral(key.toString(), ScalarType.getDefaultDateType(Type.DATE));
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Date's format is error {},{}", key.toString(), e);
|
||||
continue;
|
||||
|
||||
@ -26,6 +26,7 @@ import org.apache.doris.analysis.LargeIntLiteral;
|
||||
import org.apache.doris.analysis.LiteralExpr;
|
||||
import org.apache.doris.analysis.NullLiteral;
|
||||
import org.apache.doris.analysis.StringLiteral;
|
||||
import org.apache.doris.catalog.ScalarType;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.InvalidFormatException;
|
||||
@ -129,84 +130,12 @@ 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();
|
||||
try {
|
||||
dateLiteral.fromDateFormatStr(fmtLiteral.getStringValue(), date.getStringValue(), false);
|
||||
dateLiteral.setType(DateLiteral.getDefaultDateType(dateLiteral.getType()));
|
||||
dateLiteral.setType(ScalarType.getDefaultDateType(dateLiteral.getType()));
|
||||
return dateLiteral;
|
||||
} catch (InvalidFormatException e) {
|
||||
e.printStackTrace();
|
||||
@ -287,74 +216,6 @@ 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
|
||||
@ -362,7 +223,7 @@ public class FEFunctions {
|
||||
throw new AnalysisException("unixtime should larger than zero");
|
||||
}
|
||||
DateLiteral dl = new DateLiteral(unixTime.getLongValue() * 1000, TimeUtils.getTimeZone(),
|
||||
DateLiteral.getDefaultDateType(Type.DATETIME));
|
||||
ScalarType.getDefaultDateType(Type.DATETIME));
|
||||
return new StringLiteral(dl.getStringValue());
|
||||
}
|
||||
|
||||
@ -373,14 +234,14 @@ public class FEFunctions {
|
||||
throw new AnalysisException("unixtime should larger than zero");
|
||||
}
|
||||
DateLiteral dl = new DateLiteral(unixTime.getLongValue() * 1000, TimeUtils.getTimeZone(),
|
||||
DateLiteral.getDefaultDateType(Type.DATETIME));
|
||||
ScalarType.getDefaultDateType(Type.DATETIME));
|
||||
return new StringLiteral(dl.dateFormat(fmtLiteral.getStringValue()));
|
||||
}
|
||||
|
||||
@FEFunction(name = "now", argTypes = {}, returnType = "DATETIME")
|
||||
public static DateLiteral now() throws AnalysisException {
|
||||
return new DateLiteral(LocalDateTime.now(TimeUtils.getTimeZone().toZoneId()),
|
||||
DateLiteral.getDefaultDateType(Type.DATETIME));
|
||||
ScalarType.getDefaultDateType(Type.DATETIME));
|
||||
}
|
||||
|
||||
@FEFunction(name = "current_timestamp", argTypes = {}, returnType = "DATETIME")
|
||||
@ -391,7 +252,7 @@ public class FEFunctions {
|
||||
@FEFunction(name = "curdate", argTypes = {}, returnType = "DATE")
|
||||
public static DateLiteral curDate() {
|
||||
return new DateLiteral(LocalDateTime.now(TimeUtils.getTimeZone().toZoneId()),
|
||||
DateLiteral.getDefaultDateType(Type.DATE));
|
||||
ScalarType.getDefaultDateType(Type.DATE));
|
||||
}
|
||||
|
||||
@FEFunction(name = "curtime", argTypes = {}, returnType = "TIME")
|
||||
@ -409,7 +270,7 @@ public class FEFunctions {
|
||||
@FEFunction(name = "utc_timestamp", argTypes = {}, returnType = "DATETIME")
|
||||
public static DateLiteral utcTimestamp() {
|
||||
return new DateLiteral(LocalDateTime.now(TimeUtils.getOrSystemTimeZone("+00:00").toZoneId()),
|
||||
DateLiteral.getDefaultDateType(Type.DATETIME));
|
||||
ScalarType.getDefaultDateType(Type.DATETIME));
|
||||
}
|
||||
|
||||
@FEFunction(name = "yearweek", argTypes = { "DATE" }, returnType = "INT")
|
||||
@ -476,70 +337,6 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
@ -778,10 +575,7 @@ public class FEFunctions {
|
||||
@FEFunction(name = "ifnull", argTypes = {"BIGINT", "BIGINT"}, returnType = "BIGINT"),
|
||||
@FEFunction(name = "ifnull", argTypes = {"DATETIME", "DATETIME"}, returnType = "DATETIME"),
|
||||
@FEFunction(name = "ifnull", argTypes = { "DATE", "DATETIME" }, returnType = "DATETIME"),
|
||||
@FEFunction(name = "ifnull", argTypes = { "DATETIME", "DATE" }, returnType = "DATETIME"),
|
||||
@FEFunction(name = "ifnull", argTypes = {"DATETIMEV2", "DATETIMEV2"}, returnType = "DATETIME"),
|
||||
@FEFunction(name = "ifnull", argTypes = { "DATEV2", "DATETIMEV2" }, returnType = "DATETIME"),
|
||||
@FEFunction(name = "ifnull", argTypes = { "DATETIMEV2", "DATEV2" }, returnType = "DATETIME")
|
||||
@FEFunction(name = "ifnull", argTypes = { "DATETIME", "DATE" }, returnType = "DATETIME")
|
||||
})
|
||||
public static LiteralExpr ifNull(LiteralExpr first, LiteralExpr second) throws AnalysisException {
|
||||
return first instanceof NullLiteral ? second : first;
|
||||
@ -795,10 +589,7 @@ 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 = {"DATETIMEV2", "DATETIMEV2"}, returnType = "DATETIME"),
|
||||
@FEFunction(name = "nvl", argTypes = { "DATEV2", "DATETIMEV2" }, returnType = "DATETIME"),
|
||||
@FEFunction(name = "nvl", argTypes = { "DATETIMEV2", "DATEV2" }, returnType = "DATETIME")
|
||||
@FEFunction(name = "nvl", argTypes = { "DATETIME", "DATE" }, returnType = "DATETIME")
|
||||
})
|
||||
public static LiteralExpr nvl(LiteralExpr first, LiteralExpr second) throws AnalysisException {
|
||||
return first instanceof NullLiteral ? second : first;
|
||||
@ -813,8 +604,6 @@ 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"),
|
||||
|
||||
@ -24,6 +24,7 @@ import org.apache.doris.analysis.DateLiteral;
|
||||
import org.apache.doris.analysis.Expr;
|
||||
import org.apache.doris.analysis.LiteralExpr;
|
||||
import org.apache.doris.analysis.NullLiteral;
|
||||
import org.apache.doris.catalog.ScalarType;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
|
||||
/**
|
||||
@ -63,7 +64,7 @@ public class RewriteDateLiteralRule implements ExprRewriteRule {
|
||||
String dateStr = childExpr.getStringValue();
|
||||
DateLiteral dateLiteral = new DateLiteral();
|
||||
dateLiteral.fromDateStr(dateStr);
|
||||
dateLiteral.setType(DateLiteral.getDefaultDateType(dateLiteral.getType()));
|
||||
dateLiteral.setType(ScalarType.getDefaultDateType(dateLiteral.getType()));
|
||||
expr.setChild(1, dateLiteral);
|
||||
} catch (AnalysisException e) {
|
||||
if (clauseType == ExprRewriter.ClauseType.OTHER_CLAUSE) {
|
||||
|
||||
@ -160,6 +160,8 @@ import org.apache.doris.qe.SqlModeHelper;
|
||||
keywordMap.put("databases", new Integer(SqlParserSymbols.KW_DATABASES));
|
||||
keywordMap.put("date", new Integer(SqlParserSymbols.KW_DATE));
|
||||
keywordMap.put("datetime", new Integer(SqlParserSymbols.KW_DATETIME));
|
||||
keywordMap.put("datev2", new Integer(SqlParserSymbols.KW_DATEV2));
|
||||
keywordMap.put("datetimev2", new Integer(SqlParserSymbols.KW_DATETIMEV2));
|
||||
keywordMap.put("time", new Integer(SqlParserSymbols.KW_TIME));
|
||||
keywordMap.put("day", new Integer(SqlParserSymbols.KW_DAY));
|
||||
keywordMap.put("decimal", new Integer(SqlParserSymbols.KW_DECIMAL));
|
||||
|
||||
@ -96,7 +96,7 @@ public class ExprTest {
|
||||
// uncheckedCastTo should return new object
|
||||
|
||||
// date
|
||||
DateLiteral dateLiteral = new DateLiteral(2020, 4, 5, 12, 0, 5);
|
||||
DateLiteral dateLiteral = new DateLiteral(2020, 4, 5, 12, 0, 5, Type.DATETIME);
|
||||
Assert.assertTrue(dateLiteral.getType().equals(Type.DATETIME));
|
||||
DateLiteral castLiteral = (DateLiteral) dateLiteral.uncheckedCastTo(Type.DATE);
|
||||
Assert.assertFalse(dateLiteral == castLiteral);
|
||||
@ -111,7 +111,7 @@ public class ExprTest {
|
||||
Assert.assertEquals(0, dateLiteral.getMinute());
|
||||
Assert.assertEquals(5, dateLiteral.getSecond());
|
||||
|
||||
DateLiteral dateLiteral2 = new DateLiteral(2020, 4, 5);
|
||||
DateLiteral dateLiteral2 = new DateLiteral(2020, 4, 5, Type.DATE);
|
||||
Assert.assertTrue(dateLiteral2.getType().equals(Type.DATE));
|
||||
castLiteral = (DateLiteral) dateLiteral2.uncheckedCastTo(Type.DATETIME);
|
||||
Assert.assertFalse(dateLiteral2 == castLiteral);
|
||||
|
||||
@ -34,6 +34,7 @@ import org.apache.doris.catalog.MaterializedIndex.IndexExtState;
|
||||
import org.apache.doris.catalog.OlapTable;
|
||||
import org.apache.doris.catalog.Partition;
|
||||
import org.apache.doris.catalog.Replica;
|
||||
import org.apache.doris.catalog.ScalarType;
|
||||
import org.apache.doris.catalog.Tablet;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
@ -682,7 +683,7 @@ public class QueryPlanTest extends TestWithFeService {
|
||||
String castSql = "select * from test.baseall where k11 < cast('2020-03-26' as date)";
|
||||
SelectStmt selectStmt = (SelectStmt) parseAndAnalyzeStmt(castSql);
|
||||
Expr rightExpr = selectStmt.getWhereClause().getChildren().get(1);
|
||||
Assert.assertTrue(rightExpr.getType().equals(Type.DATETIME));
|
||||
Assert.assertTrue(rightExpr.getType().equals(ScalarType.getDefaultDateType(Type.DATETIME)));
|
||||
|
||||
String castSql2 = "select str_to_date('11/09/2011', '%m/%d/%Y');";
|
||||
String explainString = getSQLPlanOrErrorMsg("explain " + castSql2);
|
||||
@ -1740,7 +1741,11 @@ public class QueryPlanTest extends TestWithFeService {
|
||||
//valid date contains micro second
|
||||
sql = "select day from tbl_int_date where day = '2020-10-30 10:00:01.111111'";
|
||||
explainString = getSQLPlanOrErrorMsg("EXPLAIN " + sql);
|
||||
Assert.assertTrue(explainString.contains("PREDICATES: `day` = '2020-10-30 10:00:01'"));
|
||||
if (Config.enable_date_conversion) {
|
||||
Assert.assertTrue(explainString.contains("PREDICATES: `day` = '2020-10-30 10:00:01.111111'"));
|
||||
} else {
|
||||
Assert.assertTrue(explainString.contains("PREDICATES: `day` = '2020-10-30 10:00:01'"));
|
||||
}
|
||||
//invalid date
|
||||
|
||||
sql = "select day from tbl_int_date where day = '2020-10-32'";
|
||||
@ -1794,7 +1799,11 @@ public class QueryPlanTest extends TestWithFeService {
|
||||
//valid datetime contains micro second
|
||||
sql = "select day from tbl_int_date where date = '2020-10-30 10:00:01.111111'";
|
||||
explainString = getSQLPlanOrErrorMsg("EXPLAIN " + sql);
|
||||
Assert.assertTrue(explainString.contains("PREDICATES: `date` = '2020-10-30 10:00:01'"));
|
||||
if (Config.enable_date_conversion) {
|
||||
Assert.assertTrue(explainString.contains("PREDICATES: `date` = '2020-10-30 10:00:01.111111'"));
|
||||
} else {
|
||||
Assert.assertTrue(explainString.contains("PREDICATES: `date` = '2020-10-30 10:00:01'"));
|
||||
}
|
||||
//invalid datetime
|
||||
sql = "select day from tbl_int_date where date = '2020-10-32'";
|
||||
explainString = getSQLPlanOrErrorMsg("EXPLAIN " + sql);
|
||||
|
||||
@ -25,6 +25,7 @@ import org.apache.doris.analysis.LargeIntLiteral;
|
||||
import org.apache.doris.analysis.StringLiteral;
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.Config;
|
||||
import org.apache.doris.common.util.TimeUtils;
|
||||
|
||||
import mockit.Expectations;
|
||||
@ -39,6 +40,7 @@ import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.temporal.ChronoField;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
@ -743,9 +745,17 @@ public class FEFunctionsTest {
|
||||
String currentTimestampString = FEFunctions.currentTimestamp().toSqlImpl().replace("'", "");
|
||||
|
||||
ZonedDateTime zonedDateTime = ZonedDateTime.now(TimeUtils.getTimeZone().toZoneId());
|
||||
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
|
||||
.appendPattern("uuuu-MM-dd HH:mm:ss")
|
||||
.toFormatter();
|
||||
DateTimeFormatter formatter = null;
|
||||
if (Config.enable_date_conversion) {
|
||||
formatter = new DateTimeFormatterBuilder()
|
||||
.appendPattern("uuuu-MM-dd HH:mm:ss")
|
||||
.appendFraction(ChronoField.MICRO_OF_SECOND, 0, 6, true)
|
||||
.toFormatter();
|
||||
} else {
|
||||
formatter = new DateTimeFormatterBuilder()
|
||||
.appendPattern("uuuu-MM-dd HH:mm:ss")
|
||||
.toFormatter();
|
||||
}
|
||||
|
||||
Assert.assertTrue(formatter.format(zonedDateTime).compareTo(currentTimestampString) >= 0);
|
||||
String nowTimeString = formatter.format(zonedDateTime).substring(
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
package org.apache.doris.rewrite;
|
||||
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.Config;
|
||||
import org.apache.doris.common.FeConstants;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
import org.apache.doris.utframe.DorisAssert;
|
||||
@ -76,7 +77,11 @@ public class RewriteDateLiteralRuleTest {
|
||||
public void testWithStringFormatDate() throws Exception {
|
||||
String query = "select * from " + DB_NAME + ".tb1 where k1 > '2021030112334455'";
|
||||
String planString = dorisAssert.query(query).explainQuery();
|
||||
Assert.assertTrue(planString.contains("`k1` > '2021-03-01 12:33:44'"));
|
||||
if (Config.enable_date_conversion) {
|
||||
Assert.assertTrue(planString.contains("`k1` > '2021-03-01 12:33:44.550000'"));
|
||||
} else {
|
||||
Assert.assertTrue(planString.contains("`k1` > '2021-03-01 12:33:44'"));
|
||||
}
|
||||
|
||||
query = "select k1 > '20210301' from " + DB_NAME + ".tb1";
|
||||
planString = dorisAssert.query(query).explainQuery();
|
||||
@ -84,7 +89,11 @@ public class RewriteDateLiteralRuleTest {
|
||||
|
||||
query = "select k1 > '20210301233234.34' from " + DB_NAME + ".tb1";
|
||||
planString = dorisAssert.query(query).explainQuery();
|
||||
Assert.assertTrue(planString.contains("`k1` > '2021-03-01 23:32:34'"));
|
||||
if (Config.enable_date_conversion) {
|
||||
Assert.assertTrue(planString.contains("`k1` > '2021-03-01 23:32:34.340000'"));
|
||||
} else {
|
||||
Assert.assertTrue(planString.contains("`k1` > '2021-03-01 23:32:34'"));
|
||||
}
|
||||
|
||||
query = "select * from " + DB_NAME + ".tb1 where k1 > '2021-03-01'";
|
||||
planString = dorisAssert.query(query).explainQuery();
|
||||
|
||||
Reference in New Issue
Block a user