This is an automated email from the ASF dual-hosted git repository. caogaofei pushed a commit to branch beyyes/alias in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 7b4c455d241d26dabc5b918c85ab634a5bfa4d92 Author: Beyyes <[email protected]> AuthorDate: Mon Aug 12 18:15:12 2024 +0800 add AliasRelation impl --- .../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()) {
