You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ca...@apache.org on 2024/04/19 16:04:52 UTC

(iotdb) branch ty/TableModelGrammar updated: support select time column

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

caogaofei 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 651c5798648 support select time column
651c5798648 is described below

commit 651c579864865266b43e8f5f385c70d1dd3008f7
Author: Beyyes <cg...@foxmail.com>
AuthorDate: Sat Apr 20 00:04:36 2024 +0800

    support select time column
---
 .../source/relational/TableScanOperator.java       |  2 ++
 .../relational/ColumnTransformerBuilder.java       | 19 +++++++++----
 .../plan/planner/TableOperatorGenerator.java       | 28 ++++++++++++------
 .../relational/analyzer/StatementAnalyzer.java     | 33 +++++++++++++---------
 .../plan/relational/planner/LogicalPlanner.java    |  7 +++--
 .../plan/relational/planner/RelationPlanner.java   |  4 ---
 .../distribute/RelationalDistributionPlanner.java  | 16 +++++++++++
 7 files changed, 75 insertions(+), 34 deletions(-)

diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/TableScanOperator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/TableScanOperator.java
index 80eb310db1a..8449df18d42 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/TableScanOperator.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/TableScanOperator.java
@@ -323,6 +323,8 @@ public class TableScanOperator extends AbstractDataSourceOperator {
     for (ColumnSchema columnSchema : columnSchemas) {
       if (columnSchema.getColumnCategory() != TsTableColumnCategory.TIME) {
         resultDataTypes.add(getTSDataType(columnSchema.getType()));
+      } else {
+        throw new IllegalArgumentException("Should not have TimeColumnSchema");
       }
     }
     return resultDataTypes;
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
index ca90eff8dc0..5fa9a39146a 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
@@ -39,6 +39,7 @@ import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.ConstantCo
 import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.IdentityColumnTransformer;
 import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.LeafColumnTransformer;
 import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.NullColumnTransformer;
+import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.TimeColumnTransformer;
 import org.apache.iotdb.db.queryengine.transformation.dag.column.multi.LogicalAndMultiColumnTransformer;
 import org.apache.iotdb.db.queryengine.transformation.dag.column.multi.LogicalOrMultiColumnTransformer;
 import org.apache.iotdb.db.queryengine.transformation.dag.column.unary.ArithmeticNegationColumnTransformer;
@@ -578,12 +579,18 @@ public class ColumnTransformerBuilder
         context.cache.computeIfAbsent(
             node,
             e -> {
-              IdentityColumnTransformer identity =
-                  new IdentityColumnTransformer(
-                      context.getType(node),
-                      context.inputLocations.get(Symbol.from(node)).get(0).getValueColumnIndex());
-              context.leafList.add(identity);
-              return identity;
+              int valueIdx =
+                  context.inputLocations.get(Symbol.from(node)).get(0).getValueColumnIndex();
+              LeafColumnTransformer leafColumnTransformer;
+              if (valueIdx == -1) {
+                leafColumnTransformer = new TimeColumnTransformer(INT64);
+              } else {
+                leafColumnTransformer =
+                    new IdentityColumnTransformer(context.getType(node), valueIdx);
+              }
+
+              context.leafList.add(leafColumnTransformer);
+              return leafColumnTransformer;
             });
     res.addReferenceCount();
     return res;
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
index 2c1c431f096..ecc601a651e 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java
@@ -140,27 +140,31 @@ public class TableOperatorGenerator extends PlanVisitor<Operator, LocalExecution
     List<String> measurementColumnNames = new ArrayList<>();
     List<IMeasurementSchema> measurementSchemas = new ArrayList<>();
     int measurementColumnCount = 0;
-    for (int i = 0; i < outputColumnCount; i++) {
-      Symbol columnName = outputColumnNames.get(i);
+    int idx = 0;
+    boolean hasTimeColumn = false;
+    for (Symbol columnName : outputColumnNames) {
       ColumnSchema schema =
           requireNonNull(columnSchemaMap.get(columnName), columnName + " is null");
-      columnSchemas.add(schema);
+
       switch (schema.getColumnCategory()) {
         case ID:
         case ATTRIBUTE:
-          columnsIndexArray[i] =
+          columnsIndexArray[idx++] =
               requireNonNull(
                   idAndAttributeColumnsIndexMap.get(columnName), columnName + " is null");
+          columnSchemas.add(schema);
           break;
         case MEASUREMENT:
-          columnsIndexArray[i] = measurementColumnCount;
+          columnsIndexArray[idx++] = measurementColumnCount;
           measurementColumnCount++;
           measurementColumnNames.add(columnName.getName());
           measurementSchemas.add(
               new MeasurementSchema(schema.getName(), getTSDataType(schema.getType())));
+          columnSchemas.add(schema);
           break;
         case TIME:
-          columnsIndexArray[i] = -1;
+          hasTimeColumn = true;
+          // columnsIndexArray[i] = -1;
           break;
         default:
           throw new IllegalArgumentException(
@@ -168,6 +172,11 @@ public class TableOperatorGenerator extends PlanVisitor<Operator, LocalExecution
       }
     }
 
+    int[] newColumnsIndexArray = new int[outputColumnCount - 1];
+    if (hasTimeColumn) {
+      System.arraycopy(columnsIndexArray, 0, newColumnsIndexArray, 0, outputColumnCount - 1);
+    }
+
     SeriesScanOptions.Builder scanOptionsBuilder = getSeriesScanOptionsBuilder(context);
     scanOptionsBuilder.withPushDownLimit(node.getPushDownLimit());
     scanOptionsBuilder.withPushDownOffset(node.getPushDownOffset());
@@ -201,7 +210,7 @@ public class TableOperatorGenerator extends PlanVisitor<Operator, LocalExecution
             operatorContext,
             node.getPlanNodeId(),
             columnSchemas,
-            columnsIndexArray,
+            newColumnsIndexArray,
             measurementColumnCount,
             node.getDeviceEntries(),
             node.getScanOrder(),
@@ -476,7 +485,10 @@ public class TableOperatorGenerator extends PlanVisitor<Operator, LocalExecution
     return constructFilterAndProjectOperator(
         predicate,
         inputOperator,
-        node.getOutputSymbols().stream().map(Symbol::toSymbolReference).toArray(Expression[]::new),
+        node.getOutputSymbols().stream()
+            .filter(e -> !TIMESTAMP_EXPRESSION_STRING.equalsIgnoreCase(e.getName()))
+            .map(Symbol::toSymbolReference)
+            .toArray(Expression[]::new),
         inputDataTypes,
         inputLocations,
         node.getPlanNodeId(),
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 0a6d6ae1834..186150009d8 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
@@ -879,20 +879,25 @@ public class StatementAnalyzer {
           });
 
       // TODO Auth control
-      //      tableFieldsMap.asMap().forEach((table, tableFields) -> {
-      //        Set<String> accessibleColumns = accessControl.filterColumns(
-      //                session.toSecurityContext(),
-      //                table.getCatalogName(),
-      //                ImmutableMap.of(
-      //                    table.asSchemaTableName(),
-      //                    tableFields.stream()
-      //                        .map(field -> field.getOriginColumnName().get())
-      //                        .collect(toImmutableSet())))
-      //            .getOrDefault(table.asSchemaTableName(), ImmutableSet.of());
-      //        accessibleFields.addAll(tableFields.stream()
-      //            .filter(field -> accessibleColumns.contains(field.getOriginColumnName().get()))
-      //            .collect(toImmutableList()));
-      //      });
+      tableFieldsMap
+          .asMap()
+          .forEach(
+              (table, tableFields) -> {
+                //              Set<String> accessibleColumns = accessControl.filterColumns(
+                //                      session.toSecurityContext(),
+                //                      table.getCatalogName(),
+                //                      ImmutableMap.of(
+                //                          table.asSchemaTableName(),
+                //                          tableFields.stream()
+                //                              .map(field -> field.getOriginColumnName().get())
+                //                              .collect(toImmutableSet())))
+                //                  .getOrDefault(table.asSchemaTableName(), ImmutableSet.of());
+                accessibleFields.addAll(
+                    tableFields.stream()
+                        // .filter(field ->
+                        // accessibleColumns.contains(field.getOriginColumnName().get()))
+                        .collect(toImmutableList()));
+              });
 
       return fields.stream().filter(accessibleFields.build()::contains).collect(toImmutableList());
     }
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java
index 2eb3f4e12d9..0669b701c96 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/LogicalPlanner.java
@@ -108,9 +108,11 @@ public class LogicalPlanner {
     RelationType outputDescriptor = analysis.getOutputDescriptor();
     for (Field field : outputDescriptor.getVisibleFields()) {
       String name = field.getName().orElse("_col" + columnNumber);
-      names.add(name);
-      columnHeaders.add(new ColumnHeader(name, transferTypeToTsDataType(field.getType())));
+      if (!"time".equalsIgnoreCase(name)) {
+        columnHeaders.add(new ColumnHeader(name, transferTypeToTsDataType(field.getType())));
+      }
 
+      names.add(name);
       int fieldIndex = outputDescriptor.indexOf(field);
       Symbol symbol = plan.getSymbol(fieldIndex);
       outputs.add(symbol);
@@ -124,6 +126,7 @@ public class LogicalPlanner {
 
     DatasetHeader respDatasetHeader = new DatasetHeader(columnHeaders, false);
     analysis.setRespDatasetHeader(respDatasetHeader);
+
     return outputNode;
   }
 
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 e04458cb38a..50c33ee6c58 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
@@ -98,10 +98,6 @@ public class RelationPlanner extends AstVisitor<RelationPlan, Void> {
     Collection<Field> fields = scope.getRelationType().getAllFields();
     int IDIdx = 0, attributeIdx = 0;
     for (Field field : fields) {
-      if ("time".equalsIgnoreCase(field.getName().get())) {
-        // TODO consider time ColumnCategory
-        continue;
-      }
       Symbol symbol = symbolAllocator.newSymbol(field);
       outputSymbolsBuilder.add(symbol);
       symbolToColumnSchema.put(
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/RelationalDistributionPlanner.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/RelationalDistributionPlanner.java
index 45ece8cae71..e3cd4e9f8e6 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/RelationalDistributionPlanner.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/RelationalDistributionPlanner.java
@@ -23,9 +23,14 @@ import org.apache.iotdb.db.queryengine.plan.planner.plan.SubPlan;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
 import org.apache.iotdb.db.queryengine.plan.planner.plan.node.sink.IdentitySinkNode;
 import org.apache.iotdb.db.queryengine.plan.relational.analyzer.Analysis;
+import org.apache.iotdb.db.queryengine.plan.relational.planner.Symbol;
+import org.apache.iotdb.db.relational.sql.tree.Query;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.apache.iotdb.db.queryengine.plan.expression.leaf.TimestampOperand.TIMESTAMP_EXPRESSION_STRING;
 
 public class RelationalDistributionPlanner {
   private final Analysis analysis;
@@ -50,6 +55,17 @@ public class RelationalDistributionPlanner {
       throw new IllegalStateException("root node must return only one");
     }
 
+    PlanNode outputNode = distributedPlanNodeResult.get(0);
+    if (analysis.getStatement() != null && analysis.getStatement() instanceof Query) {
+      analysis
+          .getRespDatasetHeader()
+          .setColumnToTsBlockIndexMap(
+              outputNode.getOutputSymbols().stream()
+                  .map(Symbol::getName)
+                  .filter(e -> !TIMESTAMP_EXPRESSION_STRING.equalsIgnoreCase(e))
+                  .collect(Collectors.toList()));
+    }
+
     SubPlan subPlan = new SubPlanGenerator().splitToSubPlan(logicalQueryPlan);
     subPlan.getPlanFragment().setRoot(true);