You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by su...@apache.org on 2021/06/01 08:42:42 UTC

[iotdb] branch vector_refactor updated: refactor InsertRowPlan

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

sunzesong pushed a commit to branch vector_refactor
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/vector_refactor by this push:
     new c5f27d4  refactor InsertRowPlan
c5f27d4 is described below

commit c5f27d44995b2595644a349f2a6187df78b85118
Author: samperson1997 <sz...@mails.tsinghua.edu.cn>
AuthorDate: Tue Jun 1 16:42:07 2021 +0800

    refactor InsertRowPlan
---
 .../org/apache/iotdb/VectorSessionExample.java     | 29 ++++++-
 .../iotdb/db/engine/memtable/AbstractMemTable.java | 18 ++--
 .../org/apache/iotdb/db/metadata/MManager.java     | 95 +++++++++-------------
 .../java/org/apache/iotdb/db/metadata/MTree.java   |  2 -
 .../iotdb/db/qp/physical/crud/InsertPlan.java      |  9 ++
 .../iotdb/db/qp/physical/crud/InsertRowPlan.java   | 20 +++++
 .../org/apache/iotdb/db/service/TSServiceImpl.java | 24 +++++-
 .../java/org/apache/iotdb/session/Session.java     | 64 +++++++++++----
 .../apache/iotdb/session/SessionCacheLeaderUT.java |  4 +-
 thrift/src/main/thrift/rpc.thrift                  |  6 +-
 10 files changed, 176 insertions(+), 95 deletions(-)

diff --git a/example/session/src/main/java/org/apache/iotdb/VectorSessionExample.java b/example/session/src/main/java/org/apache/iotdb/VectorSessionExample.java
index 293a8ab..1662c1d 100644
--- a/example/session/src/main/java/org/apache/iotdb/VectorSessionExample.java
+++ b/example/session/src/main/java/org/apache/iotdb/VectorSessionExample.java
@@ -49,13 +49,14 @@ public class VectorSessionExample {
     // set session fetchSize
     session.setFetchSize(10000);
 
-    createAlignedTimeseries();
-    //    createTemplate();
+    //    createAlignedTimeseries();
+    //        createTemplate();
     //    insertTabletWithAlignedTimeseriesMethod1();
     //    insertTabletWithAlignedTimeseriesMethod2();
-    //
+
+    //    insertAlignedRecord();
     //    insertNullableTabletWithAlignedTimeseries();
-    //    selectTest();
+    selectTest();
     //    selectWithValueFilterTest();
     //
     //    selectWithGroupByTest();
@@ -361,4 +362,24 @@ public class VectorSessionExample {
 
     session.executeNonQueryStatement("flush");
   }
+
+  private static void insertAlignedRecord()
+      throws IoTDBConnectionException, StatementExecutionException {
+    List<String> measurements = new ArrayList<>();
+    List<TSDataType> types = new ArrayList<>();
+    measurements.add("s1");
+    measurements.add("s2");
+    measurements.add("s3");
+    types.add(TSDataType.INT64);
+    types.add(TSDataType.INT32);
+    types.add(TSDataType.INT64);
+
+    for (long time = 0; time < 100; time++) {
+      List<Object> values = new ArrayList<>();
+      values.add(1L);
+      values.add(2);
+      values.add(3L);
+      session.insertRecord(ROOT_SG1_D1 + ".vector", time, measurements, types, values, true);
+    }
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
index ba62303..aba8090 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
@@ -117,27 +117,27 @@ public abstract class AbstractMemTable implements IMemTable {
 
     MeasurementMNode[] measurementMNodes = insertRowPlan.getMeasurementMNodes();
     int columnIndex = 0;
-    for (int i = 0; i < measurementMNodes.length; i++) {
-
-      if (measurementMNodes[i] != null
-          && measurementMNodes[i].getSchema().getType() == TSDataType.VECTOR) {
+    for (MeasurementMNode measurementMNode : measurementMNodes) {
+      if (measurementMNode != null && measurementMNode.getSchema().getType() == TSDataType.VECTOR) {
         // write vector
         Object[] vectorValue =
-            new Object[measurementMNodes[i].getSchema().getValueTSDataTypeList().size()];
+            new Object[measurementMNode.getSchema().getValueTSDataTypeList().size()];
         for (int j = 0; j < vectorValue.length; j++) {
           vectorValue[j] = values[columnIndex];
           columnIndex++;
         }
         memSize +=
             MemUtils.getVectorRecordSize(
-                measurementMNodes[i].getSchema().getValueTSDataTypeList(),
+                measurementMNode.getSchema().getValueTSDataTypeList(),
                 vectorValue,
                 disableMemControl);
         write(
             insertRowPlan.getDeviceId().getFullPath(),
-            measurementMNodes[i].getSchema(),
+            measurementMNode.getSchema(),
             insertRowPlan.getTime(),
             vectorValue);
+        // because only one vector is in this plan
+        break;
       } else {
         if (values[columnIndex] == null) {
           columnIndex++;
@@ -145,11 +145,11 @@ public abstract class AbstractMemTable implements IMemTable {
         }
         memSize +=
             MemUtils.getRecordSize(
-                measurementMNodes[i].getSchema().getType(), values[columnIndex], disableMemControl);
+                measurementMNode.getSchema().getType(), values[columnIndex], disableMemControl);
 
         write(
             insertRowPlan.getDeviceId().getFullPath(),
-            measurementMNodes[i].getSchema(),
+            measurementMNode.getSchema(),
             insertRowPlan.getTime(),
             values[columnIndex]);
         columnIndex++;
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
index bd0b887..f2001f0 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
@@ -515,7 +515,7 @@ public class MManager {
   }
 
   public void createAlignedTimeSeries(
-      PartialPath devicePath,
+      PartialPath prefixPath,
       List<String> measurements,
       List<TSDataType> dataTypes,
       List<TSEncoding> encodings,
@@ -523,7 +523,7 @@ public class MManager {
       throws MetadataException {
     createAlignedTimeSeries(
         new CreateAlignedTimeSeriesPlan(
-            devicePath, measurements, dataTypes, encodings, compressor, null));
+            prefixPath, measurements, dataTypes, encodings, compressor, null));
   }
 
   /**
@@ -538,21 +538,20 @@ public class MManager {
               + "please increase MAX_HEAP_SIZE in iotdb-env.sh/bat and restart");
     }
     try {
-      PartialPath devicePath = plan.getPrefixPath();
+      PartialPath prefixPath = plan.getPrefixPath();
       List<String> measurements = plan.getMeasurements();
-      int alignedSize = measurements.size();
       List<TSDataType> dataTypes = plan.getDataTypes();
       List<TSEncoding> encodings = plan.getEncodings();
 
-      for (int i = 0; i < alignedSize; i++) {
+      for (int i = 0; i < measurements.size(); i++) {
         SchemaUtils.checkDataTypeWithEncoding(dataTypes.get(i), encodings.get(i));
       }
 
-      ensureStorageGroup(devicePath);
+      ensureStorageGroup(prefixPath);
 
       // create time series in MTree
       mtree.createAlignedTimeseries(
-          devicePath, measurements, plan.getDataTypes(), plan.getEncodings(), plan.getCompressor());
+          prefixPath, measurements, plan.getDataTypes(), plan.getEncodings(), plan.getCompressor());
 
       // update statistics and schemaDataTypeNumMap
       totalSeriesNumber.addAndGet(measurements.size());
@@ -1139,7 +1138,7 @@ public class MManager {
    * get MeasurementSchema or VectorMeasurementSchema which contains the measurement
    *
    * @param device device path
-   * @param measurement measurement name, could start with "$#$"
+   * @param measurement measurement name, could be vector name
    * @return MeasurementSchema or VectorMeasurementSchema
    */
   public IMeasurementSchema getSeriesSchema(PartialPath device, String measurement)
@@ -2148,6 +2147,7 @@ public class MManager {
   public MNode getSeriesSchemasAndReadLockDevice(InsertPlan plan)
       throws MetadataException, IOException {
     PartialPath deviceId = plan.getDeviceId();
+    String vectorId = plan.getVectorId(); // could be null for not aligned timeseries
     String[] measurementList = plan.getMeasurements();
     MeasurementMNode[] measurementMNodes = plan.getMeasurementMNodes();
 
@@ -2160,19 +2160,11 @@ public class MManager {
     // 2. get schema of each measurement
     // if do not have measurement
     MeasurementMNode measurementMNode;
-    int loc = 0;
-
     for (int i = 0; i < measurementList.length; i++) {
       try {
         String measurement = measurementList[i];
-        boolean isVector = false;
-        String firstMeasurementOfVector = null;
-        if (measurement.contains("(") && measurement.contains(",")) {
-          isVector = true;
-          firstMeasurementOfVector = measurement.replace("(", "").replace(")", "").split(",")[0];
-        }
 
-        MNode child = getMNode(deviceMNode.left, isVector ? firstMeasurementOfVector : measurement);
+        MNode child = getMNode(deviceMNode.left, vectorId != null ? vectorId : measurement);
         if (child instanceof MeasurementMNode) {
           measurementMNode = (MeasurementMNode) child;
         } else if (child instanceof StorageGroupMNode) {
@@ -2184,22 +2176,15 @@ public class MManager {
             throw new PathNotExistException(deviceId + PATH_SEPARATOR + measurement);
           } else {
             if (plan instanceof InsertRowPlan || plan instanceof InsertTabletPlan) {
-              List<String> measurements =
-                  Arrays.asList(measurement.replace("(", "").replace(")", "").split(","));
-              if (measurements.size() == 1) {
-                internalCreateTimeseries(
-                    deviceId.concatNode(measurement), plan.getDataTypes()[loc]);
+              if (plan.getVectorId() == null) {
+                internalCreateTimeseries(deviceId.concatNode(measurement), plan.getDataTypes()[i]);
                 measurementMNode = (MeasurementMNode) deviceMNode.left.getChild(measurement);
               } else {
-                int curLoc = loc;
-                List<TSDataType> dataTypes = new ArrayList<>();
-                for (int j = 0; j < measurements.size(); j++) {
-                  dataTypes.add(plan.getDataTypes()[curLoc]);
-                  curLoc++;
-                }
-                internalAlignedCreateTimeseries(deviceId, measurements, dataTypes);
-                measurementMNode =
-                    (MeasurementMNode) deviceMNode.left.getChild(measurements.get(0));
+                internalAlignedCreateTimeseries(
+                    new PartialPath(deviceId.getFullPath(), vectorId),
+                    Arrays.asList(measurementList),
+                    Arrays.asList(plan.getDataTypes()));
+                measurementMNode = (MeasurementMNode) deviceMNode.left.getChild(plan.getVectorId());
               }
             } else {
               throw new MetadataException(
@@ -2215,39 +2200,34 @@ public class MManager {
         TSDataType insertDataType;
         DataTypeMismatchException mismatchException = null;
         if (plan instanceof InsertRowPlan || plan instanceof InsertTabletPlan) {
-          if (measurementList[i].contains("(") && measurementList[i].contains(",")) {
-            for (int j = 0; j < measurementList[i].split(",").length; j++) {
-              TSDataType dataTypeInNode =
-                  measurementMNode.getSchema().getValueTSDataTypeList().get(j);
-              insertDataType = plan.getDataTypes()[loc];
-              if (insertDataType == null) {
-                insertDataType = dataTypeInNode;
-              }
-              if (dataTypeInNode != insertDataType) {
-                mismatch = true;
-                logger.warn(
-                    "DataType mismatch, Insert measurement {} in {} type {}, metadata tree type {}",
-                    measurementMNode.getSchema().getValueMeasurementIdList().get(j),
-                    measurementList[i],
-                    insertDataType,
-                    dataTypeInNode);
-                mismatchException =
-                    new DataTypeMismatchException(
-                        measurementList[i], insertDataType, dataTypeInNode);
-                break;
-              }
-              loc++;
+          if (plan.getVectorId() != null) {
+            TSDataType dataTypeInNode =
+                measurementMNode.getSchema().getValueTSDataTypeList().get(i);
+            insertDataType = plan.getDataTypes()[i];
+            if (insertDataType == null) {
+              insertDataType = dataTypeInNode;
+            }
+            if (dataTypeInNode != insertDataType) {
+              mismatch = true;
+              logger.warn(
+                  "DataType mismatch, Insert measurement {} in {} type {}, metadata tree type {}",
+                  measurementMNode.getSchema().getValueMeasurementIdList().get(i),
+                  measurementList[i],
+                  insertDataType,
+                  dataTypeInNode);
+              mismatchException =
+                  new DataTypeMismatchException(measurementList[i], insertDataType, dataTypeInNode);
             }
           } else {
             if (plan instanceof InsertRowPlan) {
               if (!((InsertRowPlan) plan).isNeedInferType()) {
                 // only when InsertRowPlan's values is object[], we should check type
-                insertDataType = getTypeInLoc(plan, loc);
+                insertDataType = getTypeInLoc(plan, i);
               } else {
                 insertDataType = measurementMNode.getSchema().getType();
               }
             } else {
-              insertDataType = getTypeInLoc(plan, loc);
+              insertDataType = getTypeInLoc(plan, i);
             }
             mismatch = measurementMNode.getSchema().getType() != insertDataType;
             if (mismatch) {
@@ -2260,7 +2240,6 @@ public class MManager {
                   new DataTypeMismatchException(
                       measurementList[i], insertDataType, measurementMNode.getSchema().getType());
             }
-            loc++;
           }
         }
 
@@ -2364,14 +2343,14 @@ public class MManager {
 
   /** create aligned timeseries ignoring PathAlreadyExistException */
   private void internalAlignedCreateTimeseries(
-      PartialPath devicePath, List<String> measurements, List<TSDataType> dataTypes)
+      PartialPath prefixPath, List<String> measurements, List<TSDataType> dataTypes)
       throws MetadataException {
     List<TSEncoding> encodings = new ArrayList<>();
     for (TSDataType dataType : dataTypes) {
       encodings.add(getDefaultEncoding(dataType));
     }
     createAlignedTimeSeries(
-        devicePath,
+        prefixPath,
         measurements,
         dataTypes,
         encodings,
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
index 4a1466a..2b6a1e1 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
@@ -312,13 +312,11 @@ public class MTree implements Serializable {
     }
     MNode cur = root;
     boolean hasSetStorageGroup = false;
-    StorageGroupMNode storageGroupMNode = null;
     // e.g, devicePath = root.sg.d1, create internal nodes and set cur to d1 node
     for (int i = 1; i < deviceNodeNames.length - 1; i++) {
       String nodeName = deviceNodeNames[i];
       if (cur instanceof StorageGroupMNode) {
         hasSetStorageGroup = true;
-        storageGroupMNode = (StorageGroupMNode) cur;
       }
       if (!cur.hasChild(nodeName)) {
         if (!hasSetStorageGroup) {
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java
index 68dcac3..c1a8f6e 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java
@@ -33,6 +33,7 @@ import java.util.List;
 public abstract class InsertPlan extends PhysicalPlan {
 
   protected PartialPath deviceId;
+  protected String vectorId;
   protected String[] measurements;
   // get from client
   protected TSDataType[] dataTypes;
@@ -57,6 +58,14 @@ public abstract class InsertPlan extends PhysicalPlan {
     this.deviceId = deviceId;
   }
 
+  public String getVectorId() {
+    return vectorId;
+  }
+
+  public void setVectorId(String vectorId) {
+    this.vectorId = vectorId;
+  }
+
   public String[] getMeasurements() {
     return this.measurements;
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
index f20b385..d7e8bcf 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
@@ -94,6 +94,7 @@ public class InsertRowPlan extends InsertPlan {
     isNeedInferType = true;
   }
 
+  /** should be deprecated after insertRecords() and insertRowsOfOneDevice() support vector */
   public InsertRowPlan(
       PartialPath deviceId, long insertTime, String[] measurementList, ByteBuffer values)
       throws QueryProcessException {
@@ -107,6 +108,25 @@ public class InsertRowPlan extends InsertPlan {
     isNeedInferType = false;
   }
 
+  /** for vector */
+  public InsertRowPlan(
+      PartialPath deviceId,
+      String vectorId,
+      long insertTime,
+      String[] measurementList,
+      ByteBuffer values)
+      throws QueryProcessException {
+    super(Operator.OperatorType.INSERT);
+    this.time = insertTime;
+    this.deviceId = deviceId;
+    this.vectorId = vectorId;
+    this.measurements = measurementList;
+    this.dataTypes = new TSDataType[measurementList.length];
+    this.values = new Object[measurementList.length];
+    this.fillValues(values);
+    isNeedInferType = false;
+  }
+
   @TestOnly
   public InsertRowPlan(
       PartialPath deviceId,
diff --git a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
index 4ecdbc5..4fabaf0 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
@@ -1543,12 +1543,22 @@ public class TSServiceImpl implements TSIService.Iface {
       AUDIT_LOGGER.debug(
           "Session {} insertRecord, device {}, time {}",
           currSessionId.get(),
-          req.getDeviceId(),
+          req.getPrefixPath(),
           req.getTimestamp());
 
+      PartialPath deviceId;
+      String vectorId;
+      if (req.isVector) {
+        deviceId = new PartialPath(req.getPrefixPath()).getDevicePath();
+        vectorId = new PartialPath(req.getPrefixPath()).getMeasurement();
+      } else {
+        deviceId = new PartialPath(req.getPrefixPath());
+        vectorId = null;
+      }
       InsertRowPlan plan =
           new InsertRowPlan(
-              new PartialPath(req.getDeviceId()),
+              deviceId,
+              vectorId,
               req.getTimestamp(),
               req.getMeasurements().toArray(new String[0]),
               req.values);
@@ -1621,8 +1631,14 @@ public class TSServiceImpl implements TSIService.Iface {
         return RpcUtils.getStatus(TSStatusCode.NOT_LOGIN_ERROR);
       }
 
-      InsertTabletPlan insertTabletPlan =
-          new InsertTabletPlan(new PartialPath(req.deviceId), req.measurements);
+      InsertTabletPlan insertTabletPlan;
+      PartialPath prefixPath = new PartialPath(req.getPrefixPath());
+      if (req.isVector) {
+        insertTabletPlan = new InsertTabletPlan(prefixPath.getDevicePath(), req.measurements);
+        insertTabletPlan.setVectorId(prefixPath.getMeasurement());
+      } else {
+        insertTabletPlan = new InsertTabletPlan(prefixPath, req.measurements);
+      }
       insertTabletPlan.setTimes(QueryDataSetUtils.readTimesFromBuffer(req.timestamps, req.size));
       insertTabletPlan.setColumns(
           QueryDataSetUtils.readValuesFromBuffer(
diff --git a/session/src/main/java/org/apache/iotdb/session/Session.java b/session/src/main/java/org/apache/iotdb/session/Session.java
index c219100..295f856 100644
--- a/session/src/main/java/org/apache/iotdb/session/Session.java
+++ b/session/src/main/java/org/apache/iotdb/session/Session.java
@@ -38,6 +38,7 @@ import org.apache.iotdb.service.rpc.thrift.TSInsertTabletsReq;
 import org.apache.iotdb.service.rpc.thrift.TSProtocolVersion;
 import org.apache.iotdb.service.rpc.thrift.TSSetSchemaTemplateReq;
 import org.apache.iotdb.tsfile.common.conf.TSFileConfig;
+import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -601,13 +602,25 @@ public class Session {
       long time,
       List<String> measurements,
       List<TSDataType> types,
+      boolean isVector,
       Object... values)
       throws IoTDBConnectionException, StatementExecutionException {
     TSInsertRecordReq request =
-        genTSInsertRecordReq(deviceId, time, measurements, types, Arrays.asList(values));
+        genTSInsertRecordReq(deviceId, time, measurements, types, Arrays.asList(values), isVector);
     insertRecord(deviceId, request);
   }
 
+  public void insertRecord(
+      String deviceId,
+      long time,
+      List<String> measurements,
+      List<TSDataType> types,
+      Object... values)
+      throws IoTDBConnectionException, StatementExecutionException {
+    // not vector by default
+    insertRecord(deviceId, time, measurements, types, false, values);
+  }
+
   private void insertRecord(String deviceId, TSInsertRecordReq request)
       throws IoTDBConnectionException, StatementExecutionException {
     try {
@@ -713,9 +726,24 @@ public class Session {
       long time,
       List<String> measurements,
       List<TSDataType> types,
+      List<Object> values,
+      boolean isVector)
+      throws IoTDBConnectionException, StatementExecutionException {
+    TSInsertRecordReq request =
+        genTSInsertRecordReq(deviceId, time, measurements, types, values, isVector);
+    insertRecord(deviceId, request);
+  }
+
+  public void insertRecord(
+      String deviceId,
+      long time,
+      List<String> measurements,
+      List<TSDataType> types,
       List<Object> values)
       throws IoTDBConnectionException, StatementExecutionException {
-    TSInsertRecordReq request = genTSInsertRecordReq(deviceId, time, measurements, types, values);
+    // not vector by default
+    TSInsertRecordReq request =
+        genTSInsertRecordReq(deviceId, time, measurements, types, values, false);
     insertRecord(deviceId, request);
   }
 
@@ -724,15 +752,17 @@ public class Session {
       long time,
       List<String> measurements,
       List<TSDataType> types,
-      List<Object> values)
+      List<Object> values,
+      boolean isVector)
       throws IoTDBConnectionException {
     TSInsertRecordReq request = new TSInsertRecordReq();
-    request.setDeviceId(deviceId);
+    request.setPrefixPath(deviceId);
     request.setTimestamp(time);
     request.setMeasurements(measurements);
     ByteBuffer buffer = ByteBuffer.allocate(calculateLength(types, values));
     putValues(types, values, buffer);
     request.setValues(buffer);
+    request.setIsVector(isVector);
     return request;
   }
 
@@ -1123,24 +1153,29 @@ public class Session {
     }
 
     TSInsertTabletReq request = new TSInsertTabletReq();
-    request.setDeviceId(tablet.deviceId);
+
     for (IMeasurementSchema measurementSchema : tablet.getSchemas()) {
       if (measurementSchema instanceof MeasurementSchema) {
+        request.setPrefixPath(tablet.deviceId);
         request.addToMeasurements(measurementSchema.getMeasurementId());
         request.addToTypes(measurementSchema.getType().ordinal());
+        request.setIsVector(false);
       } else {
+        if (tablet.getSchemas().size() > 1) {
+          if (request.isVector) {
+            throw new BatchExecutionException(
+                "One tablet should only contain one aligned timeseries!");
+          }
+        }
+        request.setPrefixPath(
+            tablet.deviceId + TsFileConstant.PATH_SEPARATOR + measurementSchema.getMeasurementId());
         int measurementsSize = measurementSchema.getValueMeasurementIdList().size();
-        StringBuilder measurement = new StringBuilder("(");
         for (int i = 0; i < measurementsSize; i++) {
-          measurement.append(measurementSchema.getValueMeasurementIdList().get(i));
-          if (i != measurementsSize - 1) {
-            measurement.append(",");
-          } else {
-            measurement.append(")");
-          }
+          request.addToMeasurements(measurementSchema.getValueMeasurementIdList().get(i));
           request.addToTypes(measurementSchema.getValueTSDataTypeList().get(i).ordinal());
         }
-        request.addToMeasurements(measurement.toString());
+        request.setIsVector(true);
+        break;
       }
     }
     request.setTimestamps(SessionUtils.getTimeBuffer(tablet));
@@ -1343,7 +1378,8 @@ public class Session {
       List<TSDataType> types,
       List<Object> values)
       throws IoTDBConnectionException, StatementExecutionException {
-    TSInsertRecordReq request = genTSInsertRecordReq(deviceId, time, measurements, types, values);
+    TSInsertRecordReq request =
+        genTSInsertRecordReq(deviceId, time, measurements, types, values, false);
     defaultSessionConnection.testInsertRecord(request);
   }
 
diff --git a/session/src/test/java/org/apache/iotdb/session/SessionCacheLeaderUT.java b/session/src/test/java/org/apache/iotdb/session/SessionCacheLeaderUT.java
index 763a27b..7e7f4e6 100644
--- a/session/src/test/java/org/apache/iotdb/session/SessionCacheLeaderUT.java
+++ b/session/src/test/java/org/apache/iotdb/session/SessionCacheLeaderUT.java
@@ -779,7 +779,7 @@ public class SessionCacheLeaderUT {
 
     @Override
     protected void insertRecord(TSInsertRecordReq request) throws RedirectException {
-      throw new RedirectException(getDeviceIdBelongedEndpoint(request.deviceId));
+      throw new RedirectException(getDeviceIdBelongedEndpoint(request.prefixPath));
     }
 
     @Override
@@ -805,7 +805,7 @@ public class SessionCacheLeaderUT {
 
     @Override
     protected void insertTablet(TSInsertTabletReq request) throws RedirectException {
-      throw new RedirectException(getDeviceIdBelongedEndpoint(request.deviceId));
+      throw new RedirectException(getDeviceIdBelongedEndpoint(request.prefixPath));
     }
 
     @Override
diff --git a/thrift/src/main/thrift/rpc.thrift b/thrift/src/main/thrift/rpc.thrift
index 93429b9..2effea4 100644
--- a/thrift/src/main/thrift/rpc.thrift
+++ b/thrift/src/main/thrift/rpc.thrift
@@ -194,10 +194,11 @@ struct TSSetTimeZoneReq {
 // for session
 struct TSInsertRecordReq {
   1: required i64 sessionId
-  2: required string deviceId
+  2: required string prefixPath
   3: required list<string> measurements
   4: required binary values
   5: required i64 timestamp
+  6: optional bool isVector
 }
 
 struct TSInsertStringRecordReq {
@@ -210,12 +211,13 @@ struct TSInsertStringRecordReq {
 
 struct TSInsertTabletReq {
   1: required i64 sessionId
-  2: required string deviceId
+  2: required string prefixPath
   3: required list<string> measurements
   4: required binary values
   5: required binary timestamps
   6: required list<i32> types
   7: required i32 size
+  8: optional bool isVector
 }
 
 struct TSInsertTabletsReq {