This is an automated email from the ASF dual-hosted git repository.

dataroaring pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 187bf14d81 [feature-wip](auto-inc)(step-1) add syntax support for 
duplicate table (#20284)
187bf14d81 is described below

commit 187bf14d8129c043db1bd23674ae55ee53ae4dc8
Author: bobhan1 <[email protected]>
AuthorDate: Wed Jun 7 22:01:28 2023 +0800

    [feature-wip](auto-inc)(step-1) add syntax support for duplicate table 
(#20284)
    
    
    Co-authored-by: yifeng <[email protected]>
---
 fe/fe-core/src/main/cup/sql_parser.cup             |  22 ++-
 .../java/org/apache/doris/analysis/ColumnDef.java  |  39 ++--
 .../CreateMultiTableMaterializedViewStmt.java      |   1 +
 .../main/java/org/apache/doris/catalog/Column.java |  28 ++-
 .../doris/catalog/external/HMSExternalTable.java   |   2 +-
 .../java/org/apache/doris/common/ErrorCode.java    |  17 +-
 .../doris/common/proc/IndexSchemaProcNode.java     |   3 +
 .../apache/doris/datasource/InternalCatalog.java   |  35 +++-
 .../apache/doris/service/FrontendServiceImpl.java  |   4 +-
 fe/fe-core/src/main/jflex/sql_scanner.flex         |   1 +
 .../storage/test_dup_table_auto_inc_col.out        |  29 +++
 .../aggregate/test_aggregate_table.groovy          |  18 ++
 .../storage/test_dup_table_auto_inc_col.groovy     | 220 +++++++++++++++++++++
 .../data_model_p0/unique/test_unique_table.groovy  |  16 ++
 14 files changed, 400 insertions(+), 35 deletions(-)

diff --git a/fe/fe-core/src/main/cup/sql_parser.cup 
b/fe/fe-core/src/main/cup/sql_parser.cup
index 4f2014b001..b4dac21cf7 100644
--- a/fe/fe-core/src/main/cup/sql_parser.cup
+++ b/fe/fe-core/src/main/cup/sql_parser.cup
@@ -256,6 +256,7 @@ terminal String
     KW_ANTI,
     KW_APPEND,
     KW_ARRAY,
+    KW_AUTO_INCREMENT,
     KW_AS,
     KW_ASC,
     KW_AUTHORS,
@@ -867,7 +868,7 @@ nonterminal ParseNode load_property;
 nonterminal List<ParseNode> opt_load_property_list;
 
 // Boolean
-nonterminal Boolean opt_negative, opt_is_allow_null, opt_is_key, 
opt_read_only, opt_aggregate, opt_local;
+nonterminal Boolean opt_negative, opt_is_allow_null, opt_is_key, 
opt_read_only, opt_aggregate, opt_local, opt_is_auto_inc;
 nonterminal String opt_from_rollup, opt_to_rollup;
 nonterminal ColumnPosition opt_col_pos;
 
@@ -3467,21 +3468,21 @@ opt_is_key ::=
     ;
 
 column_definition ::=
-    ident:columnName type_def:typeDef opt_is_key:isKey 
opt_is_allow_null:isAllowNull opt_default_value:defaultValue opt_comment:comment
+    ident:columnName type_def:typeDef opt_is_key:isKey 
opt_is_allow_null:isAllowNull opt_is_auto_inc:isAutoInc 
opt_default_value:defaultValue opt_comment:comment
     {:
-        ColumnDef columnDef = new ColumnDef(columnName, typeDef, isKey, null, 
isAllowNull, defaultValue, comment);
+        ColumnDef columnDef = new ColumnDef(columnName, typeDef, isKey, null, 
isAllowNull, isAutoInc, defaultValue, comment);
         RESULT = columnDef;
     :}
-    | ident:columnName type_def:typeDef IDENT:fnName LPAREN 
type_def_nullable_list:list RPAREN opt_default_value:defaultValue 
opt_comment:comment
+    | ident:columnName type_def:typeDef IDENT:fnName LPAREN 
type_def_nullable_list:list RPAREN opt_is_auto_inc:isAutoInc 
opt_default_value:defaultValue opt_comment:comment
     {:
         ColumnDef columnDef = new ColumnDef(columnName, typeDef, false, 
AggregateType.GENERIC_AGGREGATION, false, defaultValue, comment);
         columnDef.setGenericAggregationName(fnName);
         columnDef.setGenericAggregationArguments(list);
         RESULT = columnDef;
     :}
-    | ident:columnName type_def:typeDef opt_is_key:isKey opt_agg_type:aggType 
opt_is_allow_null:isAllowNull opt_default_value:defaultValue opt_comment:comment
+    | ident:columnName type_def:typeDef opt_is_key:isKey opt_agg_type:aggType 
opt_is_allow_null:isAllowNull opt_is_auto_inc:isAutoInc 
opt_default_value:defaultValue opt_comment:comment
     {:
-        ColumnDef columnDef = new ColumnDef(columnName, typeDef, isKey, 
aggType, isAllowNull, defaultValue, comment);
+        ColumnDef columnDef = new ColumnDef(columnName, typeDef, isKey, 
aggType, isAllowNull, isAutoInc, defaultValue, comment);
         RESULT = columnDef;
     :}
     | ident:columnName type_def:typeDef opt_is_key:isKey opt_agg_type:aggType 
LPAREN type_def_nullable_list:list RPAREN opt_default_value:defaultValue 
opt_comment:comment
@@ -3521,6 +3522,15 @@ opt_is_allow_null ::=
     :}
     ;
 
+opt_is_auto_inc ::=
+    {:
+        RESULT = false;
+    :}
+    | KW_AUTO_INCREMENT
+    {:
+        RESULT = true;
+    :}
+    ;
 opt_comment ::=
     /* empty */
     {:
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 7cd5ca9aa3..8a6bff11f0 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
@@ -40,7 +40,7 @@ import java.util.stream.Collectors;
 
 // Column definition which is generated by SQL syntax parser
 // Syntax:
-//      name type [key] [agg_type] [NULL | NOT NULL] [DEFAULT default_value] 
[comment]
+//      name type [key] [agg_type] [NULL | NOT NULL] [AUTO_INCREMENT] [DEFAULT 
default_value] [comment]
 // Example:
 //      id bigint key NOT NULL DEFAULT "-1" "user id"
 //      pv bigint sum NULL DEFAULT "-1" "page visit"
@@ -123,12 +123,18 @@ public class ColumnDef {
 
     private boolean isKey;
     private boolean isAllowNull;
+    private boolean isAutoInc;
     private DefaultValue defaultValue;
     private String comment;
     private boolean visible;
 
     public ColumnDef(String name, TypeDef typeDef) {
-        this(name, typeDef, false, null, false, DefaultValue.NOT_SET, "");
+        this(name, typeDef, false, null, false, false, DefaultValue.NOT_SET, 
"");
+    }
+
+    public ColumnDef(String name, TypeDef typeDef, boolean isKey, 
AggregateType aggregateType,
+                     boolean isAllowNull, boolean isAutoInc, DefaultValue 
defaultValue, String comment) {
+        this(name, typeDef, isKey, aggregateType, isAllowNull, isAutoInc, 
defaultValue, comment, true);
     }
 
     public ColumnDef(String name, TypeDef typeDef, boolean isAllowNull) {
@@ -137,16 +143,17 @@ public class ColumnDef {
 
     public ColumnDef(String name, TypeDef typeDef, boolean isKey, 
AggregateType aggregateType,
                      boolean isAllowNull, DefaultValue defaultValue, String 
comment) {
-        this(name, typeDef, isKey, aggregateType, isAllowNull, defaultValue, 
comment, true);
+        this(name, typeDef, isKey, aggregateType, isAllowNull, false, 
defaultValue, comment, true);
     }
 
     public ColumnDef(String name, TypeDef typeDef, boolean isKey, 
AggregateType aggregateType,
-            boolean isAllowNull, DefaultValue defaultValue, String comment, 
boolean visible) {
+            boolean isAllowNull, boolean isAutoInc, DefaultValue defaultValue, 
String comment, boolean visible) {
         this.name = name;
         this.typeDef = typeDef;
         this.isKey = isKey;
         this.aggregateType = aggregateType;
         this.isAllowNull = isAllowNull;
+        this.isAutoInc = isAutoInc;
         this.defaultValue = defaultValue;
         this.comment = comment;
         this.visible = visible;
@@ -154,38 +161,38 @@ public class ColumnDef {
 
     public static ColumnDef newDeleteSignColumnDef() {
         return new ColumnDef(Column.DELETE_SIGN, 
TypeDef.create(PrimitiveType.TINYINT), false, null, false,
-                new ColumnDef.DefaultValue(true, "0"), "doris delete flag 
hidden column", false);
+                false, new ColumnDef.DefaultValue(true, "0"), "doris delete 
flag hidden column", false);
     }
 
     public static ColumnDef newDeleteSignColumnDef(AggregateType 
aggregateType) {
         return new ColumnDef(Column.DELETE_SIGN, 
TypeDef.create(PrimitiveType.TINYINT), false, aggregateType, false,
-                new ColumnDef.DefaultValue(true, "0"), "doris delete flag 
hidden column", false);
+                false, new ColumnDef.DefaultValue(true, "0"), "doris delete 
flag hidden column", false);
     }
 
     public static ColumnDef newSequenceColumnDef(Type type) {
-        return new ColumnDef(Column.SEQUENCE_COL, new TypeDef(type), false, 
null, true, DefaultValue.NULL_DEFAULT_VALUE,
-                "sequence column hidden column", false);
+        return new ColumnDef(Column.SEQUENCE_COL, new TypeDef(type), false, 
null, true,
+                false, DefaultValue.NULL_DEFAULT_VALUE, "sequence column 
hidden column", false);
     }
 
     public static ColumnDef newSequenceColumnDef(Type type, AggregateType 
aggregateType) {
         return new ColumnDef(Column.SEQUENCE_COL, new TypeDef(type), false,
-                aggregateType, true, DefaultValue.NULL_DEFAULT_VALUE,
+                aggregateType, true, false, DefaultValue.NULL_DEFAULT_VALUE,
                 "sequence column hidden column", false);
     }
 
     public static ColumnDef newRowStoreColumnDef() {
-        return new ColumnDef(Column.ROW_STORE_COL, 
TypeDef.create(PrimitiveType.STRING), false, null, false,
+        return new ColumnDef(Column.ROW_STORE_COL, 
TypeDef.create(PrimitiveType.STRING), false, null, false, false,
                 new ColumnDef.DefaultValue(true, ""), "doris row store hidden 
column", false);
     }
 
     public static ColumnDef newVersionColumnDef() {
-        return new ColumnDef(Column.VERSION_COL, 
TypeDef.create(PrimitiveType.BIGINT), false, null, false,
+        return new ColumnDef(Column.VERSION_COL, 
TypeDef.create(PrimitiveType.BIGINT), false, null, false, false,
                 new ColumnDef.DefaultValue(true, "0"), "doris version hidden 
column", false);
     }
 
     public static ColumnDef newVersionColumnDef(AggregateType aggregateType) {
         return new ColumnDef(Column.VERSION_COL, 
TypeDef.create(PrimitiveType.BIGINT), false, aggregateType, false,
-                new ColumnDef.DefaultValue(true, "0"), "doris version hidden 
column", false);
+                false, new ColumnDef.DefaultValue(true, "0"), "doris version 
hidden column", false);
     }
 
     public boolean isAllowNull() {
@@ -486,6 +493,10 @@ public class ColumnDef {
             sb.append("NULL ");
         }
 
+        if (isAutoInc) {
+            sb.append("AUTO_INCREMENT ");
+        }
+
         if (defaultValue.isSet) {
             sb.append("DEFAULT \"").append(defaultValue.value).append("\" ");
         }
@@ -506,8 +517,8 @@ public class ColumnDef {
             type = Expr.createAggStateType(genericAggregationName, typeList, 
nullableList);
         }
 
-        return new Column(name, type, isKey, aggregateType, isAllowNull, 
defaultValue.value, comment, visible,
-                defaultValue.defaultValueExprDef, 
Column.COLUMN_UNIQUE_ID_INIT_VALUE, defaultValue.getValue(),
+        return new Column(name, type, isKey, aggregateType, isAllowNull, 
isAutoInc, defaultValue.value, comment,
+                visible, defaultValue.defaultValueExprDef, 
Column.COLUMN_UNIQUE_ID_INIT_VALUE, defaultValue.getValue(),
                 genericAggregationName, typeList, nullableList);
     }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMultiTableMaterializedViewStmt.java
 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMultiTableMaterializedViewStmt.java
index 541eb4ed9f..ee00efdab0 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMultiTableMaterializedViewStmt.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateMultiTableMaterializedViewStmt.java
@@ -164,6 +164,7 @@ public class CreateMultiTableMaterializedViewStmt extends 
CreateTableStmt {
                         column.isKey(),
                         null,
                         column.isAllowNull(),
+                        column.isAutoInc(),
                         new DefaultValue(column.getDefaultValue() != null, 
column.getDefaultValue()),
                         column.getComment())
                 ).collect(Collectors.toList());
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java
index 936db90a35..f3e7b4daa4 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Column.java
@@ -70,7 +70,7 @@ public class Column implements Writable, GsonPostProcessable {
     private static final String COLUMN_MAP_VALUE = "value";
 
     public static final Column UNSUPPORTED_COLUMN = new Column("unknown",
-            Type.UNSUPPORTED, true, null, true, null, "invalid", true, null, 
-1, null, null, null, null);
+            Type.UNSUPPORTED, true, null, true, false, null, "invalid", true, 
null, -1, null, null, null, null);
 
     @SerializedName(value = "name")
     private String name;
@@ -91,6 +91,8 @@ public class Column implements Writable, GsonPostProcessable {
     private boolean isKey;
     @SerializedName(value = "isAllowNull")
     private boolean isAllowNull;
+    @SerializedName(value = "isAutoInc")
+    private boolean isAutoInc;
     @SerializedName(value = "defaultValue")
     private String defaultValue;
     @SerializedName(value = "comment")
@@ -167,27 +169,27 @@ public class Column implements Writable, 
GsonPostProcessable {
 
     public Column(String name, Type type, boolean isKey, AggregateType 
aggregateType, boolean isAllowNull,
             String defaultValue, String comment) {
-        this(name, type, isKey, aggregateType, isAllowNull, defaultValue, 
comment, true, null,
+        this(name, type, isKey, aggregateType, isAllowNull, false, 
defaultValue, comment, true, null,
                 COLUMN_UNIQUE_ID_INIT_VALUE, defaultValue, null, null, null);
     }
 
     public Column(String name, Type type, boolean isKey, AggregateType 
aggregateType, boolean isAllowNull,
             String comment, boolean visible, int colUniqueId) {
-        this(name, type, isKey, aggregateType, isAllowNull, null, comment, 
visible, null,
+        this(name, type, isKey, aggregateType, isAllowNull, false, null, 
comment, visible, null,
                 colUniqueId, null, null, null, null);
     }
 
     public Column(String name, Type type, boolean isKey, AggregateType 
aggregateType, boolean isAllowNull,
             String defaultValue, String comment, boolean visible, 
DefaultValueExprDef defaultValueExprDef,
             int colUniqueId, String realDefaultValue) {
-        this(name, type, isKey, aggregateType, isAllowNull, defaultValue, 
comment, visible, defaultValueExprDef,
+        this(name, type, isKey, aggregateType, isAllowNull, false, 
defaultValue, comment, visible, defaultValueExprDef,
                 colUniqueId, realDefaultValue, null, null, null);
     }
 
     public Column(String name, Type type, boolean isKey, AggregateType 
aggregateType, boolean isAllowNull,
-            String defaultValue, String comment, boolean visible, 
DefaultValueExprDef defaultValueExprDef,
-            int colUniqueId, String realDefaultValue, String 
genericAggregationName,
-            List<Type> genericAggregationArguments, List<Boolean> 
nullableList) {
+            boolean isAutoInc, String defaultValue, String comment, boolean 
visible,
+            DefaultValueExprDef defaultValueExprDef, int colUniqueId, String 
realDefaultValue,
+            String genericAggregationName, List<Type> 
genericAggregationArguments, List<Boolean> nullableList) {
         this.name = name;
         if (this.name == null) {
             this.name = "";
@@ -202,6 +204,7 @@ public class Column implements Writable, 
GsonPostProcessable {
         this.isAggregationTypeImplicit = false;
         this.isKey = isKey;
         this.isAllowNull = isAllowNull;
+        this.isAutoInc = isAutoInc;
         this.defaultValue = defaultValue;
         this.realDefaultValue = realDefaultValue;
         this.defaultValueExprDef = defaultValueExprDef;
@@ -230,6 +233,7 @@ public class Column implements Writable, 
GsonPostProcessable {
         this.isKey = column.isKey();
         this.isCompoundKey = column.isCompoundKey();
         this.isAllowNull = column.isAllowNull();
+        this.isAutoInc = column.isAutoInc();
         this.defaultValue = column.getDefaultValue();
         this.realDefaultValue = column.realDefaultValue;
         this.defaultValueExprDef = column.defaultValueExprDef;
@@ -426,6 +430,10 @@ public class Column implements Writable, 
GsonPostProcessable {
         return isAllowNull;
     }
 
+    public boolean isAutoInc() {
+        return isAutoInc;
+    }
+
     public void setIsAllowNull(boolean isAllowNull) {
         this.isAllowNull = isAllowNull;
     }
@@ -732,6 +740,9 @@ public class Column implements Writable, 
GsonPostProcessable {
         } else {
             sb.append(" NOT NULL");
         }
+        if (isAutoInc) {
+            sb.append(" AUTO_INCREMENT");
+        }
         if (defaultValue != null && getDataType() != PrimitiveType.HLL && 
getDataType() != PrimitiveType.BITMAP) {
             if (defaultValueExprDef != null) {
                 sb.append(" DEFAULT ").append(defaultValue).append("");
@@ -753,7 +764,7 @@ public class Column implements Writable, 
GsonPostProcessable {
     @Override
     public int hashCode() {
         return Objects.hash(name, getDataType(), getStrLen(), getPrecision(), 
getScale(), aggregationType,
-                isAggregationTypeImplicit, isKey, isAllowNull, defaultValue, 
comment, children, visible,
+                isAggregationTypeImplicit, isKey, isAllowNull, isAutoInc, 
defaultValue, comment, children, visible,
                 realDefaultValue);
     }
 
@@ -774,6 +785,7 @@ public class Column implements Writable, 
GsonPostProcessable {
                 && isAggregationTypeImplicit == other.isAggregationTypeImplicit
                 && isKey == other.isKey
                 && isAllowNull == other.isAllowNull
+                && isAutoInc == other.isAutoInc
                 && getDataType().equals(other.getDataType())
                 && getStrLen() == other.getStrLen()
                 && getPrecision() == other.getPrecision()
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/external/HMSExternalTable.java
 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/external/HMSExternalTable.java
index 7a8fdaf6fb..3fe68dbab8 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/external/HMSExternalTable.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/external/HMSExternalTable.java
@@ -402,7 +402,7 @@ public class HMSExternalTable extends ExternalTable {
                     
HiveMetaStoreClientHelper.hiveTypeToDorisType(field.getType(),
                             IcebergExternalTable.ICEBERG_DATETIME_SCALE_MS),
                     true, null,
-                    true, null, field.getComment(), true, null,
+                    true, false, null, field.getComment(), true, null,
                     
schema.caseInsensitiveFindField(field.getName()).fieldId(), null, null, null, 
null));
         }
         return tmpSchema;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java 
b/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java
index 447c9d481d..f773bfd5ff 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/common/ErrorCode.java
@@ -1190,7 +1190,22 @@ public enum ErrorCode {
      + " table supports time travel in current version"),
 
     ERR_NONSSL_HANDSHAKE_RESPONSE(5091, new byte[] {'4', '2', '0', '0'},
-            "SSL mode on but received non-ssl handshake response from 
client.");
+            "SSL mode on but received non-ssl handshake response from 
client."),
+
+    ERR_MORE_THAN_ONE_AUTO_INCREMENT_COLUMN(5092, new byte[]{'4', '2', '0', 
'0', '0'},
+            "there can be at most one auto increment column in OlapTable."),
+
+    ERR_AUTO_INCREMENT_COLUMN_NULLABLE(5093, new byte[]{'4', '2', '0', '0', 
'0'},
+            "the auto increment column should be NOT NULL."),
+
+    ERR_AUTO_INCREMENT_COLUMN_WITH_DEFAULT_VALUE(5094, new byte[]{'4', '2', 
'0', '0', '0'},
+            "the auto increment column can't have default value."),
+
+    ERR_AUTO_INCREMENT_COLUMN_NOT_BIGINT_TYPE(5095, new byte[]{'4', '2', '0', 
'0', '0'},
+            "the auto increment must be BIGINT type."),
+
+    ERR_AUTO_INCREMENT_COLUMN_NOT_INT_DUPLICATE_TABLE(5096, new byte[]{'4', 
'2', '0', '0', '0'},
+            "the auto increment is only supported in duplicate table.");
 
     // This is error code
     private final int code;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/common/proc/IndexSchemaProcNode.java
 
b/fe/fe-core/src/main/java/org/apache/doris/common/proc/IndexSchemaProcNode.java
index 9d3ea1882f..7ede055f1d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/common/proc/IndexSchemaProcNode.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/common/proc/IndexSchemaProcNode.java
@@ -64,6 +64,9 @@ public class IndexSchemaProcNode implements ProcNodeInterface 
{
             if (bfColumns != null && bfColumns.contains(column.getName())) {
                 extras.add("BLOOM_FILTER");
             }
+            if (column.isAutoInc()) {
+                extras.add("AUTO_INCREMENT");
+            }
             String extraStr = StringUtils.join(extras, ",");
 
             List<String> rowList = Arrays.asList(column.getDisplayName(),
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
index 1fc3b20bcc..eef9b345b3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
@@ -1192,7 +1192,8 @@ public class InternalCatalog implements 
CatalogIf<Database> {
                 }
                 ColumnDef columnDef;
                 if (resultExpr.getSrcSlotRef() == null) {
-                    columnDef = new ColumnDef(name, typeDef, false, null, 
true, new DefaultValue(false, null), "");
+                    columnDef = new ColumnDef(name, typeDef, false, null,
+                        true, false, new DefaultValue(false, null), "");
                 } else {
                     Column column = 
resultExpr.getSrcSlotRef().getDesc().getColumn();
                     boolean setDefault = 
StringUtils.isNotBlank(column.getDefaultValue());
@@ -1204,7 +1205,7 @@ public class InternalCatalog implements 
CatalogIf<Database> {
                         defaultValue = new DefaultValue(setDefault, 
column.getDefaultValue());
                     }
                     columnDef = new ColumnDef(name, typeDef, false, null,
-                            column.isAllowNull(), defaultValue, 
column.getComment());
+                            column.isAllowNull(), column.isAutoInc(), 
defaultValue, column.getComment());
                 }
                 createTableStmt.addColumnDef(columnDef);
                 // set first column as default distribution
@@ -1839,6 +1840,7 @@ public class InternalCatalog implements 
CatalogIf<Database> {
         // create columns
         List<Column> baseSchema = stmt.getColumns();
         validateColumns(baseSchema, isKeysRequired);
+        checkAutoIncColummns(baseSchema, keysType);
 
         // analyze replica allocation
         ReplicaAllocation replicaAlloc = 
PropertyAnalyzer.analyzeReplicaAllocation(stmt.getProperties(), "");
@@ -2582,7 +2584,7 @@ public class InternalCatalog implements 
CatalogIf<Database> {
     }
 
     /*
-     * generate and check columns' order and key's existence
+     * generate and check columns' order and key's existence,
      */
     private void validateColumns(List<Column> columns, boolean isKeysRequired) 
throws DdlException {
         if (columns.isEmpty()) {
@@ -2607,6 +2609,33 @@ public class InternalCatalog implements 
CatalogIf<Database> {
         }
     }
 
+    /*
+     * check column's auto increment property
+     */
+    private void checkAutoIncColummns(List<Column> columns, KeysType type) 
throws DdlException {
+        boolean encounterAutoIncColumn = false;
+        for (Column column : columns) {
+            if (column.isAutoInc()) {
+                if (encounterAutoIncColumn) {
+                    
ErrorReport.reportDdlException(ErrorCode.ERR_MORE_THAN_ONE_AUTO_INCREMENT_COLUMN);
+                }
+                encounterAutoIncColumn = true;
+                if (column.isAllowNull()) {
+                    
ErrorReport.reportDdlException(ErrorCode.ERR_AUTO_INCREMENT_COLUMN_NULLABLE);
+                }
+                if (column.getDefaultValue() != null) {
+                    
ErrorReport.reportDdlException(ErrorCode.ERR_AUTO_INCREMENT_COLUMN_WITH_DEFAULT_VALUE);
+                }
+                if (!column.getType().isBigIntType()) {
+                    
ErrorReport.reportDdlException(ErrorCode.ERR_AUTO_INCREMENT_COLUMN_NOT_BIGINT_TYPE);
+                }
+            }
+        }
+        if (encounterAutoIncColumn && type != KeysType.DUP_KEYS) {
+            
ErrorReport.reportDdlException(ErrorCode.ERR_AUTO_INCREMENT_COLUMN_NOT_INT_DUPLICATE_TABLE);
+        }
+    }
+
     /*
      * Truncate specified table or partitions.
      * The main idea is:
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java 
b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
index 6ec8718abd..a0d349e407 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
@@ -358,8 +358,8 @@ public class FrontendServiceImpl implements 
FrontendService.Iface {
         if (typeDef.getType().isArrayType()) {
             defaultVal = ColumnDef.DefaultValue.ARRAY_EMPTY_DEFAULT_VALUE;
         }
-        return new ColumnDef(tColumnDesc.getColumnName(), typeDef, false, 
null, isAllowNull, defaultVal,
-                comment, true);
+        return new ColumnDef(tColumnDesc.getColumnName(), typeDef, false, 
null, isAllowNull, false,
+            defaultVal, comment, true);
     }
 
     @Override
diff --git a/fe/fe-core/src/main/jflex/sql_scanner.flex 
b/fe/fe-core/src/main/jflex/sql_scanner.flex
index 1e7f99da11..5c228844b1 100644
--- a/fe/fe-core/src/main/jflex/sql_scanner.flex
+++ b/fe/fe-core/src/main/jflex/sql_scanner.flex
@@ -106,6 +106,7 @@ import org.apache.doris.qe.SqlModeHelper;
         keywordMap.put("anti", new Integer(SqlParserSymbols.KW_ANTI));
         keywordMap.put("append", new Integer(SqlParserSymbols.KW_APPEND));
         keywordMap.put("array", new Integer(SqlParserSymbols.KW_ARRAY));
+        keywordMap.put("auto_increment", new 
Integer(SqlParserSymbols.KW_AUTO_INCREMENT));
         keywordMap.put("as", new Integer(SqlParserSymbols.KW_AS));
         keywordMap.put("asc", new Integer(SqlParserSymbols.KW_ASC));
         keywordMap.put("authors", new Integer(SqlParserSymbols.KW_AUTHORS));
diff --git 
a/regression-test/data/data_model_p0/duplicate/storage/test_dup_table_auto_inc_col.out
 
b/regression-test/data/data_model_p0/duplicate/storage/test_dup_table_auto_inc_col.out
new file mode 100644
index 0000000000..053b5f077f
--- /dev/null
+++ 
b/regression-test/data/data_model_p0/duplicate/storage/test_dup_table_auto_inc_col.out
@@ -0,0 +1,29 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !desc --
+id     BIGINT  No      true    \N      AUTO_INCREMENT
+value  INT     No      false   \N      NONE
+
+-- !sql --
+test_dup_tab_auto_inc_col1     CREATE TABLE `test_dup_tab_auto_inc_col1` (\n  
`id` bigint(20) NOT NULL AUTO_INCREMENT,\n  `value` int(11) NOT NULL\n) 
ENGINE=OLAP\nDUPLICATE KEY(`id`)\nCOMMENT 'OLAP'\nDISTRIBUTED BY HASH(`id`) 
BUCKETS 1\nPROPERTIES (\n"replication_allocation" = "tag.location.default: 
1",\n"storage_format" = "V2",\n"light_schema_change" = 
"true",\n"disable_auto_compaction" = 
"false",\n"enable_single_replica_compaction" = "false"\n);
+
+-- !desc --
+id     INT     No      true    \N      
+value  BIGINT  No      false   \N      NONE,AUTO_INCREMENT
+
+-- !sql --
+test_dup_tab_auto_inc_col2     CREATE TABLE `test_dup_tab_auto_inc_col2` (\n  
`id` int(11) NOT NULL,\n  `value` bigint(20) NOT NULL AUTO_INCREMENT\n) 
ENGINE=OLAP\nDUPLICATE KEY(`id`)\nCOMMENT 'OLAP'\nDISTRIBUTED BY HASH(`id`) 
BUCKETS 1\nPROPERTIES (\n"replication_allocation" = "tag.location.default: 
1",\n"storage_format" = "V2",\n"light_schema_change" = 
"true",\n"disable_auto_compaction" = 
"false",\n"enable_single_replica_compaction" = "false"\n);
+
+-- !sql --
+1
+1
+5
+5
+9
+9
+13
+13
+13
+13
+17
+17
+
diff --git 
a/regression-test/suites/data_model_p0/aggregate/test_aggregate_table.groovy 
b/regression-test/suites/data_model_p0/aggregate/test_aggregate_table.groovy
index 9a72174b40..463b548bb5 100644
--- a/regression-test/suites/data_model_p0/aggregate/test_aggregate_table.groovy
+++ b/regression-test/suites/data_model_p0/aggregate/test_aggregate_table.groovy
@@ -99,5 +99,23 @@ suite("test_aggregate_table") {
     qt_desc_date_table """desc date_agg"""
     sql """DROP TABLE date_agg"""
 
+
+    def table_auto_inc = "test_aggregate_tab_with_auto_inc_col"
+    sql "drop table if exists ${table_auto_inc}"
+    test {
+        sql """
+            CREATE TABLE IF NOT EXISTS ${table_auto_inc} (
+                k BIGINT NOT NULL AUTO_INCREMENT,
+                int_value_sum int sum,
+                int_value_max int max,
+                int_value_min int min,
+                int_value_replace int replace,
+                int_value_replace_if_not_null int replace_if_not_null
+            )
+            AGGREGATE KEY(k)
+            DISTRIBUTED BY HASH(k) BUCKETS 5 properties("replication_num" = 
"1");
+        """
+        exception "the auto increment is only supported in duplicate table."
+    }
     // sql "drop database ${dbName}"
 }
diff --git 
a/regression-test/suites/data_model_p0/duplicate/storage/test_dup_table_auto_inc_col.groovy
 
b/regression-test/suites/data_model_p0/duplicate/storage/test_dup_table_auto_inc_col.groovy
new file mode 100644
index 0000000000..c85ab4eda2
--- /dev/null
+++ 
b/regression-test/suites/data_model_p0/duplicate/storage/test_dup_table_auto_inc_col.groovy
@@ -0,0 +1,220 @@
+// 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_dup_table_auto_inc_col") {
+
+    // duplicate table with a auto-increment key column
+    def table1 = "test_dup_tab_auto_inc_col1"
+    sql "drop table if exists ${table1}"
+    sql """
+        CREATE TABLE IF NOT EXISTS `${table1}` (
+          `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "",
+          `value` int(11) NOT NULL COMMENT ""
+        ) ENGINE=OLAP
+        DUPLICATE KEY(`id`)
+        COMMENT "OLAP"
+        DISTRIBUTED BY HASH(`id`) BUCKETS 1
+        PROPERTIES (
+        "replication_allocation" = "tag.location.default: 1",
+        "in_memory" = "false",
+        "storage_format" = "V2"
+        )
+    """
+    qt_desc "desc ${table1}"
+    qt_sql "show create table ${table1};"
+
+    // duplicate table with a auto-increment value column
+    def table2 = "test_dup_tab_auto_inc_col2"
+    sql "drop table if exists ${table2}"
+    sql """
+        CREATE TABLE IF NOT EXISTS `${table2}` (
+          `id` int(11) NOT NULL COMMENT "",
+          `value` BIGINT NOT NULL AUTO_INCREMENT COMMENT ""
+        ) ENGINE=OLAP
+        DUPLICATE KEY(`id`)
+        COMMENT "OLAP"
+        DISTRIBUTED BY HASH(`id`) BUCKETS 1
+        PROPERTIES (
+        "replication_allocation" = "tag.location.default: 1",
+        "in_memory" = "false",
+        "storage_format" = "V2"
+        )
+    """
+    qt_desc "desc ${table2}"
+    qt_sql "show create table ${table2};"
+
+    // duplicate table with two auto-increment columns
+    def table3 = "test_dup_tab_auto_inc_col3"
+    sql "drop table if exists ${table3}"
+    test {
+        sql """
+            CREATE TABLE IF NOT EXISTS `${table3}` (
+              `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT "",
+              `value` BIGINT NOT NULL AUTO_INCREMENT COMMENT ""
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`id`)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`id`) BUCKETS 1
+            PROPERTIES (
+            "replication_allocation" = "tag.location.default: 1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            )
+        """
+        exception "there can be at most one auto increment column in 
OlapTable."
+    }
+
+    // duplicate table with a auto-increment key column
+    // insert values and check query
+    def table4 = "test_dup_tab_basic_int_tab1"
+    sql "drop table if exists ${table4}"
+    sql """
+CREATE TABLE IF NOT EXISTS `${table4}` (
+  `siteid` BIGINT NOT NULL AUTO_INCREMENT COMMENT "",
+  `citycode` int(11) NOT NULL COMMENT "",
+  `userid` int(11) NOT NULL COMMENT "",
+  `pv` int(11) NOT NULL COMMENT ""
+) ENGINE=OLAP
+DUPLICATE KEY(`siteid`)
+COMMENT "OLAP"
+DISTRIBUTED BY HASH(`siteid`) BUCKETS 1
+PROPERTIES (
+"replication_allocation" = "tag.location.default: 1",
+"in_memory" = "false",
+"storage_format" = "V2"
+)
+
+"""
+    sql """insert into ${table4} values
+        (9,10,11,12),
+        (9,10,11,12),
+        (1,2,3,4),
+        (13,21,22,16),
+        (13,14,15,16),
+        (17,18,19,20),
+        (1,2,3,4),
+        (13,21,22,16),
+        (13,14,15,16),
+        (17,18,19,20),
+        (5,6,7,8),
+        (5,6,7,8)
+"""
+    // read key column
+    qt_sql """select siteid from ${table4} order by siteid"""    
+    // read non-key column
+    sql """select citycode from ${table4} order by citycode"""
+    sql "drop table if exists ${table4}"
+
+    // duplicate table with a auto-increment value column
+    // insert values and check query
+    def table5 = "test_dup_tab_basic_int_tab2"
+    sql "drop table if exists ${table5}"
+    sql """
+CREATE TABLE IF NOT EXISTS `${table5}` (
+  `siteid` int(11) NOT NULL COMMENT "",
+  `citycode` BIGINT NOT NULL AUTO_INCREMENT COMMENT "",
+  `userid` int(11) NOT NULL COMMENT "",
+  `pv` int(11) NOT NULL COMMENT ""
+) ENGINE=OLAP
+DUPLICATE KEY(`siteid`)
+COMMENT "OLAP"
+DISTRIBUTED BY HASH(`siteid`) BUCKETS 1
+PROPERTIES (
+"replication_allocation" = "tag.location.default: 1",
+"in_memory" = "false",
+"storage_format" = "V2"
+) """
+    sql """insert into ${table5} values
+        (9,10,11,12),
+        (9,10,11,12),
+        (1,2,3,4),
+        (13,21,22,16),
+        (13,14,15,16),
+        (17,18,19,20),
+        (1,2,3,4),
+        (13,21,22,16),
+        (13,14,15,16),
+        (17,18,19,20),
+        (5,6,7,8),
+        (5,6,7,8) """
+
+    // read key column
+    sql """select siteid from ${table5} order by siteid"""
+
+    // read non-key column
+    sql """select citycode from ${table5} order by citycode"""
+    sql "drop table if exists ${table5}"
+
+    def table_check = "test_dup_tab_auto_inc_col_check"
+    sql "drop table if exists ${table_check}"
+
+    test {
+        sql """
+            CREATE TABLE IF NOT EXISTS `${table_check}` (
+              `id` BIGINT AUTO_INCREMENT COMMENT "",
+              `value` int(11) NOT NULL COMMENT ""
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`id`)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`id`) BUCKETS 1
+            PROPERTIES (
+            "replication_allocation" = "tag.location.default: 1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            )
+        """
+        exception "the auto increment column should be NOT NULL."
+    }
+
+    sql "drop table if exists ${table_check}"
+    test {
+        sql """
+            CREATE TABLE IF NOT EXISTS `${table_check}` (
+              `id` VARCHAR NOT NULL AUTO_INCREMENT COMMENT "",
+              `value` int(11) NOT NULL COMMENT ""
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`id`)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`id`) BUCKETS 1
+            PROPERTIES (
+            "replication_allocation" = "tag.location.default: 1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            )
+        """
+        exception "the auto increment must be BIGINT type."
+    }
+
+    sql "drop table if exists ${table_check}"
+    test {
+        sql """
+            CREATE TABLE IF NOT EXISTS `${table_check}` (
+              `id` BIGINT NOT NULL AUTO_INCREMENT DEFAULT "0" COMMENT "",
+              `value` int(11) NOT NULL COMMENT ""
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`id`)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`id`) BUCKETS 1
+            PROPERTIES (
+            "replication_allocation" = "tag.location.default: 1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            )
+        """
+        exception "the auto increment column can't have default value."
+    }
+}
\ No newline at end of file
diff --git 
a/regression-test/suites/data_model_p0/unique/test_unique_table.groovy 
b/regression-test/suites/data_model_p0/unique/test_unique_table.groovy
index eb9bd2b57d..f3fdc71bde 100644
--- a/regression-test/suites/data_model_p0/unique/test_unique_table.groovy
+++ b/regression-test/suites/data_model_p0/unique/test_unique_table.groovy
@@ -42,4 +42,20 @@ suite("test_unique_table") {
     order_qt_select_uniq_table "select * from ${tbName}"
     qt_desc_uniq_table "desc ${tbName}"
     sql "DROP TABLE ${tbName}"
+
+    def table_auto_inc = "test_aggregate_tab_with_auto_inc_col"
+    sql "drop table if exists ${table_auto_inc}"
+    test {
+        sql """
+            CREATE TABLE IF NOT EXISTS ${table_auto_inc} (
+                k BIGINT NOT NULL AUTO_INCREMENT,
+                int_value int,
+                char_value char(10),
+                date_value date
+            )
+            UNIQUE KEY(k)
+            DISTRIBUTED BY HASH(k) BUCKETS 5 properties("replication_num" = 
"1");
+        """
+        exception "the auto increment is only supported in duplicate table."
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to