Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
40ac111
[Feat](nereids) support generated column
feiniaofeiafei May 23, 2024
71b1c8b
[Feat](nereids) support generated column
feiniaofeiafei May 31, 2024
9bd1103
[Feat](nereids) support generated column
feiniaofeiafei May 31, 2024
ef0ef4a
[Feat](nereids) support generated column
feiniaofeiafei May 31, 2024
0409c3f
[Feat](nereids) support generated column
feiniaofeiafei May 31, 2024
f2b99f5
[Feat](nereids) support generated column
feiniaofeiafei Jun 2, 2024
fe4ba69
[Feat](nereids) support generated column
feiniaofeiafei Jun 2, 2024
cff3c30
[Feat](nereids) support generated column
feiniaofeiafei Jun 3, 2024
ec1d9fc
[Feat](nereids) support generated column
feiniaofeiafei Jun 6, 2024
c80e0ad
[Feat](nereids) support generated column
feiniaofeiafei Jun 6, 2024
bfc1f5b
[Feat](nereids) support generated column
feiniaofeiafei Jun 7, 2024
90fc7cf
[Feat](nereids) support generated column
feiniaofeiafei Jun 7, 2024
1df666b
[Feat](nereids) support generated column
feiniaofeiafei Jun 7, 2024
c8a1a18
[Feat](nereids) support generated column
feiniaofeiafei Jun 12, 2024
74faa45
[Feat](nereids) support generated column
feiniaofeiafei Jun 19, 2024
b373e55
[Feat](nereids) support generated column
feiniaofeiafei Jun 20, 2024
fc0efd8
[Feat](nereids) support generated column
feiniaofeiafei Jun 20, 2024
b02f4bc
[Feat](nereids) support generated column
feiniaofeiafei Jun 20, 2024
df1b9f4
[Feat](nereids) support generated column
feiniaofeiafei Jun 21, 2024
49b90e8
[Feat](nereids) support generated column
feiniaofeiafei Jun 21, 2024
f636264
[Feat](nereids) support generated column
feiniaofeiafei Jun 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ AT: 'AT';
AUTHORS: 'AUTHORS';
AUTO: 'AUTO';
AUTO_INCREMENT: 'AUTO_INCREMENT';
ALWAYS: 'ALWAYS';
BACKEND: 'BACKEND';
BACKENDS: 'BACKENDS';
BACKUP: 'BACKUP';
Expand Down Expand Up @@ -276,6 +277,7 @@ FRONTENDS: 'FRONTENDS';
FULL: 'FULL';
FUNCTION: 'FUNCTION';
FUNCTIONS: 'FUNCTIONS';
GENERATED: 'GENERATED';
GENERIC: 'GENERIC';
GLOBAL: 'GLOBAL';
GRANT: 'GRANT';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -585,14 +585,15 @@ columnDef
: colName=identifier type=dataType
KEY?
(aggType=aggTypeDef)?
((GENERATED ALWAYS)? AS LEFT_PAREN generatedExpr=expression RIGHT_PAREN)?
((NOT)? nullable=NULL)?
(AUTO_INCREMENT (LEFT_PAREN autoIncInitValue=number RIGHT_PAREN)?)?
(DEFAULT (nullValue=NULL | INTEGER_VALUE | DECIMAL_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)?
;

indexDefs
: indexes+=indexDef (COMMA indexes+=indexDef)*
;
Expand Down Expand Up @@ -1028,6 +1029,7 @@ nonReserved
| AGG_STATE
| AGGREGATE
| ALIAS
| ALWAYS
| ANALYZED
| ARRAY
| ARRAY_RANGE
Expand Down Expand Up @@ -1142,6 +1144,7 @@ nonReserved
| FREE
| FRONTENDS
| FUNCTION
| GENERATED
| GENERIC
| GLOBAL
| GRAPH
Expand Down
27 changes: 26 additions & 1 deletion fe/fe-core/src/main/cup/sql_parser.cup
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import org.apache.doris.catalog.PrimitiveType;
import org.apache.doris.catalog.ScalarType;
import org.apache.doris.catalog.Type;
import org.apache.doris.catalog.ArrayType;
import org.apache.doris.catalog.GeneratedColumnInfo;
import org.apache.doris.catalog.MapType;
import org.apache.doris.catalog.StructField;
import org.apache.doris.catalog.StructType;
Expand All @@ -62,6 +63,7 @@ import org.apache.doris.resource.workloadschedpolicy.WorkloadActionMeta;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.Optional;
import java.util.stream.Collectors;

import java_cup.runtime.Symbol;
Expand Down Expand Up @@ -261,6 +263,7 @@ terminal String
KW_ALIAS,
KW_ALL,
KW_ALTER,
KW_ALWAYS,
KW_ANALYZE,
KW_AND,
KW_ANTI,
Expand Down Expand Up @@ -408,6 +411,7 @@ terminal String
KW_FULL,
KW_FUNCTION,
KW_FUNCTIONS,
KW_GENERATED,
KW_GENERIC,
KW_GLOBAL,
KW_GRANT,
Expand Down Expand Up @@ -1004,6 +1008,9 @@ nonterminal String stage_name;
nonterminal StageAndPattern stage_and_pattern;
nonterminal List<Expr> copy_select_expr_list;

//genearted column
nonterminal Boolean opt_generated_always;

precedence nonassoc COMMA;
precedence nonassoc STRING_LITERAL;
precedence nonassoc KW_COLUMNS;
Expand Down Expand Up @@ -3968,6 +3975,11 @@ column_definition ::=
ColumnDef columnDef = new ColumnDef(columnName, typeDef, isKey, aggType, nullable_type, autoIncInitValue, defaultValue, comment);
RESULT = columnDef;
:}
| ident:columnName type_def:typeDef opt_is_key:isKey opt_generated_always KW_AS LPAREN expr:expr RPAREN opt_nullable_type:nullable_type opt_comment:comment
{:
ColumnDef columnDef = new ColumnDef(columnName, typeDef, isKey, nullable_type, comment, Optional.of(new GeneratedColumnInfo(null, expr)));
RESULT = columnDef;
:}
;

index_definition ::=
Expand Down Expand Up @@ -7942,7 +7954,16 @@ opt_work ::=
RESULT = null;
:}
;

opt_generated_always ::=
/* empty */
{:
RESULT = null;
:}
| KW_GENERATED KW_ALWAYS
{:
RESULT = null;
:}
;
opt_chain ::=
{:
RESULT = null;
Expand Down Expand Up @@ -7982,6 +8003,8 @@ type_func_name_keyword ::=
keyword ::=
KW_AFTER:id
{: RESULT = id; :}
| KW_ALWAYS:id
{: RESULT = id; :}
| KW_AGGREGATE:id
{: RESULT = id; :}
| KW_ALIAS:id
Expand Down Expand Up @@ -8142,6 +8165,8 @@ keyword ::=
{: RESULT = id; :}
| KW_GLOBAL:id
{: RESULT = id; :}
| KW_GENERATED:id
{: RESULT = id; :}
| KW_GENERIC:id
{: RESULT = id; :}
| KW_GRAPH:id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.doris.analysis.CreateMaterializedViewStmt;
import org.apache.doris.analysis.DropColumnClause;
import org.apache.doris.analysis.DropIndexClause;
import org.apache.doris.analysis.Expr;
import org.apache.doris.analysis.IndexDef;
import org.apache.doris.analysis.ModifyColumnClause;
import org.apache.doris.analysis.ModifyTablePropertiesClause;
Expand All @@ -42,6 +43,7 @@
import org.apache.doris.catalog.DistributionInfo.DistributionInfoType;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.EnvFactory;
import org.apache.doris.catalog.GeneratedColumnInfo;
import org.apache.doris.catalog.HashDistributionInfo;
import org.apache.doris.catalog.Index;
import org.apache.doris.catalog.KeysType;
Expand Down Expand Up @@ -377,6 +379,23 @@ private boolean processDropColumn(DropColumnClause alterClause, OlapTable olapTa
}
}

// generated column check
Map<String, Column> nameToColumn = new HashMap<>();
for (Column c : indexSchemaMap.get(baseIndexId)) {
nameToColumn.put(c.getName(), c);
}
if (null == targetIndexName) {
if (nameToColumn.containsKey(dropColName)) {
Column column = nameToColumn.get(dropColName);
Set<String> generatedColumnsThatReferToThis = column.getGeneratedColumnsThatReferToThis();
if (!generatedColumnsThatReferToThis.isEmpty()) {
throw new DdlException(
"Column '" + dropColName + "' has a generated column dependency on :"
+ generatedColumnsThatReferToThis);
}
}
}

Iterator<Index> it = indexes.iterator();
while (it.hasNext()) {
Index index = it.next();
Expand All @@ -403,6 +422,8 @@ private boolean processDropColumn(DropColumnClause alterClause, OlapTable olapTa
if (column.getName().equalsIgnoreCase(dropColName)) {
baseIter.remove();
found = true;
// find generated column referred column
removeColumnWhenDropGeneratedColumn(column, nameToColumn);
break;
}
}
Expand Down Expand Up @@ -528,6 +549,7 @@ private boolean processModifyColumn(ModifyColumnClause alterClause, OlapTable ol
Map<Long, LinkedList<Column>> indexSchemaMap) throws DdlException {
Column modColumn = alterClause.getColumn();
boolean lightSchemaChange = false;

if (KeysType.AGG_KEYS == olapTable.getKeysType()) {
if (modColumn.isKey() && null != modColumn.getAggregationType()) {
throw new DdlException("Can not assign aggregation method on key column: " + modColumn.getName());
Expand Down Expand Up @@ -784,12 +806,15 @@ private void processReorderColumn(ReorderColumnsClause alterClause, OlapTable ol
if (targetIndexName == null) {
targetIndexName = baseIndexName;
}

long targetIndexId = olapTable.getIndexIdByName(targetIndexName);

LinkedList<Column> newSchema = new LinkedList<Column>();
List<Column> targetIndexSchema = indexSchemaMap.get(targetIndexId);

// When rollup is specified, there is no need to check the order of generated columns.
// When rollup is not specified and the order of baseIndex needs to be modified, the order needs to be checked.
if (alterClause.getRollupName() == null) {
checkOrder(targetIndexSchema, orderedColNames);
}
// check and create new ordered column list
Set<String> colNameSet = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
for (String colName : orderedColNames) {
Expand Down Expand Up @@ -1004,6 +1029,10 @@ private boolean addColumnInternal(OlapTable olapTable, Column newColumn, ColumnP
}
}

if (newColumn.getGeneratedColumnInfo() != null) {
throw new DdlException("Not supporting alter table add generated columns.");
}

/*
* add new column to indexes.
* UNIQUE:
Expand Down Expand Up @@ -3194,4 +3223,61 @@ public boolean updateBinlogConfig(Database db, OlapTable olapTable, List<AlterCl

return false;
}

private void removeColumnWhenDropGeneratedColumn(Column dropColumn, Map<String, Column> nameToColumn) {
GeneratedColumnInfo generatedColumnInfo = dropColumn.getGeneratedColumnInfo();
if (generatedColumnInfo == null) {
return;
}
String dropColName = dropColumn.getName();
Expr expr = generatedColumnInfo.getExpr();
Set<Expr> slotRefsInGeneratedExpr = new HashSet<>();
expr.collect(e -> e instanceof SlotRef, slotRefsInGeneratedExpr);
for (Expr slotRef : slotRefsInGeneratedExpr) {
String name = ((SlotRef) slotRef).getColumnName();
if (!nameToColumn.containsKey(name)) {
continue;
}
Column c = nameToColumn.get(name);
Set<String> sets = c.getGeneratedColumnsThatReferToThis();
sets.remove(dropColName);
}
}

private void checkOrder(List<Column> targetIndexSchema, List<String> orderedColNames) throws DdlException {
Set<String> nameSet = new HashSet<>();
for (Column column : targetIndexSchema) {
if (column.isVisible() && null == column.getGeneratedColumnInfo()) {
nameSet.add(column.getName());
}
}
for (String colName : orderedColNames) {
Column oneCol = null;
for (Column column : targetIndexSchema) {
if (column.getName().equalsIgnoreCase(colName) && column.isVisible()) {
oneCol = column;
break;
}
}
if (oneCol == null) {
throw new DdlException("Column[" + colName + "] not exists");
}
if (null == oneCol.getGeneratedColumnInfo()) {
continue;
}
Expr expr = oneCol.getGeneratedColumnInfo().getExpr();
Set<Expr> slotRefsInGeneratedExpr = new HashSet<>();
expr.collect(e -> e instanceof SlotRef, slotRefsInGeneratedExpr);
for (Expr slotRef : slotRefsInGeneratedExpr) {
String slotName = ((SlotRef) slotRef).getColumnName();
if (!nameSet.contains(slotName)) {
throw new DdlException("The specified column order is incorrect, `" + colName
+ "` should come after `" + slotName
+ "`, because both of them are generated columns, and `"
+ colName + "` refers to `" + slotName + "`.");
}
}
nameSet.add(colName);
}
}
}
Loading