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

(iotdb) branch ty/TableModelGrammar updated: add interface

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 095f86adc68 add interface
095f86adc68 is described below

commit 095f86adc684ff7bfd7a8e3ee2ca904dde2c34b7
Author: JackieTien97 <ja...@gmail.com>
AuthorDate: Tue Apr 16 09:20:37 2024 +0800

    add interface
---
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java |  6 +-
 .../execution/operator/AggregationUtil.java        |  3 +
 .../AbstractSeriesAggregationScanOperator.java     |  3 +
 .../db/queryengine/plan/analyze/Analysis.java      |  2 +-
 .../plan/relational/analyzer/Analysis.java         | 25 +++-----
 .../plan/relational/analyzer/Field.java            | 39 ++++++++++--
 .../plan/relational/analyzer/RelationType.java     |  2 +
 .../plan/relational/analyzer/ResolvedField.java    |  5 ++
 .../relational/analyzer/StatementAnalyzer.java     | 40 ++++++------
 .../plan/relational/metadata/ColumnSchema.java     | 18 +++++-
 .../plan/relational/metadata/DeviceEntry.java      | 43 +++++++++++++
 .../plan/relational/metadata/Metadata.java         | 40 +++++-------
 .../relational/metadata/TableMetadataImpl.java     | 25 +-------
 .../plan/relational/planner/RelationPlanner.java   | 12 +---
 .../relational/planner/node/TableScanNode.java     | 13 ++++
 .../plan/relational/analyzer/AnalyzerTest.java     |  8 +--
 .../plan/relational/analyzer/TestMatadata.java     | 71 +---------------------
 .../apache/iotdb/commons/conf/CommonConfig.java    |  4 +-
 18 files changed, 176 insertions(+), 183 deletions(-)

diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
index 27c07ff6bd0..df068dc3420 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
@@ -423,13 +423,13 @@ public class IoTDBConfig {
   private int avgSeriesPointNumberThreshold = 100000;
 
   /** Enable inner space compaction for sequence files */
-  private boolean enableSeqSpaceCompaction = true;
+  private boolean enableSeqSpaceCompaction = false;
 
   /** Enable inner space compaction for unsequence files */
-  private boolean enableUnseqSpaceCompaction = true;
+  private boolean enableUnseqSpaceCompaction = false;
 
   /** Compact the unsequence files into the overlapped sequence files */
-  private boolean enableCrossSpaceCompaction = true;
+  private boolean enableCrossSpaceCompaction = false;
 
   /** The buffer for sort operation */
   private long sortBufferSize = 1024 * 1024L;
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/AggregationUtil.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/AggregationUtil.java
index 36fd4ca0557..4981b241c90 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/AggregationUtil.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/AggregationUtil.java
@@ -136,11 +136,14 @@ public class AggregationUtil {
     }
 
     TsBlock inputRegion = inputTsBlock.getRegion(0, lastIndexToProcess + 1);
+    int index = -1;
     for (Aggregator aggregator : aggregators) {
+      index++;
       // current agg method has been calculated
       if (aggregator.hasFinalResult()) {
         continue;
       }
+      System.out.println("raw data index: " + index);
       aggregator.processTsBlock(inputRegion, null);
     }
     int lastReadRowIndex = lastIndexToProcess + 1;
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/AbstractSeriesAggregationScanOperator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/AbstractSeriesAggregationScanOperator.java
index 6ee4f0ee98a..f4c1b214c2a 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/AbstractSeriesAggregationScanOperator.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/AbstractSeriesAggregationScanOperator.java
@@ -224,10 +224,13 @@ public abstract class AbstractSeriesAggregationScanOperator extends AbstractData
   }
 
   protected void calcFromStatistics(Statistics timeStatistics, Statistics[] valueStatistics) {
+    int index = -1;
     for (Aggregator aggregator : aggregators) {
+      index++;
       if (aggregator.hasFinalResult()) {
         continue;
       }
+      System.out.println("statistics index: " + index);
       aggregator.processStatistics(timeStatistics, valueStatistics);
     }
   }
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/Analysis.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/Analysis.java
index cf73c743b59..1dc42d10896 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/Analysis.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/Analysis.java
@@ -189,7 +189,7 @@ public class Analysis implements IAnalysis {
   // indicate is there a value filter
   private boolean hasValueFilter = false;
 
-  // a global time predicate used in `initQueryDataSource` and filter push down
+  // a global time predicate used in `initQueryDataSource` and filter push down?
   private Expression globalTimePredicate;
 
   // expression of output column to be calculated
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
index 22fcee512be..3465a6b45d2 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Analysis.java
@@ -23,9 +23,8 @@ import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
 import org.apache.iotdb.db.queryengine.common.header.DatasetHeader;
 import org.apache.iotdb.db.queryengine.plan.analyze.IAnalysis;
-import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnHandle;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName;
-import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableHandle;
+import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableSchema;
 import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl;
 import org.apache.iotdb.db.queryengine.plan.relational.security.Identity;
 import org.apache.iotdb.db.relational.sql.tree.AllColumns;
@@ -126,8 +125,6 @@ public class Analysis implements IAnalysis {
 
   private final Map<NodeRef<Relation>, List<Type>> relationCoercions = new LinkedHashMap<>();
 
-  private final Map<Field, ColumnHandle> columns = new LinkedHashMap<>();
-
   private final Map<NodeRef<QuerySpecification>, List<FunctionCall>> aggregates =
       new LinkedHashMap<>();
   private final Map<NodeRef<OrderBy>, List<Expression>> orderByAggregates = new LinkedHashMap<>();
@@ -292,14 +289,6 @@ public class Analysis implements IAnalysis {
     relationCoercions.put(NodeRef.of(relation), ImmutableList.copyOf(types));
   }
 
-  public void setColumn(Field field, ColumnHandle handle) {
-    columns.put(field, handle);
-  }
-
-  public ColumnHandle getColumn(Field field) {
-    return columns.get(field);
-  }
-
   public Map<NodeRef<Expression>, Type> getCoercions() {
     return unmodifiableMap(coercions);
   }
@@ -444,7 +433,7 @@ public class Analysis implements IAnalysis {
     return subQueries.computeIfAbsent(NodeRef.of(node), key -> new SubqueryAnalysis());
   }
 
-  public TableHandle getTableHandle(Table table) {
+  public TableSchema getTableHandle(Table table) {
     return tables
         .get(NodeRef.of(table))
         .getHandle()
@@ -452,7 +441,7 @@ public class Analysis implements IAnalysis {
             () -> new IllegalArgumentException(format("%s is not a table reference", table)));
   }
 
-  public Collection<TableHandle> getTables() {
+  public Collection<TableSchema> getTables() {
     return tables.values().stream()
         .map(TableEntry::getHandle)
         .filter(Optional::isPresent)
@@ -460,7 +449,7 @@ public class Analysis implements IAnalysis {
         .collect(toImmutableList());
   }
 
-  public void registerTable(Table table, Optional<TableHandle> handle, QualifiedObjectName name) {
+  public void registerTable(Table table, Optional<TableSchema> handle, QualifiedObjectName name) {
     tables.put(NodeRef.of(table), new TableEntry(handle, name));
   }
 
@@ -621,15 +610,15 @@ public class Analysis implements IAnalysis {
   }
 
   private static class TableEntry {
-    private final Optional<TableHandle> handle;
+    private final Optional<TableSchema> handle;
     private final QualifiedObjectName name;
 
-    public TableEntry(Optional<TableHandle> handle, QualifiedObjectName name) {
+    public TableEntry(Optional<TableSchema> handle, QualifiedObjectName name) {
       this.handle = requireNonNull(handle, "handle is null");
       this.name = requireNonNull(name, "name is null");
     }
 
-    public Optional<TableHandle> getHandle() {
+    public Optional<TableSchema> getHandle() {
       return handle;
     }
 
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Field.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Field.java
index e71495c1abb..8efba703e79 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Field.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/Field.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.analyzer;
 
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName;
 import org.apache.iotdb.db.relational.sql.tree.QualifiedName;
 import org.apache.iotdb.tsfile.read.common.type.Type;
@@ -33,10 +34,13 @@ public class Field {
   private final Optional<QualifiedName> relationAlias;
   private final Optional<String> name;
   private final Type type;
+
+  private final TsTableColumnCategory columnCategory;
+
   private final boolean hidden;
   private final boolean aliased;
 
-  public static Field newUnqualified(String name, Type type) {
+  public static Field newUnqualified(String name, Type type, TsTableColumnCategory columnCategory) {
     requireNonNull(name, "name is null");
     requireNonNull(type, "type is null");
 
@@ -44,23 +48,33 @@ public class Field {
         Optional.empty(),
         Optional.of(name),
         type,
+        columnCategory,
         false,
         Optional.empty(),
         Optional.empty(),
         false);
   }
 
-  public static Field newUnqualified(Optional<String> name, Type type) {
+  public static Field newUnqualified(
+      Optional<String> name, Type type, TsTableColumnCategory columnCategory) {
     requireNonNull(name, "name is null");
     requireNonNull(type, "type is null");
 
     return new Field(
-        Optional.empty(), name, type, false, Optional.empty(), Optional.empty(), false);
+        Optional.empty(),
+        name,
+        type,
+        columnCategory,
+        false,
+        Optional.empty(),
+        Optional.empty(),
+        false);
   }
 
   public static Field newUnqualified(
       Optional<String> name,
       Type type,
+      TsTableColumnCategory columnCategory,
       Optional<QualifiedObjectName> originTable,
       Optional<String> originColumn,
       boolean aliased) {
@@ -68,13 +82,15 @@ public class Field {
     requireNonNull(type, "type is null");
     requireNonNull(originTable, "originTable is null");
 
-    return new Field(Optional.empty(), name, type, false, originTable, originColumn, aliased);
+    return new Field(
+        Optional.empty(), name, type, columnCategory, false, originTable, originColumn, aliased);
   }
 
   public static Field newQualified(
       QualifiedName relationAlias,
       Optional<String> name,
       Type type,
+      TsTableColumnCategory columnCategory,
       boolean hidden,
       Optional<QualifiedObjectName> originTable,
       Optional<String> originColumn,
@@ -85,13 +101,21 @@ public class Field {
     requireNonNull(originTable, "originTable is null");
 
     return new Field(
-        Optional.of(relationAlias), name, type, hidden, originTable, originColumn, aliased);
+        Optional.of(relationAlias),
+        name,
+        type,
+        columnCategory,
+        hidden,
+        originTable,
+        originColumn,
+        aliased);
   }
 
   public Field(
       Optional<QualifiedName> relationAlias,
       Optional<String> name,
       Type type,
+      TsTableColumnCategory columnCategory,
       boolean hidden,
       Optional<QualifiedObjectName> originTable,
       Optional<String> originColumnName,
@@ -105,6 +129,7 @@ public class Field {
     this.relationAlias = relationAlias;
     this.name = name;
     this.type = type;
+    this.columnCategory = columnCategory;
     this.hidden = hidden;
     this.originTable = originTable;
     this.originColumnName = originColumnName;
@@ -131,6 +156,10 @@ public class Field {
     return type;
   }
 
+  public TsTableColumnCategory getColumnCategory() {
+    return columnCategory;
+  }
+
   public boolean isHidden() {
     return hidden;
   }
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/RelationType.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/RelationType.java
index fed4bdea8c9..5071f280b6f 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/RelationType.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/RelationType.java
@@ -148,6 +148,7 @@ public class RelationType {
                 QualifiedName.of(relationAlias),
                 columnAlias,
                 field.getType(),
+                field.getColumnCategory(),
                 field.isHidden(),
                 field.getOriginTable(),
                 field.getOriginColumnName(),
@@ -161,6 +162,7 @@ public class RelationType {
                 QualifiedName.of(relationAlias),
                 columnAlias,
                 field.getType(),
+                field.getColumnCategory(),
                 false,
                 field.getOriginTable(),
                 field.getOriginColumnName(),
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ResolvedField.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ResolvedField.java
index 3a2ba5e5a5b..b2d9560e07d 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ResolvedField.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/ResolvedField.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.analyzer;
 
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
 import com.google.errorprone.annotations.Immutable;
@@ -50,6 +51,10 @@ public class ResolvedField {
     return field.getType();
   }
 
+  public TsTableColumnCategory getColumnCategory() {
+    return field.getColumnCategory();
+  }
+
   public Scope getScope() {
     return scope;
   }
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 2f98a73d3f2..0a6d6ae1834 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
@@ -19,15 +19,14 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.analyzer;
 
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
 import org.apache.iotdb.db.queryengine.execution.warnings.IoTDBWarning;
 import org.apache.iotdb.db.queryengine.execution.warnings.WarningCollector;
-import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnHandle;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnSchema;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName;
-import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableHandle;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableSchema;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.ScopeAware;
 import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl;
@@ -115,7 +114,6 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Optional;
 import java.util.OptionalLong;
@@ -945,6 +943,7 @@ public class StatementAnalyzer {
                 field.getRelationAlias(),
                 alias,
                 field.getType(),
+                field.getColumnCategory(),
                 false,
                 field.getOriginTable(),
                 field.getOriginColumnName(),
@@ -1237,6 +1236,7 @@ public class StatementAnalyzer {
                 Field.newUnqualified(
                     name,
                     field.getType(),
+                    field.getColumnCategory(),
                     field.getOriginTable(),
                     field.getOriginColumnName(),
                     false);
@@ -1274,6 +1274,7 @@ public class StatementAnalyzer {
               Field.newUnqualified(
                   field.map(Identifier::getValue),
                   analysis.getType(expression),
+                  TsTableColumnCategory.MEASUREMENT,
                   originTable,
                   originColumn,
                   column.getAlias().isPresent()); // TODO don't use analysis as a side-channel. Use
@@ -1373,6 +1374,7 @@ public class StatementAnalyzer {
                 oldField.getRelationAlias(),
                 oldField.getName(),
                 outputFieldTypes[i],
+                oldField.getColumnCategory(),
                 oldField.isHidden(),
                 oldField.getOriginTable(),
                 oldField.getOriginColumnName(),
@@ -1433,19 +1435,15 @@ public class StatementAnalyzer {
       analysis.setRelationName(
           table, QualifiedName.of(name.getDatabaseName(), name.getObjectName()));
 
-      Optional<TableHandle> tableHandle = metadata.getTableHandle(sessionContext, name);
+      Optional<TableSchema> tableSchema = metadata.getTableSchema(sessionContext, name);
       // This can only be a table
-      if (!tableHandle.isPresent()) {
+      if (!tableSchema.isPresent()) {
         throw new SemanticException(String.format("Table '%s' does not exist", name));
       }
       analysis.addEmptyColumnReferencesForTable(accessControl, sessionContext.getIdentity(), name);
 
-      TableSchema tableSchema = metadata.getTableSchema(sessionContext, tableHandle.get());
-      Map<String, ColumnHandle> columnHandles =
-          metadata.getColumnHandles(sessionContext, tableHandle.get());
-
       ImmutableList.Builder<Field> fields = ImmutableList.builder();
-      fields.addAll(analyzeTableOutputFields(table, name, tableSchema, columnHandles));
+      fields.addAll(analyzeTableOutputFields(table, name, tableSchema.get()));
 
       //      boolean addRowIdColumn = updateKind.isPresent();
       //
@@ -1468,7 +1466,7 @@ public class StatementAnalyzer {
               .build();
       //      analyzeFiltersAndMasks(table, name, new RelationType(outputFields),
       // accessControlScope);
-      analysis.registerTable(table, tableHandle, name);
+      analysis.registerTable(table, tableSchema, name);
 
       Scope tableScope = createAndAssignScope(table, scope, outputFields);
 
@@ -1506,6 +1504,7 @@ public class StatementAnalyzer {
                     QualifiedName.of(table.getName().getSuffix()),
                     Optional.of(aliases.next().getValue()),
                     inputField.getType(),
+                    inputField.getColumnCategory(),
                     false,
                     inputField.getOriginTable(),
                     inputField.getOriginColumnName(),
@@ -1525,6 +1524,7 @@ public class StatementAnalyzer {
                     QualifiedName.of(table.getName().getSuffix()),
                     inputField.getName(),
                     inputField.getType(),
+                    inputField.getColumnCategory(),
                     false,
                     inputField.getOriginTable(),
                     inputField.getOriginColumnName(),
@@ -1540,10 +1540,7 @@ public class StatementAnalyzer {
     }
 
     private List<Field> analyzeTableOutputFields(
-        Table table,
-        QualifiedObjectName tableName,
-        TableSchema tableSchema,
-        Map<String, ColumnHandle> columnHandles) {
+        Table table, QualifiedObjectName tableName, TableSchema tableSchema) {
       // TODO: discover columns lazily based on where they are needed (to support connectors that
       // can't enumerate all tables)
       ImmutableList.Builder<Field> fields = ImmutableList.builder();
@@ -1553,14 +1550,12 @@ public class StatementAnalyzer {
                 table.getName(),
                 Optional.of(column.getName()),
                 column.getType(),
+                column.getColumnCategory(),
                 column.isHidden(),
                 Optional.of(tableName),
                 Optional.of(column.getName()),
                 false);
         fields.add(field);
-        ColumnHandle columnHandle = columnHandles.get(column.getName());
-        checkArgument(columnHandle != null, "Unknown field %s", field);
-        analysis.setColumn(field, columnHandle);
         analysis.addSourceColumns(
             field, ImmutableSet.of(new Analysis.SourceColumn(tableName, column.getName())));
       }
@@ -1681,7 +1676,10 @@ public class StatementAnalyzer {
 
       List<Field> fields =
           commonSuperType.getTypeParameters().stream()
-              .map(valueType -> Field.newUnqualified(Optional.empty(), valueType))
+              .map(
+                  valueType ->
+                      Field.newUnqualified(
+                          Optional.empty(), valueType, TsTableColumnCategory.MEASUREMENT))
               .collect(toImmutableList());
 
       return createAndAssignScope(node, scope, fields);
@@ -1844,7 +1842,9 @@ public class StatementAnalyzer {
 
         analysis.addTypes(ImmutableMap.of(NodeRef.of(column), leftField.getType()));
 
-        joinFields.add(Field.newUnqualified(column.getValue(), leftField.getType()));
+        joinFields.add(
+            Field.newUnqualified(
+                column.getValue(), leftField.getType(), leftField.getColumnCategory()));
 
         leftJoinFields.add(leftField.getRelationFieldIndex());
         rightJoinFields.add(rightField.getRelationFieldIndex());
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/ColumnSchema.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/ColumnSchema.java
index a94ae08651a..3509d5bd98e 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/ColumnSchema.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/ColumnSchema.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.plan.relational.metadata;
 
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
 import java.util.Objects;
@@ -30,13 +31,16 @@ import static java.util.Objects.requireNonNull;
 public class ColumnSchema {
   private final String name;
   private final Type type;
+  private final TsTableColumnCategory columnCategory;
   private final boolean hidden;
 
-  private ColumnSchema(String name, Type type, boolean hidden) {
+  private ColumnSchema(
+      String name, Type type, boolean hidden, TsTableColumnCategory columnCategory) {
     requireNonNull(type, "type is null");
 
     this.name = name.toLowerCase(ENGLISH);
     this.type = type;
+    this.columnCategory = columnCategory;
     this.hidden = hidden;
   }
 
@@ -48,6 +52,10 @@ public class ColumnSchema {
     return type;
   }
 
+  public TsTableColumnCategory getColumnCategory() {
+    return columnCategory;
+  }
+
   public boolean isHidden() {
     return hidden;
   }
@@ -89,6 +97,7 @@ public class ColumnSchema {
   public static class Builder {
     private String name;
     private Type type;
+    private TsTableColumnCategory columnCategory;
     private boolean hidden;
 
     private Builder() {}
@@ -109,13 +118,18 @@ public class ColumnSchema {
       return this;
     }
 
+    public Builder setColumnCategory(TsTableColumnCategory columnCategory) {
+      this.columnCategory = requireNonNull(columnCategory, "columnCategory is null");
+      return this;
+    }
+
     public Builder setHidden(boolean hidden) {
       this.hidden = hidden;
       return this;
     }
 
     public ColumnSchema build() {
-      return new ColumnSchema(name, type, hidden);
+      return new ColumnSchema(name, type, hidden, columnCategory);
     }
   }
 }
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/DeviceEntry.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/DeviceEntry.java
new file mode 100644
index 00000000000..d126b465ae2
--- /dev/null
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/DeviceEntry.java
@@ -0,0 +1,43 @@
+/*
+ * 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.queryengine.plan.relational.metadata;
+
+import org.apache.iotdb.tsfile.file.metadata.IDeviceID;
+
+import java.util.List;
+
+public class DeviceEntry {
+
+  private final IDeviceID deviceID;
+  private final List<String> attributeColumnValues;
+
+  public DeviceEntry(IDeviceID deviceID, List<String> attributeColumnValues) {
+    this.deviceID = deviceID;
+    this.attributeColumnValues = attributeColumnValues;
+  }
+
+  public IDeviceID getDeviceID() {
+    return deviceID;
+  }
+
+  public List<String> getAttributeColumnValues() {
+    return attributeColumnValues;
+  }
+}
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/Metadata.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/Metadata.java
index 00843f38201..fa4d75bcf36 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/Metadata.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/Metadata.java
@@ -24,10 +24,10 @@ import org.apache.iotdb.db.queryengine.plan.relational.function.OperatorType;
 import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl;
 import org.apache.iotdb.db.queryengine.plan.relational.type.TypeNotFoundException;
 import org.apache.iotdb.db.queryengine.plan.relational.type.TypeSignature;
+import org.apache.iotdb.db.relational.sql.tree.Expression;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 
 public interface Metadata {
@@ -39,31 +39,8 @@ public interface Metadata {
    * of information required by semantic analyzer to analyze the query.
    *
    * @throws RuntimeException if table handle is no longer valid
-   * @see #getTableMetadata(SessionInfo, TableHandle)
    */
-  TableSchema getTableSchema(SessionInfo session, TableHandle tableHandle);
-
-  /**
-   * Return the metadata for the specified table handle.
-   *
-   * @throws RuntimeException if table handle is no longer valid
-   * @see #getTableSchema(SessionInfo, TableHandle) a different method which is less expensive.
-   */
-  TableMetadata getTableMetadata(SessionInfo session, TableHandle tableHandle);
-
-  /** Returns a table handle for the specified table name with a specified version */
-  Optional<TableHandle> getTableHandle(SessionInfo session, QualifiedObjectName name);
-
-  /**
-   * Gets all of the columns on the specified table, or an empty map if the columns cannot be
-   * enumerated.
-   *
-   * @throws RuntimeException if table handle is no longer valid
-   */
-  Map<String, ColumnHandle> getColumnHandles(SessionInfo session, TableHandle tableHandle);
-
-  ResolvedFunction resolveOperator(OperatorType operatorType, List<? extends Type> argumentTypes)
-      throws OperatorNotFoundException;
+  Optional<TableSchema> getTableSchema(SessionInfo session, QualifiedObjectName name);
 
   Type getOperatorReturnType(OperatorType operatorType, List<? extends Type> argumentTypes)
       throws OperatorNotFoundException;
@@ -76,4 +53,17 @@ public interface Metadata {
   Type getType(TypeSignature signature) throws TypeNotFoundException;
 
   boolean canCoerce(Type from, Type to);
+
+  /**
+   * get all device ids and corresponding attributes from schema region
+   *
+   * @param tableName qualified table name
+   * @param expressionList device filter in conj style, need to remove all the deviceId filter after
+   *     index scanning
+   * @param attributeColumns attribute column names
+   */
+  List<DeviceEntry> indexScan(
+      QualifiedObjectName tableName,
+      List<Expression> expressionList,
+      List<String> attributeColumns);
 }
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
index f040a086142..fea259a2b50 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
@@ -34,7 +34,6 @@ import org.apache.iotdb.tsfile.read.common.type.Type;
 
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Optional;
 
 import static org.apache.iotdb.tsfile.read.common.type.BinaryType.TEXT;
@@ -54,29 +53,7 @@ public class TableMetadataImpl implements Metadata {
   }
 
   @Override
-  public TableSchema getTableSchema(SessionInfo session, TableHandle tableHandle) {
-    return null;
-  }
-
-  @Override
-  public TableMetadata getTableMetadata(SessionInfo session, TableHandle tableHandle) {
-    return null;
-  }
-
-  @Override
-  public Optional<TableHandle> getTableHandle(SessionInfo session, QualifiedObjectName name) {
-    return Optional.empty();
-  }
-
-  @Override
-  public Map<String, ColumnHandle> getColumnHandles(SessionInfo session, TableHandle tableHandle) {
-    return null;
-  }
-
-  @Override
-  public ResolvedFunction resolveOperator(
-      OperatorType operatorType, List<? extends Type> argumentTypes)
-      throws OperatorNotFoundException {
+  public Optional<TableSchema> getTableSchema(SessionInfo session, QualifiedObjectName name) {
     return null;
   }
 
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 9e180d3dc4c..d084324151f 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
@@ -20,8 +20,7 @@ import org.apache.iotdb.db.queryengine.plan.relational.analyzer.Analysis;
 import org.apache.iotdb.db.queryengine.plan.relational.analyzer.Field;
 import org.apache.iotdb.db.queryengine.plan.relational.analyzer.NodeRef;
 import org.apache.iotdb.db.queryengine.plan.relational.analyzer.Scope;
-import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnHandle;
-import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableHandle;
+import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableSchema;
 import org.apache.iotdb.db.queryengine.plan.relational.planner.node.TableScanNode;
 import org.apache.iotdb.db.relational.sql.tree.AliasedRelation;
 import org.apache.iotdb.db.relational.sql.tree.AstVisitor;
@@ -32,7 +31,6 @@ import org.apache.iotdb.db.relational.sql.tree.SubqueryExpression;
 import org.apache.iotdb.db.relational.sql.tree.Table;
 
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 
 import java.util.Collection;
 import java.util.List;
@@ -90,10 +88,9 @@ class RelationPlanner extends AstVisitor<RelationPlan, Void> {
     if (namedQuery != null) {
       throw new RuntimeException("NamedQuery is not supported");
     } else {
-      TableHandle handle = analysis.getTableHandle(node);
+      TableSchema handle = analysis.getTableHandle(node);
 
       ImmutableList.Builder<Symbol> outputSymbolsBuilder = ImmutableList.builder();
-      ImmutableMap.Builder<Symbol, ColumnHandle> columns = ImmutableMap.builder();
 
       // Collection<Field> fields = analysis.getMaterializedViewStorageTableFields(node);
       Collection<Field> fields = scope.getRelationType().getAllFields();
@@ -101,13 +98,10 @@ class RelationPlanner extends AstVisitor<RelationPlan, Void> {
         Symbol symbol = symbolAllocator.newSymbol(field);
 
         outputSymbolsBuilder.add(symbol);
-        columns.put(symbol, analysis.getColumn(field));
       }
 
       List<Symbol> outputSymbols = outputSymbolsBuilder.build();
-      PlanNode root =
-          new TableScanNode(
-              idAllocator.genPlanNodeId(), handle, outputSymbols, columns.buildOrThrow());
+      PlanNode root = new TableScanNode(idAllocator.genPlanNodeId(), null, outputSymbols, null);
 
       plan = new RelationPlan(root, scope, outputSymbols);
     }
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java
index 1b7c2476ba3..022712a5fed 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/TableScanNode.java
@@ -18,6 +18,19 @@ public class TableScanNode extends PlanNode {
   private final List<Symbol> outputSymbols;
   private final Map<Symbol, ColumnHandle> assignments; // symbol -> column
 
+  // db.tablename
+  //  String qualifiedTableName;
+  //
+  //  List<Symbol> outputSymbols;
+  //
+  //  List<IDeviceID> deviceIDList;
+  //
+  //  List<List<String>> deviceAttributesList;
+  //
+  //  Map<Symbol, ColumnSchema> assignments;
+  //
+  //  Map<Symbol, Integer> attributesMap;
+
   public TableScanNode(
       PlanNodeId id,
       TableHandle table,
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
index c42342c16cd..ac07251c00d 100644
--- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java
@@ -72,9 +72,6 @@ public class AnalyzerTest {
     Mockito.when(metadata.tableExists(Mockito.any())).thenReturn(true);
 
     TableHandle tableHandle = Mockito.mock(TableHandle.class);
-    Mockito.when(
-            metadata.getTableHandle(Mockito.any(), eq(new QualifiedObjectName("testdb", "table1"))))
-        .thenReturn(Optional.of(tableHandle));
 
     Map<String, ColumnHandle> map = new HashMap<>();
     TableSchema tableSchema = Mockito.mock(TableSchema.class);
@@ -94,8 +91,9 @@ public class AnalyzerTest {
     List<ColumnSchema> columnSchemaList = Arrays.asList(column1, column2, column3);
     Mockito.when(tableSchema.getColumns()).thenReturn(columnSchemaList);
 
-    Mockito.when(metadata.getTableSchema(Mockito.any(), eq(tableHandle))).thenReturn(tableSchema);
-    Mockito.when(metadata.getColumnHandles(Mockito.any(), eq(tableHandle))).thenReturn(map);
+    Mockito.when(
+            metadata.getTableSchema(Mockito.any(), eq(new QualifiedObjectName("testdb", "table1"))))
+        .thenReturn(Optional.of(tableSchema));
 
     //    ResolvedFunction lLessThanI =
     //        new ResolvedFunction(
diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java
index 0a8b6635ee7..79aaa33061f 100644
--- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java
+++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java
@@ -4,19 +4,12 @@ import org.apache.iotdb.commons.udf.builtin.BuiltinAggregationFunction;
 import org.apache.iotdb.commons.udf.builtin.BuiltinScalarFunction;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.db.queryengine.common.SessionInfo;
-import org.apache.iotdb.db.queryengine.plan.relational.function.BoundSignature;
-import org.apache.iotdb.db.queryengine.plan.relational.function.FunctionId;
-import org.apache.iotdb.db.queryengine.plan.relational.function.FunctionKind;
 import org.apache.iotdb.db.queryengine.plan.relational.function.OperatorType;
-import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnHandle;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnMetadata;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.ColumnSchema;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.Metadata;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.OperatorNotFoundException;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName;
-import org.apache.iotdb.db.queryengine.plan.relational.metadata.ResolvedFunction;
-import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableHandle;
-import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableMetadata;
 import org.apache.iotdb.db.queryengine.plan.relational.metadata.TableSchema;
 import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl;
 import org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager;
@@ -25,16 +18,11 @@ import org.apache.iotdb.db.queryengine.plan.relational.type.TypeNotFoundExceptio
 import org.apache.iotdb.db.queryengine.plan.relational.type.TypeSignature;
 import org.apache.iotdb.db.utils.constant.SqlConstant;
 import org.apache.iotdb.tsfile.read.common.type.BinaryType;
-import org.apache.iotdb.tsfile.read.common.type.BooleanType;
 import org.apache.iotdb.tsfile.read.common.type.Type;
 
-import org.mockito.Mockito;
-
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Optional;
 
 import static org.apache.iotdb.tsfile.read.common.type.BinaryType.TEXT;
@@ -77,7 +65,7 @@ public class TestMatadata implements Metadata {
   }
 
   @Override
-  public TableSchema getTableSchema(SessionInfo session, TableHandle tableHandle) {
+  public Optional<TableSchema> getTableSchema(SessionInfo session, QualifiedObjectName name) {
     List<ColumnSchema> columnSchemas =
         Arrays.asList(
             ColumnSchema.builder(TIME_CM).build(),
@@ -89,62 +77,7 @@ public class TestMatadata implements Metadata {
             ColumnSchema.builder(S1_CM).build(),
             ColumnSchema.builder(S2_CM).build());
 
-    return new TableSchema(TABLE1, columnSchemas);
-  }
-
-  @Override
-  public TableMetadata getTableMetadata(SessionInfo session, TableHandle tableHandle) {
-    return new TableMetadata(
-        TABLE1,
-        Arrays.asList(TIME_CM, TAG1_CM, TAG2_CM, TAG3_CM, ATTR1_CM, ATTR2_CM, S1_CM, S2_CM));
-  }
-
-  @Override
-  public Optional<TableHandle> getTableHandle(SessionInfo session, QualifiedObjectName name) {
-    return Optional.of(Mockito.mock(TableHandle.class));
-  }
-
-  @Override
-  public Map<String, ColumnHandle> getColumnHandles(SessionInfo session, TableHandle tableHandle) {
-    Map<String, ColumnHandle> map = new HashMap<>();
-    ColumnHandle columnHandle = Mockito.mock(ColumnHandle.class);
-    map.put(TIME, columnHandle);
-    map.put(TAG1, columnHandle);
-    map.put(TAG2, columnHandle);
-    map.put(TAG3, columnHandle);
-    map.put(ATTR1, columnHandle);
-    map.put(ATTR2, columnHandle);
-    map.put(S1, columnHandle);
-    map.put(S2, columnHandle);
-    return map;
-  }
-
-  @Override
-  public ResolvedFunction resolveOperator(
-      OperatorType operatorType, List<? extends Type> argumentTypes)
-      throws OperatorNotFoundException {
-    if (operatorType == OperatorType.LESS_THAN) {
-      return new ResolvedFunction(
-          new BoundSignature("less_than", BooleanType.BOOLEAN, Arrays.asList(INT64, INT32)),
-          new FunctionId("less_than"),
-          FunctionKind.SCALAR,
-          true);
-    } else if (operatorType == OperatorType.ADD) {
-      return new ResolvedFunction(
-          new BoundSignature("add", INT64, Arrays.asList(INT64, INT32)),
-          new FunctionId("add"),
-          FunctionKind.SCALAR,
-          true);
-    } else if (operatorType == OperatorType.EQUAL) {
-      return new ResolvedFunction(
-          new BoundSignature(
-              "equals", BooleanType.BOOLEAN, Arrays.asList(BinaryType.TEXT, BinaryType.TEXT)),
-          new FunctionId("equals"),
-          FunctionKind.SCALAR,
-          true);
-    } else {
-      throw new OperatorNotFoundException(operatorType, argumentTypes, new RuntimeException());
-    }
+    return Optional.of(new TableSchema(TABLE1, columnSchemas));
   }
 
   @Override
diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
index 22a8616ee95..5029a5911a7 100644
--- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
+++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/CommonConfig.java
@@ -153,7 +153,7 @@ public class CommonConfig {
   private long timePartitionInterval = 604_800_000;
 
   /** This variable set timestamp precision as millisecond, microsecond or nanosecond. */
-  private String timestampPrecision = "ms";
+  private String timestampPrecision = "ns";
 
   private boolean timestampPrecisionCheckEnabled = true;
 
@@ -242,7 +242,7 @@ public class CommonConfig {
   private String schemaEngineMode = "Memory";
 
   /** Whether to enable Last cache. */
-  private boolean lastCacheEnable = true;
+  private boolean lastCacheEnable = false;
 
   // Max size for tag and attribute of one time series
   private int tagAttributeTotalSize = 700;