[improvement](column) Support for the default value of current_timestamp in microsecond (#21487)
This commit is contained in:
@ -3518,6 +3518,10 @@ opt_default_value ::=
|
||||
{:
|
||||
RESULT = ColumnDef.DefaultValue.CURRENT_TIMESTAMP_DEFAULT_VALUE;
|
||||
:}
|
||||
| KW_DEFAULT KW_CURRENT_TIMESTAMP LPAREN INTEGER_LITERAL:precision RPAREN
|
||||
{:
|
||||
RESULT = ColumnDef.DefaultValue.currentTimeStampDefaultValueWithPrecision(precision);
|
||||
:}
|
||||
;
|
||||
|
||||
opt_is_key ::=
|
||||
|
||||
@ -36,6 +36,7 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -88,6 +89,12 @@ public class ColumnDef {
|
||||
this.defaultValueExprDef = new DefaultValueExprDef(exprName);
|
||||
}
|
||||
|
||||
public DefaultValue(boolean isSet, String value, String exprName, Long precision) {
|
||||
this.isSet = isSet;
|
||||
this.value = value;
|
||||
this.defaultValueExprDef = new DefaultValueExprDef(exprName, precision);
|
||||
}
|
||||
|
||||
// default "CURRENT_TIMESTAMP", only for DATETIME type
|
||||
public static String CURRENT_TIMESTAMP = "CURRENT_TIMESTAMP";
|
||||
public static String NOW = "now";
|
||||
@ -104,14 +111,60 @@ public class ColumnDef {
|
||||
// default "value", "[]" means empty array
|
||||
public static DefaultValue ARRAY_EMPTY_DEFAULT_VALUE = new DefaultValue(true, "[]");
|
||||
|
||||
public static DefaultValue currentTimeStampDefaultValueWithPrecision(Long precision) {
|
||||
if (precision > ScalarType.MAX_DATETIMEV2_SCALE || precision < 0) {
|
||||
throw new IllegalArgumentException("column's default value current_timestamp"
|
||||
+ " precision must be between 0 and 6");
|
||||
}
|
||||
if (precision == 0) {
|
||||
return new DefaultValue(true, CURRENT_TIMESTAMP, NOW);
|
||||
}
|
||||
String value = CURRENT_TIMESTAMP + "(" + precision + ")";
|
||||
String exprName = NOW;
|
||||
return new DefaultValue(true, value, exprName, precision);
|
||||
}
|
||||
|
||||
public boolean isCurrentTimeStamp() {
|
||||
return "CURRENT_TIMESTAMP".equals(value) && NOW.equals(defaultValueExprDef.getExprName());
|
||||
}
|
||||
|
||||
public boolean isCurrentTimeStampWithPrecision() {
|
||||
return defaultValueExprDef != null && value.startsWith(CURRENT_TIMESTAMP + "(")
|
||||
&& NOW.equals(defaultValueExprDef.getExprName());
|
||||
}
|
||||
|
||||
public long getCurrentTimeStampPrecision() {
|
||||
if (isCurrentTimeStampWithPrecision()) {
|
||||
return Long.parseLong(value.substring(CURRENT_TIMESTAMP.length() + 1, value.length() - 1));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return isCurrentTimeStamp()
|
||||
? LocalDateTime.now(TimeUtils.getTimeZone().toZoneId()).toString().replace('T', ' ')
|
||||
: value;
|
||||
if (isCurrentTimeStamp()) {
|
||||
return LocalDateTime.now(TimeUtils.getTimeZone().toZoneId()).toString().replace('T', ' ');
|
||||
} else if (isCurrentTimeStampWithPrecision()) {
|
||||
long precision = getCurrentTimeStampPrecision();
|
||||
String format = "yyyy-MM-dd HH:mm:ss";
|
||||
if (precision == 0) {
|
||||
return LocalDateTime.now(TimeUtils.getTimeZone().toZoneId()).toString().replace('T', ' ');
|
||||
} else if (precision == 1) {
|
||||
format = "yyyy-MM-dd HH:mm:ss.S";
|
||||
} else if (precision == 2) {
|
||||
format = "yyyy-MM-dd HH:mm:ss.SS";
|
||||
} else if (precision == 3) {
|
||||
format = "yyyy-MM-dd HH:mm:ss.SSS";
|
||||
} else if (precision == 4) {
|
||||
format = "yyyy-MM-dd HH:mm:ss.SSSS";
|
||||
} else if (precision == 5) {
|
||||
format = "yyyy-MM-dd HH:mm:ss.SSSSS";
|
||||
} else if (precision == 6) {
|
||||
format = "yyyy-MM-dd HH:mm:ss.SSSSSS";
|
||||
}
|
||||
return LocalDateTime.now(TimeUtils.getTimeZone().toZoneId())
|
||||
.format(DateTimeFormatter.ofPattern(format));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -459,6 +512,17 @@ public class ColumnDef {
|
||||
new DateLiteral(defaultValue, scalarType);
|
||||
} else {
|
||||
if (defaultValueExprDef.getExprName().equals(DefaultValue.NOW)) {
|
||||
if (defaultValueExprDef.getPrecision() != null) {
|
||||
Long defaultValuePrecision = defaultValueExprDef.getPrecision();
|
||||
String typeStr = scalarType.toString();
|
||||
int typePrecision =
|
||||
Integer.parseInt(typeStr.substring(typeStr.indexOf("(") + 1, typeStr.indexOf(")")));
|
||||
if (defaultValuePrecision > typePrecision) {
|
||||
typeStr = typeStr.replace("V2", "");
|
||||
throw new AnalysisException("default value precision: " + defaultValue
|
||||
+ " can not be greater than type precision: " + typeStr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
throw new AnalysisException("date literal [" + defaultValue + "] is invalid");
|
||||
|
||||
@ -22,29 +22,52 @@ package org.apache.doris.analysis;
|
||||
|
||||
import org.apache.doris.catalog.Type;
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.io.Text;
|
||||
import org.apache.doris.common.io.Writable;
|
||||
import org.apache.doris.persist.gson.GsonPostProcessable;
|
||||
import org.apache.doris.persist.gson.GsonUtils;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This def used for column which defaultValue is an expression.
|
||||
*/
|
||||
public class DefaultValueExprDef {
|
||||
public class DefaultValueExprDef implements Writable, GsonPostProcessable {
|
||||
private static final Logger LOG = LogManager.getLogger(DefaultValueExprDef.class);
|
||||
@SerializedName("exprName")
|
||||
private String exprName;
|
||||
@SerializedName("precision")
|
||||
private Long precision;
|
||||
|
||||
|
||||
public DefaultValueExprDef(String exprName) {
|
||||
this.exprName = exprName;
|
||||
}
|
||||
|
||||
public DefaultValueExprDef(String exprName, Long precision) {
|
||||
this.exprName = exprName;
|
||||
this.precision = precision;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate a FunctionCallExpr
|
||||
* @return FunctionCallExpr of exprName
|
||||
*/
|
||||
public FunctionCallExpr getExpr(Type type) {
|
||||
FunctionCallExpr expr = new FunctionCallExpr(exprName, new FunctionParams(null));
|
||||
List<Expr> exprs = null;
|
||||
if (precision != null) {
|
||||
exprs = Lists.newArrayList();
|
||||
exprs.add(new IntLiteral(precision));
|
||||
}
|
||||
FunctionCallExpr expr = new FunctionCallExpr(exprName, new FunctionParams(exprs));
|
||||
try {
|
||||
expr.analyzeImplForDefaultValue(type);
|
||||
} catch (AnalysisException e) {
|
||||
@ -56,4 +79,26 @@ public class DefaultValueExprDef {
|
||||
public String getExprName() {
|
||||
return exprName;
|
||||
}
|
||||
|
||||
public Long getPrecision() {
|
||||
return precision;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput out) throws IOException {
|
||||
String json = GsonUtils.GSON.toJson(this);
|
||||
Text.writeString(out, json);
|
||||
}
|
||||
|
||||
public static DefaultValueExprDef read(DataInput in) throws IOException {
|
||||
String json = Text.readString(in);
|
||||
return GsonUtils.GSON.fromJson(json, DefaultValueExprDef.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gsonPostProcess() throws IOException {
|
||||
if (precision == null) {
|
||||
precision = 0L;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1230,8 +1230,14 @@ public class InternalCatalog implements CatalogIf<Database> {
|
||||
boolean setDefault = StringUtils.isNotBlank(column.getDefaultValue());
|
||||
DefaultValue defaultValue;
|
||||
if (column.getDefaultValueExprDef() != null) {
|
||||
defaultValue = new DefaultValue(setDefault, column.getDefaultValue(),
|
||||
if (column.getDefaultValueExprDef().getPrecision() != null) {
|
||||
defaultValue = new DefaultValue(setDefault, column.getDefaultValue(),
|
||||
column.getDefaultValueExprDef().getExprName(),
|
||||
column.getDefaultValueExprDef().getPrecision());
|
||||
} else {
|
||||
defaultValue = new DefaultValue(setDefault, column.getDefaultValue(),
|
||||
column.getDefaultValueExprDef().getExprName());
|
||||
}
|
||||
} else {
|
||||
defaultValue = new DefaultValue(setDefault, column.getDefaultValue());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user