This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch ty/TableModelGrammar
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/ty/TableModelGrammar by this
push:
new 875f5037eda fix compile
875f5037eda is described below
commit 875f5037eda5680945b8a8e60dd548343637f0d6
Author: JackieTien97 <[email protected]>
AuthorDate: Wed Feb 28 12:23:10 2024 +0800
fix compile
---
.../relational/analyzer/AggregationAnalyzer.java | 6 +
.../relational/analyzer/StatementAnalyzer.java | 175 ++++++++++++---------
.../db/relational/grammar/sql/RelationalSql.g4 | 2 +
.../iotdb/db/relational/sql/parser/AstBuilder.java | 6 +
.../iotdb/db/relational/sql/tree/AstVisitor.java | 4 +
.../sql/tree/DefaultTraversalVisitor.java | 8 +
.../apache/iotdb/db/relational/sql/tree/Row.java | 77 +++++++++
.../iotdb/tsfile/read/common/type/BinaryType.java | 10 +-
.../iotdb/tsfile/read/common/type/BooleanType.java | 8 +
.../iotdb/tsfile/read/common/type/DoubleType.java | 8 +
.../iotdb/tsfile/read/common/type/FloatType.java | 10 +-
.../iotdb/tsfile/read/common/type/IntType.java | 10 +-
.../iotdb/tsfile/read/common/type/LongType.java | 10 +-
.../iotdb/tsfile/read/common/type/RowType.java | 147 +++++++++++++++++
.../apache/iotdb/tsfile/read/common/type/Type.java | 5 +
.../iotdb/tsfile/read/common/type/TypeEnum.java | 4 +-
16 files changed, 409 insertions(+), 81 deletions(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AggregationAnalyzer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AggregationAnalyzer.java
index b1a642d95e5..48aa4ea7890 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AggregationAnalyzer.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AggregationAnalyzer.java
@@ -48,6 +48,7 @@ import org.apache.iotdb.db.relational.sql.tree.NotExpression;
import org.apache.iotdb.db.relational.sql.tree.NullIfExpression;
import org.apache.iotdb.db.relational.sql.tree.Parameter;
import org.apache.iotdb.db.relational.sql.tree.QuantifiedComparisonExpression;
+import org.apache.iotdb.db.relational.sql.tree.Row;
import org.apache.iotdb.db.relational.sql.tree.SearchedCaseExpression;
import org.apache.iotdb.db.relational.sql.tree.SimpleCaseExpression;
import org.apache.iotdb.db.relational.sql.tree.SubqueryExpression;
@@ -418,6 +419,11 @@ class AggregationAnalyzer {
return !node.getDefaultValue().isPresent() ||
process(node.getDefaultValue().get(), context);
}
+ @Override
+ protected Boolean visitRow(Row node, Void context) {
+ return node.getItems().stream().allMatch(item -> process(item, context));
+ }
+
@Override
protected Boolean visitParameter(Parameter node, Void context) {
// if (analysis.isDescribe()) {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
index 26a4d9b8c8c..89628784651 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
@@ -76,6 +76,7 @@ import
org.apache.iotdb.db.relational.sql.tree.QuerySpecification;
import org.apache.iotdb.db.relational.sql.tree.Relation;
import org.apache.iotdb.db.relational.sql.tree.RenameColumn;
import org.apache.iotdb.db.relational.sql.tree.RenameTable;
+import org.apache.iotdb.db.relational.sql.tree.Row;
import org.apache.iotdb.db.relational.sql.tree.Select;
import org.apache.iotdb.db.relational.sql.tree.SelectItem;
import org.apache.iotdb.db.relational.sql.tree.SetOperation;
@@ -94,8 +95,10 @@ import org.apache.iotdb.db.relational.sql.tree.TableSubquery;
import org.apache.iotdb.db.relational.sql.tree.Union;
import org.apache.iotdb.db.relational.sql.tree.Update;
import org.apache.iotdb.db.relational.sql.tree.Use;
+import org.apache.iotdb.db.relational.sql.tree.Values;
import org.apache.iotdb.db.relational.sql.tree.With;
import org.apache.iotdb.db.relational.sql.tree.WithQuery;
+import org.apache.iotdb.tsfile.read.common.type.RowType;
import org.apache.iotdb.tsfile.read.common.type.Type;
import com.google.common.collect.ArrayListMultimap;
@@ -127,6 +130,7 @@ import static
com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.Iterables.getLast;
+import static com.google.common.collect.Iterables.getOnlyElement;
import static java.lang.Math.toIntExact;
import static java.util.Collections.emptyList;
import static java.util.Locale.ENGLISH;
@@ -1588,82 +1592,101 @@ public class StatementAnalyzer {
// accessControlScope, filter));
// }
- // @Override
- // protected Scope visitValues(Values node, Optional<Scope> scope) {
- // checkState(!node.getRows().isEmpty());
- //
- // List<Type> rowTypes = node.getRows().stream()
- // .map(row -> analyzeExpression(row,
createScope(scope)).getType(row))
- // .map(type -> {
- // if (type instanceof RowType) {
- // return type;
- // }
- // return RowType.anonymousRow(type);
- // })
- // .collect(toImmutableList());
- //
- // int fieldCount = rowTypes.get(0).getTypeParameters().size();
- // Type commonSuperType = rowTypes.get(0);
- // for (Type rowType : rowTypes) {
- // // check field count consistency for rows
- // if (rowType.getTypeParameters().size() != fieldCount) {
- // throw semanticException(TYPE_MISMATCH,
- // node,
- // "Values rows have mismatched sizes: %s vs %s",
- // fieldCount,
- // rowType.getTypeParameters().size());
- // }
- //
- // // determine common super type of the rows
- // commonSuperType = typeCoercion.getCommonSuperType(rowType,
commonSuperType)
- // .orElseThrow(() -> semanticException(TYPE_MISMATCH,
- // node,
- // "Values rows have mismatched types: %s vs %s",
- // rowTypes.get(0),
- // rowType));
- // }
- //
- // // add coercions
- // for (Expression row : node.getRows()) {
- // Type actualType = analysis.getType(row);
- // if (row instanceof Row) {
- // // coerce Row by fields to preserve Row structure and enable
optimizations based on
- // this structure, e.g. pruning, predicate extraction
- // // TODO coerce the whole Row and add an Optimizer rule that
converts CAST(ROW(...)
- // AS ...) into ROW(CAST(...), CAST(...), ...).
- // // The rule would also handle Row-type expressions that were
specified as
- // CAST(ROW). It should support multiple casts over a ROW.
- // for (int i = 0; i < actualType.getTypeParameters().size();
i++) {
- // Expression item = ((Row) row).getItems().get(i);
- // Type actualItemType = actualType.getTypeParameters().get(i);
- // Type expectedItemType =
commonSuperType.getTypeParameters().get(i);
- // if (!actualItemType.equals(expectedItemType)) {
- // analysis.addCoercion(item, expectedItemType,
- // typeCoercion.isTypeOnlyCoercion(actualItemType,
expectedItemType));
- // }
- // }
- // } else if (actualType instanceof RowType) {
- // // coerce row-type expression as a whole
- // if (!actualType.equals(commonSuperType)) {
- // analysis.addCoercion(row, commonSuperType,
- // typeCoercion.isTypeOnlyCoercion(actualType, commonSuperType));
- // }
- // } else {
- // // coerce field. it will be wrapped in Row by Planner
- // Type superType =
getOnlyElement(commonSuperType.getTypeParameters());
- // if (!actualType.equals(superType)) {
- // analysis.addCoercion(row, superType,
typeCoercion.isTypeOnlyCoercion(actualType,
- // superType));
- // }
- // }
- // }
- //
- // List<Field> fields = commonSuperType.getTypeParameters().stream()
- // .map(valueType -> Field.newUnqualified(Optional.empty(),
valueType))
- // .collect(toImmutableList());
- //
- // return createAndAssignScope(node, scope, fields);
- // }
+ @Override
+ protected Scope visitValues(Values node, Optional<Scope> scope) {
+ checkState(!node.getRows().isEmpty());
+
+ List<Type> rowTypes =
+ node.getRows().stream()
+ .map(row -> analyzeExpression(row,
createScope(scope)).getType(row))
+ .map(
+ type -> {
+ if (type instanceof RowType) {
+ return type;
+ }
+ return RowType.anonymousRow(type);
+ })
+ .collect(toImmutableList());
+
+ int fieldCount = rowTypes.get(0).getTypeParameters().size();
+ Type commonSuperType = rowTypes.get(0);
+ for (Type rowType : rowTypes) {
+ // check field count consistency for rows
+ if (rowType.getTypeParameters().size() != fieldCount) {
+ throw new SemanticException(
+ String.format(
+ "Values rows have mismatched sizes: %s vs %s",
+ fieldCount, rowType.getTypeParameters().size()));
+ }
+
+ // determine common super type of the rows
+ // commonSuperType = typeCoercion.getCommonSuperType(rowType,
commonSuperType)
+ // .orElseThrow(() -> semanticException(TYPE_MISMATCH,
+ // node,
+ // "Values rows have mismatched types: %s vs %s",
+ // rowTypes.get(0),
+ // rowType));
+ }
+
+ // add coercions
+ int rowIndex = 0;
+ for (Expression row : node.getRows()) {
+ Type actualType = analysis.getType(row);
+ if (row instanceof Row) {
+ // coerce Row by fields to preserve Row structure and enable
optimizations based on this
+ // structure, e.g.pruning, predicate extraction
+ // TODO coerce the whole Row and add an Optimizer rule that converts
CAST(ROW(...) AS
+ // ...)into ROW (CAST(...),CAST(...), ...).
+ // The rule would also handle Row-type expressions that were
specified as CAST(ROW).It
+ // should support multiple casts over a ROW.
+ for (int i = 0; i < actualType.getTypeParameters().size(); i++) {
+ // Expression item = ((Row) row).getItems().get(i);
+ Type actualItemType = actualType.getTypeParameters().get(i);
+ Type expectedItemType = commonSuperType.getTypeParameters().get(i);
+ if (!actualItemType.equals(expectedItemType)) {
+ throw new SemanticException(
+ String.format(
+ "Type of row %d column %d is mismatched, expected: %s,
actual: %s",
+ rowIndex, i, expectedItemType, actualItemType));
+ // analysis.addCoercion(item, expectedItemType,
+ //
typeCoercion.isTypeOnlyCoercion(actualItemType,
+ // expectedItemType));
+ }
+ }
+ } else if (actualType instanceof RowType) {
+ // coerce row-type expression as a whole
+ // if (!actualType.equals(commonSuperType)) {
+ // analysis.addCoercion(row, commonSuperType,
+ // typeCoercion.isTypeOnlyCoercion(actualType,
commonSuperType));
+ // }
+
+ throw new SemanticException(
+ String.format(
+ "Type of row %d is mismatched, expected: %s, actual: %s",
+ rowIndex, commonSuperType, actualType));
+ } else {
+ // coerce field. it will be wrapped in Row by Planner
+ Type superType = getOnlyElement(commonSuperType.getTypeParameters());
+ if (!actualType.equals(superType)) {
+ // analysis.addCoercion(row, superType,
+ // typeCoercion.isTypeOnlyCoercion(actualType,
+ // superType));
+ throw new SemanticException(
+ String.format(
+ "Type of row %d is mismatched, expected: %s, actual: %s",
+ rowIndex, superType, actualType));
+ }
+ }
+ rowIndex++;
+ }
+
+ List<Field> fields =
+ commonSuperType.getTypeParameters().stream()
+ .map(valueType -> Field.newUnqualified(Optional.empty(),
valueType))
+ .collect(toImmutableList());
+
+ return createAndAssignScope(node, scope, fields);
+ }
@Override
protected Scope visitAliasedRelation(AliasedRelation relation,
Optional<Scope> scope) {
diff --git
a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
index 84e4fea8301..880ab455df7 100644
---
a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
+++
b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4
@@ -543,6 +543,8 @@ valueExpression
primaryExpression
: literalExpression
#literal
+ | '(' expression (',' expression)+ ')'
#rowConstructor
+ | ROW '(' expression (',' expression)* ')'
#rowConstructor
| qualifiedName '(' (label=identifier '.')? ASTERISK ')'
#functionCall
| qualifiedName '(' (setQuantifier? expression (',' expression)*)?')'
#functionCall
| '(' query ')'
#subqueryExpression
diff --git
a/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/parser/AstBuilder.java
b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/parser/AstBuilder.java
index 65ad32a3ef2..7fbc148ffdb 100644
---
a/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/parser/AstBuilder.java
+++
b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/parser/AstBuilder.java
@@ -95,6 +95,7 @@ import
org.apache.iotdb.db.relational.sql.tree.QuerySpecification;
import org.apache.iotdb.db.relational.sql.tree.Relation;
import org.apache.iotdb.db.relational.sql.tree.RenameColumn;
import org.apache.iotdb.db.relational.sql.tree.RenameTable;
+import org.apache.iotdb.db.relational.sql.tree.Row;
import org.apache.iotdb.db.relational.sql.tree.SearchedCaseExpression;
import org.apache.iotdb.db.relational.sql.tree.Select;
import org.apache.iotdb.db.relational.sql.tree.SelectItem;
@@ -1151,6 +1152,11 @@ public class AstBuilder extends
RelationalSqlBaseVisitor<Node> {
return visit(ctx.expression());
}
+ @Override
+ public Node visitRowConstructor(RelationalSqlParser.RowConstructorContext
context) {
+ return new Row(getLocation(context), visit(context.expression(),
Expression.class));
+ }
+
@Override
public Node visitCast(RelationalSqlParser.CastContext ctx) {
return new Cast(
diff --git
a/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/tree/AstVisitor.java
b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/tree/AstVisitor.java
index 553e4860f89..5622b964657 100644
---
a/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/tree/AstVisitor.java
+++
b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/tree/AstVisitor.java
@@ -271,6 +271,10 @@ public abstract class AstVisitor<R, C> {
return visitQueryBody(node, context);
}
+ protected R visitRow(Row node, C context) {
+ return visitExpression(node, context);
+ }
+
protected R visitTableSubquery(TableSubquery node, C context) {
return visitQueryBody(node, context);
}
diff --git
a/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/tree/DefaultTraversalVisitor.java
b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/tree/DefaultTraversalVisitor.java
index 8f0f19a4a12..51444fb7f3f 100644
---
a/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/tree/DefaultTraversalVisitor.java
+++
b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/tree/DefaultTraversalVisitor.java
@@ -333,6 +333,14 @@ public abstract class DefaultTraversalVisitor<C> extends
AstVisitor<Void, C> {
return null;
}
+ @Override
+ protected Void visitRow(Row node, C context) {
+ for (Expression expression : node.getItems()) {
+ process(expression, context);
+ }
+ return null;
+ }
+
@Override
protected Void visitTableSubquery(TableSubquery node, C context) {
process(node.getQuery(), context);
diff --git
a/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/tree/Row.java
b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/tree/Row.java
new file mode 100644
index 00000000000..0e37061e81f
--- /dev/null
+++
b/iotdb-core/relational-parser/src/main/java/org/apache/iotdb/db/relational/sql/tree/Row.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+package org.apache.iotdb.db.relational.sql.tree;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Objects;
+
+import static java.util.Objects.requireNonNull;
+
+public class Row extends Expression {
+ private final List<Expression> items;
+
+ public Row(List<Expression> items) {
+ super(null);
+ this.items = ImmutableList.copyOf(requireNonNull(items, "items is null"));
+ }
+
+ public Row(NodeLocation location, List<Expression> items) {
+ super(requireNonNull(location, "location is null"));
+ this.items = ImmutableList.copyOf(requireNonNull(items, "items is null"));
+ }
+
+ public List<Expression> getItems() {
+ return items;
+ }
+
+ @Override
+ public <R, C> R accept(AstVisitor<R, C> visitor, C context) {
+ return visitor.visitRow(this, context);
+ }
+
+ @Override
+ public List<? extends Node> getChildren() {
+ return items;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(items);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ Row other = (Row) obj;
+ return Objects.equals(this.items, other.items);
+ }
+
+ @Override
+ public boolean shallowEquals(Node other) {
+ return sameClass(this, other);
+ }
+}
diff --git
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/BinaryType.java
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/BinaryType.java
index 98e988c38bc..19c9551942e 100644
---
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/BinaryType.java
+++
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/BinaryType.java
@@ -24,8 +24,11 @@ import
org.apache.iotdb.tsfile.read.common.block.column.Column;
import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
import org.apache.iotdb.tsfile.utils.Binary;
+import java.util.Collections;
+import java.util.List;
+
public class BinaryType implements Type {
- private static final BinaryType TEXT = new BinaryType();
+ public static final BinaryType TEXT = new BinaryType();
private BinaryType() {}
@@ -64,6 +67,11 @@ public class BinaryType implements Type {
return true;
}
+ @Override
+ public List<Type> getTypeParameters() {
+ return Collections.emptyList();
+ }
+
public static BinaryType getInstance() {
return TEXT;
}
diff --git
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/BooleanType.java
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/BooleanType.java
index fdb65f8d030..b86ee21f90d 100644
---
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/BooleanType.java
+++
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/BooleanType.java
@@ -23,6 +23,9 @@ import
org.apache.iotdb.tsfile.read.common.block.column.BooleanColumnBuilder;
import org.apache.iotdb.tsfile.read.common.block.column.Column;
import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
+import java.util.Collections;
+import java.util.List;
+
public class BooleanType implements Type {
public static final BooleanType BOOLEAN = new BooleanType();
@@ -64,6 +67,11 @@ public class BooleanType implements Type {
return true;
}
+ @Override
+ public List<Type> getTypeParameters() {
+ return Collections.emptyList();
+ }
+
public static BooleanType getInstance() {
return BOOLEAN;
}
diff --git
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/DoubleType.java
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/DoubleType.java
index 0d64ffef1b7..da4734e8a92 100644
---
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/DoubleType.java
+++
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/DoubleType.java
@@ -23,6 +23,9 @@ import
org.apache.iotdb.tsfile.read.common.block.column.Column;
import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
import org.apache.iotdb.tsfile.read.common.block.column.DoubleColumnBuilder;
+import java.util.Collections;
+import java.util.List;
+
public class DoubleType implements Type {
public static final DoubleType DOUBLE = new DoubleType();
@@ -94,6 +97,11 @@ public class DoubleType implements Type {
return true;
}
+ @Override
+ public List<Type> getTypeParameters() {
+ return Collections.emptyList();
+ }
+
public static DoubleType getInstance() {
return DOUBLE;
}
diff --git
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/FloatType.java
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/FloatType.java
index 96d258f533b..67a9b58be0e 100644
---
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/FloatType.java
+++
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/FloatType.java
@@ -23,9 +23,12 @@ import
org.apache.iotdb.tsfile.read.common.block.column.Column;
import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
import org.apache.iotdb.tsfile.read.common.block.column.FloatColumnBuilder;
+import java.util.Collections;
+import java.util.List;
+
public class FloatType implements Type {
- private static final FloatType FLOAT = new FloatType();
+ public static final FloatType FLOAT = new FloatType();
private FloatType() {}
@@ -94,6 +97,11 @@ public class FloatType implements Type {
return true;
}
+ @Override
+ public List<Type> getTypeParameters() {
+ return Collections.emptyList();
+ }
+
public static FloatType getInstance() {
return FLOAT;
}
diff --git
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/IntType.java
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/IntType.java
index e0108f925d5..a793744e053 100644
---
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/IntType.java
+++
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/IntType.java
@@ -23,9 +23,12 @@ import
org.apache.iotdb.tsfile.read.common.block.column.Column;
import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
import org.apache.iotdb.tsfile.read.common.block.column.IntColumnBuilder;
+import java.util.Collections;
+import java.util.List;
+
public class IntType implements Type {
- private static final IntType INT32 = new IntType();
+ public static final IntType INT32 = new IntType();
private IntType() {}
@@ -94,6 +97,11 @@ public class IntType implements Type {
return true;
}
+ @Override
+ public List<Type> getTypeParameters() {
+ return Collections.emptyList();
+ }
+
public static IntType getInstance() {
return INT32;
}
diff --git
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/LongType.java
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/LongType.java
index 383bc37619f..9ae2a9ccfb8 100644
---
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/LongType.java
+++
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/LongType.java
@@ -23,9 +23,12 @@ import
org.apache.iotdb.tsfile.read.common.block.column.Column;
import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
import org.apache.iotdb.tsfile.read.common.block.column.LongColumnBuilder;
+import java.util.Collections;
+import java.util.List;
+
public class LongType implements Type {
- private static final LongType INT64 = new LongType();
+ public static final LongType INT64 = new LongType();
private LongType() {}
@@ -94,6 +97,11 @@ public class LongType implements Type {
return true;
}
+ @Override
+ public List<Type> getTypeParameters() {
+ return Collections.emptyList();
+ }
+
public static LongType getInstance() {
return INT64;
}
diff --git
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/RowType.java
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/RowType.java
new file mode 100644
index 00000000000..ad8b003169a
--- /dev/null
+++
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/RowType.java
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+package org.apache.iotdb.tsfile.read.common.type;
+
+import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static java.util.Objects.requireNonNull;
+import static org.apache.iotdb.tsfile.read.common.type.TypeEnum.ROW;
+
+public class RowType implements Type {
+
+ private final List<Field> fields;
+ private final List<Type> fieldTypes;
+ private final boolean comparable;
+ private final boolean orderable;
+
+ private RowType(List<Field> originalFields) {
+
+ this.fields = new ArrayList<>(originalFields);
+ this.fieldTypes =
fields.stream().map(Field::getType).collect(Collectors.toList());
+
+ this.comparable = fields.stream().allMatch(field ->
field.getType().isComparable());
+ this.orderable = fields.stream().allMatch(field ->
field.getType().isOrderable());
+ }
+
+ public static RowType from(List<Field> fields) {
+ return new RowType(fields);
+ }
+
+ public static RowType anonymous(List<Type> types) {
+ List<Field> fields =
+ types.stream().map(type -> new Field(Optional.empty(),
type)).collect(Collectors.toList());
+
+ return new RowType(fields);
+ }
+
+ public static RowType rowType(Field... field) {
+ return from(Arrays.asList(field));
+ }
+
+ public static RowType anonymousRow(Type... types) {
+ return anonymous(Arrays.asList(types));
+ }
+
+ // Only RowParametricType.createType should call this method
+ public static RowType createWithTypeSignature(List<Field> fields) {
+ return new RowType(fields);
+ }
+
+ public static Field field(String name, Type type) {
+ return new Field(Optional.of(name), type);
+ }
+
+ public static Field field(Type type) {
+ return new Field(Optional.empty(), type);
+ }
+
+ @Override
+ public ColumnBuilder createColumnBuilder(int expectedEntries) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public TypeEnum getTypeEnum() {
+ return ROW;
+ }
+
+ @Override
+ public String getDisplayName() {
+ // Convert to standard sql name
+ StringBuilder result = new StringBuilder();
+ result.append("ROW").append('(');
+ for (Field field : fields) {
+ String typeDisplayName = field.getType().getDisplayName();
+ if (field.getName().isPresent()) {
+ // TODO: names are already canonicalized, so they should be printed as
delimited identifiers
+ result.append(field.getName().get()).append('
').append(typeDisplayName);
+ } else {
+ result.append(typeDisplayName);
+ }
+ result.append(", ");
+ }
+ result.setLength(result.length() - 2);
+ result.append(')');
+ return result.toString();
+ }
+
+ @Override
+ public List<Type> getTypeParameters() {
+ return fieldTypes;
+ }
+
+ public List<Field> getFields() {
+ return fields;
+ }
+
+ public static class Field {
+ private final Type type;
+ private final Optional<String> name;
+
+ public Field(Optional<String> name, Type type) {
+ this.type = requireNonNull(type, "type is null");
+ this.name = requireNonNull(name, "name is null");
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public Optional<String> getName() {
+ return name;
+ }
+ }
+
+ @Override
+ public boolean isComparable() {
+ return comparable;
+ }
+
+ @Override
+ public boolean isOrderable() {
+ return orderable;
+ }
+}
diff --git
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/Type.java
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/Type.java
index 1babec273aa..864663e96af 100644
---
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/Type.java
+++
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/Type.java
@@ -23,6 +23,8 @@ import
org.apache.iotdb.tsfile.read.common.block.column.Column;
import org.apache.iotdb.tsfile.read.common.block.column.ColumnBuilder;
import org.apache.iotdb.tsfile.utils.Binary;
+import java.util.List;
+
public interface Type {
/** Gets a boolean at {@code position}. */
@@ -111,4 +113,7 @@ public interface Type {
/** True if the type supports compareTo. */
boolean isOrderable();
+
+ /** For parameterized types returns the list of parameters. */
+ List<Type> getTypeParameters();
}
diff --git
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/TypeEnum.java
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/TypeEnum.java
index 83b91495abd..eeacbb14817 100644
---
a/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/TypeEnum.java
+++
b/iotdb-core/tsfile/src/main/java/org/apache/iotdb/tsfile/read/common/type/TypeEnum.java
@@ -30,5 +30,7 @@ public enum TypeEnum {
BOOLEAN,
- BINARY
+ BINARY,
+
+ ROW
}