This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 3369da8f29c Add AliasRelation support
3369da8f29c is described below
commit 3369da8f29c437ea00aaad689dea7a50a791665a
Author: Beyyes <[email protected]>
AuthorDate: Mon Aug 12 20:18:54 2024 +0800
Add AliasRelation support
---
.../it/query/old/orderBy/IoTDBOrderByTableIT.java | 4 +--
.../it/query/old/orderBy/IoTDBStreamSortIT.java | 5 ++++
.../plan/relational/planner/RelationPlanner.java | 29 ++++++++++++++++----
.../plan/relational/planner/TranslationMap.java | 32 ++++++++++++++++++++++
.../relational/planner/ir/ExpressionRewriter.java | 6 ++++
.../planner/ir/ExpressionTreeRewriter.java | 22 +++++++++++++++
6 files changed, 91 insertions(+), 7 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBOrderByTableIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBOrderByTableIT.java
index 85e5c4e39f7..5d9dcc43ee4 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBOrderByTableIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBOrderByTableIT.java
@@ -198,7 +198,7 @@ public class IoTDBOrderByTableIT {
@Test
public void orderByTest1() {
String sql =
- "select Time,num,bigNum,floatNum,str,bool from table0 where
device='d1' order by num";
+ "select Time,num,bigNum,floatNum,str,bool from table0 as t where
t.device='d1' order by t.num";
int[] ans = {2, 1, 0, 7, 8, 5, 9, 4, 3, 6, 10, 11, 13, 12, 14};
testNormalOrderBy(sql, ans);
}
@@ -206,7 +206,7 @@ public class IoTDBOrderByTableIT {
@Test
public void orderByTest2() {
String sql =
- "select Time,num,bigNum,floatNum,str,bool from table0 where
device='d1' order by bigNum,time";
+ "select Time,num,bigNum,floatNum,str,bool from table0 t where
t.device='d1' order by bigNum,t.time";
int[] ans = {13, 11, 10, 3, 1, 5, 4, 7, 9, 8, 2, 12, 0, 6, 14};
testNormalOrderBy(sql, ans);
}
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBStreamSortIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBStreamSortIT.java
index 9414e836b3e..ddcbb3ecabc 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBStreamSortIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/old/orderBy/IoTDBStreamSortIT.java
@@ -175,6 +175,11 @@ public class IoTDBStreamSortIT {
expectedHeader,
retArray,
DATABASE_NAME);
+ tableResultSetEqualTest(
+ "select time,level,attr1,device,num from table0 as t order by level
asc, t.attr1 desc nulls first, t.device desc, time asc",
+ expectedHeader,
+ retArray,
+ DATABASE_NAME);
}
@Test
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
index a1c98cb14fc..960625aaa2b 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
@@ -17,6 +17,7 @@ import
org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
import org.apache.iotdb.db.queryengine.common.QueryId;
import org.apache.iotdb.db.queryengine.common.SessionInfo;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
import
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertRowNode;
import
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.RelationalInsertRowNode;
import
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.RelationalInsertRowsNode;
@@ -179,6 +180,29 @@ public class RelationPlanner extends
AstVisitor<RelationPlan, Void> {
return new RelationPlan(plan.getRoot(), analysis.getScope(node),
plan.getFieldMappings());
}
+ @Override
+ protected RelationPlan visitAliasedRelation(AliasedRelation node, Void
context) {
+ RelationPlan subPlan = process(node.getRelation(), context);
+
+ PlanNode root = subPlan.getRoot();
+ List<Symbol> mappings = subPlan.getFieldMappings();
+
+ if (node.getColumnNames() != null) {
+ ImmutableList.Builder<Symbol> newMappings = ImmutableList.builder();
+
+ // Adjust the mappings to expose only the columns visible in the scope
of the aliased relation
+ for (int i = 0; i < subPlan.getDescriptor().getAllFieldCount(); i++) {
+ if (!subPlan.getDescriptor().getFieldByIndex(i).isHidden()) {
+ newMappings.add(subPlan.getFieldMappings().get(i));
+ }
+ }
+
+ mappings = newMappings.build();
+ }
+
+ return new RelationPlan(root, analysis.getScope(node), mappings);
+ }
+
// ================================ Implemented later
=====================================
@Override
@@ -196,11 +220,6 @@ public class RelationPlanner extends
AstVisitor<RelationPlan, Void> {
throw new IllegalStateException("Join is not supported in current
version.");
}
- @Override
- protected RelationPlan visitAliasedRelation(AliasedRelation node, Void
context) {
- throw new IllegalStateException("AliasedRelation is not supported in
current version.");
- }
-
@Override
protected RelationPlan visitIntersect(Intersect node, Void context) {
throw new IllegalStateException("Intersect is not supported in current
version.");
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TranslationMap.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TranslationMap.java
index aa29710a20b..2cc4126027e 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TranslationMap.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/TranslationMap.java
@@ -19,6 +19,7 @@ import
org.apache.iotdb.db.queryengine.plan.relational.analyzer.ResolvedField;
import org.apache.iotdb.db.queryengine.plan.relational.analyzer.Scope;
import
org.apache.iotdb.db.queryengine.plan.relational.planner.ir.ExpressionRewriter;
import
org.apache.iotdb.db.queryengine.plan.relational.planner.ir.ExpressionTreeRewriter;
+import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DereferenceExpression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FieldReference;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall;
@@ -41,6 +42,7 @@ import static
com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Verify.verify;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
+import static
org.apache.iotdb.db.queryengine.plan.relational.planner.QueryPlanner.coerceIfNecessary;
import static
org.apache.iotdb.db.queryengine.plan.relational.planner.ScopeAware.scopeAwareKey;
/**
@@ -269,6 +271,36 @@ public class TranslationMap {
return new FunctionCall(node.getName(), node.isDistinct(),
newArguments);
}
+ @Override
+ public Expression rewriteDereferenceExpression(
+ DereferenceExpression node, Void context,
ExpressionTreeRewriter<Void> treeRewriter) {
+ Optional<SymbolReference> mapped = tryGetMapping(node);
+ if (mapped.isPresent()) {
+ return coerceIfNecessary(node, mapped.get());
+ }
+
+ if (analysis.isColumnReference(node)) {
+ return coerceIfNecessary(
+ node,
+ getSymbolForColumn(node)
+ .map(Symbol::toSymbolReference)
+ .orElseThrow(
+ () -> new IllegalStateException(format("No mapping
for %s", node))));
+ } else {
+ throw new IllegalStateException("Subscript is not supported in
current version");
+ }
+ }
+
+ private Expression coerceIfNecessary(Expression original, Expression
rewritten) {
+ // Don't add a coercion for the top-level expression. That depends
on the context the
+ // expression is used, and it's the responsibility of the caller.
+ if (original == expression) {
+ return rewritten;
+ }
+
+ return QueryPlanner.coerceIfNecessary(analysis, original,
rewritten);
+ }
+
@Override
public Expression rewriteLikePredicate(
LikePredicate node, Void context, ExpressionTreeRewriter<Void>
treeRewriter) {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionRewriter.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionRewriter.java
index 7708989645e..13110f43470 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionRewriter.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionRewriter.java
@@ -25,6 +25,7 @@ import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BetweenPredicate;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Cast;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CoalesceExpression;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ComparisonExpression;
+import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DereferenceExpression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FieldReference;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall;
@@ -136,6 +137,11 @@ public class ExpressionRewriter<C> {
return rewriteExpression(node, context, treeRewriter);
}
+ public Expression rewriteDereferenceExpression(
+ DereferenceExpression node, C context, ExpressionTreeRewriter<C>
treeRewriter) {
+ return rewriteExpression(node, context, treeRewriter);
+ }
+
// public Expression rewriteBindExpression(BindExpression node, C context,
// ExpressionTreeRewriter<C> treeRewriter) {
// return rewriteExpression(node, context, treeRewriter);
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionTreeRewriter.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionTreeRewriter.java
index 9e242159c6e..7841d65de1b 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionTreeRewriter.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/ir/ExpressionTreeRewriter.java
@@ -24,6 +24,7 @@ import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.BetweenPredicate;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Cast;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.CoalesceExpression;
import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ComparisonExpression;
+import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DereferenceExpression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FieldReference;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.FunctionCall;
@@ -420,6 +421,27 @@ public final class ExpressionTreeRewriter<C> {
return node;
}
+ @Override
+ public Expression visitDereferenceExpression(DereferenceExpression node,
Context<C> context) {
+ if (!context.isDefaultRewrite()) {
+ Expression result =
+ rewriter.rewriteDereferenceExpression(node, context.get(),
ExpressionTreeRewriter.this);
+ if (result != null) {
+ return result;
+ }
+ }
+
+ Expression base = rewrite(node.getBase(), context.get());
+ if (base != node.getBase()) {
+ if (node.getField().isPresent()) {
+ return new DereferenceExpression(base, node.getField().get());
+ }
+ return new DereferenceExpression((Identifier) base);
+ }
+
+ return node;
+ }
+
@Override
public Expression visitLikePredicate(LikePredicate node, Context<C>
context) {
if (!context.isDefaultRewrite()) {