From f35912477451b82f3e8e5adfb33b5cf8aebc9368 Mon Sep 17 00:00:00 2001 From: feiniaofeiafei <53502832+feiniaofeiafei@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:11:29 +0800 Subject: [PATCH] [Feat](nereids) support column default value current_date (#32268) --- .../org/apache/doris/nereids/DorisParser.g4 | 4 +- .../org/apache/doris/analysis/ColumnDef.java | 21 +++++- .../nereids/parser/LogicalPlanBuilder.java | 4 +- .../plans/commands/info/DefaultValue.java | 2 + .../data/correctness_p0/test_current_date.out | 13 ++++ .../correctness_p0/test_current_date.groovy | 75 +++++++++++++++++++ 6 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 regression-test/data/correctness_p0/test_current_date.out create mode 100644 regression-test/suites/correctness_p0/test_current_date.groovy diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 index ebb5984e862840..921059637a596c 100644 --- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 +++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 @@ -538,8 +538,8 @@ columnDef (aggType=aggTypeDef)? ((NOT)? NULL)? (AUTO_INCREMENT (LEFT_PAREN autoIncInitValue=number RIGHT_PAREN)?)? - (DEFAULT (nullValue=NULL | INTEGER_VALUE | stringValue=STRING_LITERAL - | CURRENT_TIMESTAMP (LEFT_PAREN defaultValuePrecision=number RIGHT_PAREN)?))? + (DEFAULT (nullValue=NULL | INTEGER_VALUE | stringValue=STRING_LITERAL| CURRENT_DATE + | defaultTimestamp=CURRENT_TIMESTAMP (LEFT_PAREN defaultValuePrecision=number RIGHT_PAREN)?))? (ON UPDATE CURRENT_TIMESTAMP (LEFT_PAREN onUpdateValuePrecision=number RIGHT_PAREN)?)? (COMMENT comment=STRING_LITERAL)? ; diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/ColumnDef.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/ColumnDef.java index d202467dfb37ba..990035bbecfd0c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/ColumnDef.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/ColumnDef.java @@ -93,6 +93,7 @@ public DefaultValue(boolean isSet, String value, String exprName, Long precision this.defaultValueExprDef = new DefaultValueExprDef(exprName, precision); } + public static String CURRENT_DATE = "CURRENT_DATE"; // default "CURRENT_TIMESTAMP", only for DATETIME type public static String CURRENT_TIMESTAMP = "CURRENT_TIMESTAMP"; public static String NOW = "now"; @@ -466,7 +467,15 @@ public static void validateDefaultValue(Type type, String defaultValue, DefaultV break; case DATE: case DATEV2: - new DateLiteral(defaultValue, scalarType); + if (defaultValueExprDef == null) { + new DateLiteral(defaultValue, scalarType); + } else { + if (defaultValueExprDef.getExprName().equalsIgnoreCase(DefaultValue.CURRENT_DATE)) { + break; + } else { + throw new AnalysisException("date literal [" + defaultValue + "] is invalid"); + } + } break; case DATETIME: case DATETIMEV2: @@ -520,6 +529,16 @@ public static void validateDefaultValue(Type type, String defaultValue, DefaultV throw new AnalysisException("Types other than DATETIME and DATETIMEV2 " + "cannot use current_timestamp as the default value"); } + } else if (null != defaultValueExprDef + && defaultValueExprDef.getExprName().equals(DefaultValue.CURRENT_DATE.toLowerCase())) { + switch (primitiveType) { + case DATE: + case DATEV2: + break; + default: + throw new AnalysisException("Types other than DATE and DATEV2 " + + "cannot use current_date as the default value"); + } } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java index 019e95cbed55a2..d89172f12d0824 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java @@ -2550,7 +2550,7 @@ public ColumnDefinition visitColumnDef(ColumnDefContext ctx) { defaultValue = Optional.of(new DefaultValue(toStringValue(ctx.stringValue.getText()))); } else if (ctx.nullValue != null) { defaultValue = Optional.of(DefaultValue.NULL_DEFAULT_VALUE); - } else if (ctx.CURRENT_TIMESTAMP() != null) { + } else if (ctx.defaultTimestamp != null) { if (ctx.defaultValuePrecision == null) { defaultValue = Optional.of(DefaultValue.CURRENT_TIMESTAMP_DEFAULT_VALUE); } else { @@ -2558,6 +2558,8 @@ public ColumnDefinition visitColumnDef(ColumnDefContext ctx) { .currentTimeStampDefaultValueWithPrecision( Long.valueOf(ctx.defaultValuePrecision.getText()))); } + } else if (ctx.CURRENT_DATE() != null) { + defaultValue = Optional.of(DefaultValue.CURRENT_DATE_DEFAULT_VALUE); } } if (ctx.UPDATE() != null) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DefaultValue.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DefaultValue.java index 40c2b5ed85ad8e..8e7228705ac2a5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DefaultValue.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DefaultValue.java @@ -24,8 +24,10 @@ * default value of a column. */ public class DefaultValue { + public static String CURRENT_DATE = "CURRENT_DATE"; public static String CURRENT_TIMESTAMP = "CURRENT_TIMESTAMP"; public static String NOW = "now"; + public static DefaultValue CURRENT_DATE_DEFAULT_VALUE = new DefaultValue(CURRENT_DATE, CURRENT_DATE.toLowerCase()); public static DefaultValue CURRENT_TIMESTAMP_DEFAULT_VALUE = new DefaultValue(CURRENT_TIMESTAMP, NOW); // default null public static DefaultValue NULL_DEFAULT_VALUE = new DefaultValue(null); diff --git a/regression-test/data/correctness_p0/test_current_date.out b/regression-test/data/correctness_p0/test_current_date.out new file mode 100644 index 00000000000000..850f4c8c66278c --- /dev/null +++ b/regression-test/data/correctness_p0/test_current_date.out @@ -0,0 +1,13 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !insert_into1 -- +4 + +-- !insert_into2 -- +4 + +-- !stream_load_csv1 -- +5 + +-- !stream_load_csv2 -- +5 + diff --git a/regression-test/suites/correctness_p0/test_current_date.groovy b/regression-test/suites/correctness_p0/test_current_date.groovy new file mode 100644 index 00000000000000..763c756aad3280 --- /dev/null +++ b/regression-test/suites/correctness_p0/test_current_date.groovy @@ -0,0 +1,75 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +suite("test_current_date") { + sql "SET enable_nereids_planner=true" + sql "SET enable_fallback_to_original_planner=false" + def tableName = "test_current_date" + + sql """ DROP TABLE IF EXISTS ${tableName} """ + sql """ + CREATE TABLE IF NOT EXISTS ${tableName} + ( + id TINYINT, + name CHAR(10) NOT NULL DEFAULT "zs", + dt_0 DATE, + dt_2 DATEV2, + dt_1 DATE DEFAULT current_date, + dt_3 DATEV2 DEFAULT current_date, + + ) + COMMENT "test current_date table" + DISTRIBUTED BY HASH(id) + PROPERTIES("replication_num" = "1"); + """ + + // test insert into. + sql " insert into ${tableName} (id,name,dt_0,dt_2) values (1,'aa',current_date(),current_date()); " + sql " insert into ${tableName} (id,name,dt_0,dt_2) values (2,'bb',current_date(),current_date()); " + sql " insert into ${tableName} (id,name,dt_0,dt_2) values (3,'cc',current_date(),current_date()); " + sql " insert into ${tableName} (id,name,dt_0,dt_2) values (4,'dd',current_date(),current_date()); " + sql "sync" + qt_insert_into1 """ select count(*) from ${tableName} where dt_0 = dt_1; """ + qt_insert_into2 """ select count(*) from ${tableName} where dt_2 = dt_3; """ + + sql """select now()""" + + // test csv stream load. + streamLoad { + table "${tableName}" + + set 'column_separator', ',' + set 'columns', 'id, name, dt_0 = current_date(), dt_2 = current_date()' + + file 'test_current_timestamp_streamload.csv' + + time 10000 // limit inflight 10s + } + + sql "sync" + + qt_stream_load_csv1 """ select count(*) from ${tableName} where id > 4 and dt_0 = dt_1; """ + qt_stream_load_csv2 """ select count(*) from ${tableName} where id > 4 and dt_2 = dt_3; """ + + sql "DROP TABLE IF EXISTS test_default10" + test { + sql """create table test_default10(a int, b varchar(100) default current_date) + distributed by hash(a) properties('replication_num'="1");""" + exception "Types other than DATE and DATEV2 cannot use current_date as the default value" + } + +} \ No newline at end of file