diff --git a/.github/workflows/pre-commit-format.yml b/.github/workflows/pre-commit-format.yml
new file mode 100644
index 0000000..786a5e5
--- /dev/null
+++ b/.github/workflows/pre-commit-format.yml
@@ -0,0 +1,48 @@
+name: Formatting
+
+on:
+  workflow_dispatch:
+  pull_request:
+    branches:
+      - '**'
+  merge_group:
+    branches: [ main ]
+  schedule:
+    - cron: "0 0 * * *"
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  formatting-checks:
+    runs-on: ubuntu-20.04
+
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Setup dotnet
+        uses: actions/setup-dotnet@v4
+        with:
+          dotnet-version: '9.0.x'
+
+      - name: Setup Python environment (for pre-commit)
+        uses: actions/setup-python@v5
+        with:
+          python-version: '3.10'
+
+      - name: Clean dotnet temporary folder
+        run: |
+          sudo rm -rf /tmp/.dotnet
+
+      - name: Install pre-commit and dependencies
+        run: |
+          pip install pre-commit
+          pre-commit install-hooks
+
+      - name: Run pre-commit checks
+        env:
+          TMPDIR: ${{ runner.temp }}
+          DOTNET_CLI_HOME: ${{ runner.temp }}
+        run: |
+          pre-commit run --all-files
diff --git a/.licenserc.yaml b/.licenserc.yaml
index afe9c0c..4bda2c2 100644
--- a/.licenserc.yaml
+++ b/.licenserc.yaml
@@ -32,5 +32,6 @@
     - 'Apache.IoTDB.sln'
     - '.gitignore'
     - '.dockerignore'
+    - '.pre-commit-config.yaml'
 
   comment: on-failure
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..630051f
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,33 @@
+
+
+repos:
+  - repo: local
+    hooks:
+      - id: dotnet-format
+        name: dotnet format
+        entry: dotnet format --include
+        language: system
+        pass_filenames: true
+        files: '\.(cs|vb|fs|sln|csproj|fsproj)$'
+
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v4.6.0
+    hooks:
+      - id: trailing-whitespace
+      - id: end-of-file-fixer
+      - id: check-added-large-files
+      - id: check-yaml
+      - id: check-json
+      - id: check-xml
+
+  - repo: https://github.com/codespell-project/codespell
+    rev: v2.2.6
+    hooks:
+      - id: codespell
+        args: ["--ignore-words-list=fo,teh,ba"]
+
+exclude: |
+  (?x)^(
+      src/Apache\.IoTDB/Rpc/|
+      .*\.md$
+  )
diff --git a/Apache-IoTDB-Client-CSharp-UserCase/Program.cs b/Apache-IoTDB-Client-CSharp-UserCase/Program.cs
index 345e9a7..281104d 100644
--- a/Apache-IoTDB-Client-CSharp-UserCase/Program.cs
+++ b/Apache-IoTDB-Client-CSharp-UserCase/Program.cs
@@ -118,4 +118,3 @@
     }
 
 }
-
diff --git a/Apache.IoTDB.sln b/Apache.IoTDB.sln
index 7ddbed2..b6b5aaf 100644
--- a/Apache.IoTDB.sln
+++ b/Apache.IoTDB.sln
@@ -26,8 +26,6 @@
 		docs\time_profile_zh.pdf = docs\time_profile_zh.pdf
 	EndProjectSection
 EndProject
-Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{4D457769-80CB-401F-9155-C3125C04FACD}"
-EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apache.IoTDB.Data", "src\Apache.IoTDB.Data\Apache.IoTDB.Data.csproj", "{4308656F-D174-49A6-ACE4-15894B017D55}"
 EndProject
 Global
diff --git a/docker-compose-2c2d.yml b/docker-compose-2c2d.yml
index 318e8e8..4772779 100644
--- a/docker-compose-2c2d.yml
+++ b/docker-compose-2c2d.yml
@@ -130,4 +130,4 @@
       dockerfile: samples/Apache.IoTDB.Samples/Dockerfile
     command: ["--multi", "localhost:6667", "localhost:6668"]
     # command: ["sleep", "infinity"]
-    network_mode: host
\ No newline at end of file
+    network_mode: host
diff --git a/docker-compose.yml b/docker-compose.yml
index 3fa34a0..2c379f9 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -15,7 +15,7 @@
     networks:
         iotdb-network:
           ipv4_address: 172.18.0.2
-      
+
   iotdb:
    image: apache/iotdb:2.0.1-beta-datanode
    restart: always
@@ -38,7 +38,7 @@
          - dn_rpc_address=iotdb
          - dn_internal_address=iotdb
          - dn_seed_config_node=iotdb-confignode-1:22277
-  
+
   iotdb-confignode-1:
    image: apache/iotdb:2.0.1-beta-confignode
    restart: always
@@ -58,6 +58,6 @@
          - cn_seed_config_node=iotdb-confignode-1:22277
 
 
-networks: 
+networks:
     iotdb-network:
         external: true
diff --git a/launchSettings.json b/launchSettings.json
index cd5bd5a..6f2540e 100644
--- a/launchSettings.json
+++ b/launchSettings.json
@@ -11,4 +11,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/samples/Apache.IoTDB.Samples/Dockerfile b/samples/Apache.IoTDB.Samples/Dockerfile
index 26ee0a9..52b2dcf 100644
--- a/samples/Apache.IoTDB.Samples/Dockerfile
+++ b/samples/Apache.IoTDB.Samples/Dockerfile
@@ -36,4 +36,4 @@
 FROM base AS final
 WORKDIR /app
 COPY --from=publish /app/publish .
-ENTRYPOINT ["dotnet", "Apache.IoTDB.Samples.dll"]
\ No newline at end of file
+ENTRYPOINT ["dotnet", "Apache.IoTDB.Samples.dll"]
diff --git a/samples/Apache.IoTDB.Samples/Program.cs b/samples/Apache.IoTDB.Samples/Program.cs
index bc557bb..b825063 100644
--- a/samples/Apache.IoTDB.Samples/Program.cs
+++ b/samples/Apache.IoTDB.Samples/Program.cs
@@ -35,48 +35,48 @@
             () => "localhost",
             description: "Use single endpoint (e.g. --single localhost)");
 
-        var multiOption = new Option<List<string>>(
-            "--multi",
-            description: "Use multiple endpoints (e.g. --multi localhost:6667 localhost:6668)")
-        {
-            AllowMultipleArgumentsPerToken = true
-        };
+            var multiOption = new Option<List<string>>(
+                "--multi",
+                description: "Use multiple endpoints (e.g. --multi localhost:6667 localhost:6668)")
+            {
+                AllowMultipleArgumentsPerToken = true
+            };
 
-        var rootCommand = new RootCommand
+            var rootCommand = new RootCommand
         {
             singleOption,
             multiOption
         };
 
-        rootCommand.SetHandler(async (string single, List<string> multi) =>
-        {
-            var utilsTest = new UtilsTest();
-            utilsTest.TestParseEndPoint();
-
-            SessionPoolTest sessionPoolTest;
-
-            if (!string.IsNullOrEmpty(single) && (multi == null || multi.Count == 0))
+            rootCommand.SetHandler(async (string single, List<string> multi) =>
             {
-                sessionPoolTest = new SessionPoolTest(single);
-            }
-            else if (multi != null && multi.Count != 0)
-            {
-                sessionPoolTest = new SessionPoolTest(multi);
-            }
-            else
-            {
-                Console.WriteLine("Please specify either --single or --multi endpoints.");
-                return;
-            }
+                var utilsTest = new UtilsTest();
+                utilsTest.TestParseEndPoint();
 
-            await sessionPoolTest.Test();
+                SessionPoolTest sessionPoolTest;
 
-            var tableSessionPoolTest = new TableSessionPoolTest(sessionPoolTest);
-            await tableSessionPoolTest.Test();
+                if (!string.IsNullOrEmpty(single) && (multi == null || multi.Count == 0))
+                {
+                    sessionPoolTest = new SessionPoolTest(single);
+                }
+                else if (multi != null && multi.Count != 0)
+                {
+                    sessionPoolTest = new SessionPoolTest(multi);
+                }
+                else
+                {
+                    Console.WriteLine("Please specify either --single or --multi endpoints.");
+                    return;
+                }
 
-        }, singleOption, multiOption);
+                await sessionPoolTest.Test();
 
-        await rootCommand.InvokeAsync(args);
+                var tableSessionPoolTest = new TableSessionPoolTest(sessionPoolTest);
+                await tableSessionPoolTest.Test();
+
+            }, singleOption, multiOption);
+
+            await rootCommand.InvokeAsync(args);
         }
 
         public static void OpenDebugMode(this SessionPool session)
diff --git a/samples/Apache.IoTDB.Samples/Properties/launchSettings.json b/samples/Apache.IoTDB.Samples/Properties/launchSettings.json
index 8511cd9..8097449 100644
--- a/samples/Apache.IoTDB.Samples/Properties/launchSettings.json
+++ b/samples/Apache.IoTDB.Samples/Properties/launchSettings.json
@@ -7,4 +7,4 @@
       "commandName": "Docker"
     }
   }
-}
\ No newline at end of file
+}
diff --git a/samples/Apache.IoTDB.Samples/SessionPoolTest.AlignedRecord.cs b/samples/Apache.IoTDB.Samples/SessionPoolTest.AlignedRecord.cs
index e43ef35..cb4d8f6 100644
--- a/samples/Apache.IoTDB.Samples/SessionPoolTest.AlignedRecord.cs
+++ b/samples/Apache.IoTDB.Samples/SessionPoolTest.AlignedRecord.cs
@@ -496,4 +496,4 @@
             Console.WriteLine("TestInsertAlignedStringRecordsOfOneDevice Passed!");
         }
     }
-}
\ No newline at end of file
+}
diff --git a/samples/Apache.IoTDB.Samples/SessionPoolTest.AlignedTablet.cs b/samples/Apache.IoTDB.Samples/SessionPoolTest.AlignedTablet.cs
index 1b63271..77050ad 100644
--- a/samples/Apache.IoTDB.Samples/SessionPoolTest.AlignedTablet.cs
+++ b/samples/Apache.IoTDB.Samples/SessionPoolTest.AlignedTablet.cs
@@ -192,4 +192,4 @@
             Console.WriteLine("TestInsertAlignedTablets Passed!");
         }
     }
-}
\ No newline at end of file
+}
diff --git a/samples/Apache.IoTDB.Samples/SessionPoolTest.Record.cs b/samples/Apache.IoTDB.Samples/SessionPoolTest.Record.cs
index 3a7f7c3..4cf68f4 100644
--- a/samples/Apache.IoTDB.Samples/SessionPoolTest.Record.cs
+++ b/samples/Apache.IoTDB.Samples/SessionPoolTest.Record.cs
@@ -305,12 +305,12 @@
                 row = res.Next();
                 break;
             }
-            
+
             Console.WriteLine($"{testDatabaseName}.{testDevice}.{row.Measurements[0]}  {testMeasurements[3]}");
             System.Diagnostics.Debug.Assert($"{testDatabaseName}.{testDevice}.{testMeasurements[3]}" == row.Measurements[0]);
             System.Diagnostics.Debug.Assert($"{testDatabaseName}.{testDevice}.{testMeasurements[1]}" == row.Measurements[1]);
             System.Diagnostics.Debug.Assert($"{testDatabaseName}.{testDevice}.{testMeasurements[2]}" == row.Measurements[2]);
-            
+
             status = await session_pool.DeleteDatabaseAsync(testDatabaseName);
             System.Diagnostics.Debug.Assert(status == 0);
             await session_pool.Close();
@@ -641,7 +641,7 @@
             var rowRecord2 = new RowRecord(2, values2, measurements, dataTypes);
             var rowRecord3 = new RowRecord(3, values3, measurements, dataTypes);
 
-            var device_id = new List<string> { string.Format("{0}.{1}", testDatabaseName, testDevice),string.Format("{0}.{1}", testDatabaseName, testDevice),string.Format("{0}.{1}", testDatabaseName, testDevice) };
+            var device_id = new List<string> { string.Format("{0}.{1}", testDatabaseName, testDevice), string.Format("{0}.{1}", testDatabaseName, testDevice), string.Format("{0}.{1}", testDatabaseName, testDevice) };
             var rowRecords = new List<RowRecord> { rowRecord1, rowRecord2, rowRecord3 };
 
             status = await session_pool.InsertRecordsAsync(device_id, rowRecords);
@@ -664,4 +664,4 @@
             Console.WriteLine("TestInsertRecordsWithAllType Passed!");
         }
     }
-}
\ No newline at end of file
+}
diff --git a/samples/Apache.IoTDB.Samples/SessionPoolTest.Tablet.cs b/samples/Apache.IoTDB.Samples/SessionPoolTest.Tablet.cs
index 299050e..bf2ae17 100644
--- a/samples/Apache.IoTDB.Samples/SessionPoolTest.Tablet.cs
+++ b/samples/Apache.IoTDB.Samples/SessionPoolTest.Tablet.cs
@@ -271,7 +271,7 @@
                 TSDataType.BLOB,
                 TSDataType.STRING
             };
-            var timestamps = new List<long> {1, 2};
+            var timestamps = new List<long> { 1, 2 };
             var tablet = new Tablet(device_id, measurements, datatypes, values, timestamps);
             status = await session_pool.InsertTabletAsync(tablet);
             System.Diagnostics.Debug.Assert(status == 0);
diff --git a/samples/Apache.IoTDB.Samples/SessionPoolTest.Template.cs b/samples/Apache.IoTDB.Samples/SessionPoolTest.Template.cs
index 1d1d84d..866a7ab 100644
--- a/samples/Apache.IoTDB.Samples/SessionPoolTest.Template.cs
+++ b/samples/Apache.IoTDB.Samples/SessionPoolTest.Template.cs
@@ -101,4 +101,4 @@
         }
     }
 
-}
\ No newline at end of file
+}
diff --git a/samples/Apache.IoTDB.Samples/SessionPoolTest.TestNetwork.cs b/samples/Apache.IoTDB.Samples/SessionPoolTest.TestNetwork.cs
index 8588066..9f2a61c 100644
--- a/samples/Apache.IoTDB.Samples/SessionPoolTest.TestNetwork.cs
+++ b/samples/Apache.IoTDB.Samples/SessionPoolTest.TestNetwork.cs
@@ -351,4 +351,4 @@
         }
 
     }
-}
\ No newline at end of file
+}
diff --git a/samples/Apache.IoTDB.Samples/SessionPoolTest.TimeSeries.cs b/samples/Apache.IoTDB.Samples/SessionPoolTest.TimeSeries.cs
index 32be49a..049407c 100644
--- a/samples/Apache.IoTDB.Samples/SessionPoolTest.TimeSeries.cs
+++ b/samples/Apache.IoTDB.Samples/SessionPoolTest.TimeSeries.cs
@@ -194,4 +194,4 @@
         }
     }
 
-}
\ No newline at end of file
+}
diff --git a/samples/Apache.IoTDB.Samples/SessionPoolTest.cs b/samples/Apache.IoTDB.Samples/SessionPoolTest.cs
index f24a0a5..a189461 100644
--- a/samples/Apache.IoTDB.Samples/SessionPoolTest.cs
+++ b/samples/Apache.IoTDB.Samples/SessionPoolTest.cs
@@ -64,7 +64,8 @@
         }
         public async Task Test()
         {
-            if(nodeUrls.Count == 1){
+            if (nodeUrls.Count == 1)
+            {
                 await TestOpenWithNodeUrls();
 
                 await TestOpenWith2NodeUrls();
@@ -147,7 +148,8 @@
 
                 await TestNonSqlBy_ADO();
             }
-            else {            
+            else
+            {
                 await TestMultiNodeDataFetch();
             }
         }
@@ -580,7 +582,8 @@
             Console.WriteLine("LastDataQuery Passed");
         }
 
-        public async Task TestMultiNodeDataFetch(){
+        public async Task TestMultiNodeDataFetch()
+        {
             System.Diagnostics.Debug.Assert(nodeUrls.Count > 1, "nodeUrls.Count should be greater than 1 in MultiNode Test");
             var session_pool = new SessionPool.Builder()
                 .SetUsername(username)
@@ -596,7 +599,7 @@
             var data_type_lst = new List<TSDataType> { TSDataType.BOOLEAN, TSDataType.FLOAT };
             var encoding_lst = new List<TSEncoding> { TSEncoding.PLAIN, TSEncoding.PLAIN };
             var compressor_lst = new List<Compressor> { Compressor.SNAPPY, Compressor.SNAPPY };
-            var ts_path_lst = new List<string>() { 
+            var ts_path_lst = new List<string>() {
                 string.Format("{0}.{1}.{2}", testDatabaseName, testDevice, testMeasurements[0]),
                 string.Format("{0}.{1}.{2}", testDatabaseName, testDevice, testMeasurements[1])
             };
@@ -631,4 +634,4 @@
             Console.WriteLine("MultiNodeDataFetch Passed");
         }
     }
-}
\ No newline at end of file
+}
diff --git a/samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs b/samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs
index c0ef0ec..36d2b88 100644
--- a/samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs
+++ b/samples/Apache.IoTDB.Samples/TableSessionPoolTest.cs
@@ -26,157 +26,157 @@
 
 public class TableSessionPoolTest
 {
-  private readonly SessionPoolTest sessionPoolTest;
+    private readonly SessionPoolTest sessionPoolTest;
 
-  public TableSessionPoolTest(SessionPoolTest sessionPoolTest)
-  {
-    this.sessionPoolTest = sessionPoolTest;
-  }
+    public TableSessionPoolTest(SessionPoolTest sessionPoolTest)
+    {
+        this.sessionPoolTest = sessionPoolTest;
+    }
 
-  public async Task Test()
-  {
-    await TestCleanup();
+    public async Task Test()
+    {
+        await TestCleanup();
 
-    await TestSelectAndInsert();
-    await TestUseDatabase();
-    // await TestCleanup();
-  }
+        await TestSelectAndInsert();
+        await TestUseDatabase();
+        // await TestCleanup();
+    }
 
 
-  public async Task TestSelectAndInsert()
-  {
-    var tableSessionPool = new TableSessionPool.Builder()
-            .SetNodeUrls(sessionPoolTest.nodeUrls)
-            .SetUsername(sessionPoolTest.username)
-            .SetPassword(sessionPoolTest.password)
-            .SetFetchSize(1024)
-            .Build();
+    public async Task TestSelectAndInsert()
+    {
+        var tableSessionPool = new TableSessionPool.Builder()
+                .SetNodeUrls(sessionPoolTest.nodeUrls)
+                .SetUsername(sessionPoolTest.username)
+                .SetPassword(sessionPoolTest.password)
+                .SetFetchSize(1024)
+                .Build();
 
-    await tableSessionPool.Open(false);
+        await tableSessionPool.Open(false);
 
-    if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+        if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
 
 
-    await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE test1");
-    await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE test2");
+        await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE test1");
+        await tableSessionPool.ExecuteNonQueryStatementAsync("CREATE DATABASE test2");
 
-    await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
+        await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
 
-    // or use full qualified table name
-    await tableSessionPool.ExecuteNonQueryStatementAsync(
-        "create table test1.table1(region_id STRING TAG, plant_id STRING TAG, device_id STRING TAG, model STRING ATTRIBUTE, temperature FLOAT FIELD, humidity DOUBLE FIELD) with (TTL=3600000)");
+        // or use full qualified table name
+        await tableSessionPool.ExecuteNonQueryStatementAsync(
+            "create table test1.table1(region_id STRING TAG, plant_id STRING TAG, device_id STRING TAG, model STRING ATTRIBUTE, temperature FLOAT FIELD, humidity DOUBLE FIELD) with (TTL=3600000)");
 
-    await tableSessionPool.ExecuteNonQueryStatementAsync(
-        "create table table2(region_id STRING TAG, plant_id STRING TAG, color STRING ATTRIBUTE, temperature FLOAT FIELD, speed DOUBLE FIELD) with (TTL=6600000)");
+        await tableSessionPool.ExecuteNonQueryStatementAsync(
+            "create table table2(region_id STRING TAG, plant_id STRING TAG, color STRING ATTRIBUTE, temperature FLOAT FIELD, speed DOUBLE FIELD) with (TTL=6600000)");
 
-    // show tables from current database
-    var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
-    res.ShowTableNames();
-    while (res.HasNext()) Console.WriteLine(res.Next());
-    await res.Close();
+        // show tables from current database
+        var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+        res.ShowTableNames();
+        while (res.HasNext()) Console.WriteLine(res.Next());
+        await res.Close();
 
-    // show tables by specifying another database
-    // using SHOW tables FROM
-    res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES FROM test1");
-    res.ShowTableNames();
-    while (res.HasNext()) Console.WriteLine(res.Next());
-    await res.Close();
+        // show tables by specifying another database
+        // using SHOW tables FROM
+        res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES FROM test1");
+        res.ShowTableNames();
+        while (res.HasNext()) Console.WriteLine(res.Next());
+        await res.Close();
 
-    var tableName = "testTable1";
-    List<string> columnNames =
-        new List<string> {
+        var tableName = "testTable1";
+        List<string> columnNames =
+            new List<string> {
             "region_id",
             "plant_id",
             "device_id",
             "model",
             "temperature",
             "humidity" };
-    List<TSDataType> dataTypes =
-        new List<TSDataType>{
+        List<TSDataType> dataTypes =
+            new List<TSDataType>{
             TSDataType.STRING,
             TSDataType.STRING,
             TSDataType.STRING,
             TSDataType.STRING,
             TSDataType.FLOAT,
             TSDataType.DOUBLE};
-    List<ColumnCategory> columnCategories =
-        new List<ColumnCategory>{
+        List<ColumnCategory> columnCategories =
+            new List<ColumnCategory>{
             ColumnCategory.TAG,
             ColumnCategory.TAG,
             ColumnCategory.TAG,
             ColumnCategory.ATTRIBUTE,
             ColumnCategory.FIELD,
             ColumnCategory.FIELD};
-    var values = new List<List<object>> { };
-    var timestamps = new List<long> { };
-    for (long timestamp = 0; timestamp < 100; timestamp++)
-    {
-      timestamps.Add(timestamp);
-      values.Add(new List<object> { "1", "5", "3", "A", 1.23F + timestamp, 111.1 + timestamp });
+        var values = new List<List<object>> { };
+        var timestamps = new List<long> { };
+        for (long timestamp = 0; timestamp < 100; timestamp++)
+        {
+            timestamps.Add(timestamp);
+            values.Add(new List<object> { "1", "5", "3", "A", 1.23F + timestamp, 111.1 + timestamp });
+        }
+        var tablet = new Tablet(tableName, columnNames, columnCategories, dataTypes, values, timestamps);
+
+        await tableSessionPool.InsertAsync(tablet);
+
+
+        res = await tableSessionPool.ExecuteQueryStatementAsync("select * from testTable1 "
+              + "where region_id = '1' and plant_id in ('3', '5') and device_id = '3'");
+        res.ShowTableNames();
+        while (res.HasNext()) Console.WriteLine(res.Next());
+        await res.Close();
+
+        await tableSessionPool.Close();
     }
-    var tablet = new Tablet(tableName, columnNames, columnCategories, dataTypes, values, timestamps);
-
-    await tableSessionPool.InsertAsync(tablet);
 
 
-    res = await tableSessionPool.ExecuteQueryStatementAsync("select * from testTable1 "
-          + "where region_id = '1' and plant_id in ('3', '5') and device_id = '3'");
-    res.ShowTableNames();
-    while (res.HasNext()) Console.WriteLine(res.Next());
-    await res.Close();
+    public async Task TestUseDatabase()
+    {
+        var tableSessionPool = new TableSessionPool.Builder()
+                .SetNodeUrls(sessionPoolTest.nodeUrls)
+                .SetUsername(sessionPoolTest.username)
+                .SetPassword(sessionPoolTest.password)
+                .SetDatabase("test1")
+                .SetFetchSize(1024)
+                .Build();
 
-    await tableSessionPool.Close();
-  }
+        await tableSessionPool.Open(false);
+
+        if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
 
 
-  public async Task TestUseDatabase()
-  {
-    var tableSessionPool = new TableSessionPool.Builder()
-            .SetNodeUrls(sessionPoolTest.nodeUrls)
-            .SetUsername(sessionPoolTest.username)
-            .SetPassword(sessionPoolTest.password)
-            .SetDatabase("test1")
-            .SetFetchSize(1024)
-            .Build();
+        // show tables from current database
+        var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+        res.ShowTableNames();
+        while (res.HasNext()) Console.WriteLine(res.Next());
+        await res.Close();
 
-    await tableSessionPool.Open(false);
+        await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
 
-    if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
+        // show tables from current database
+        res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
+        res.ShowTableNames();
+        while (res.HasNext()) Console.WriteLine(res.Next());
+        await res.Close();
 
+        await tableSessionPool.Close();
+    }
 
-    // show tables from current database
-    var res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
-    res.ShowTableNames();
-    while (res.HasNext()) Console.WriteLine(res.Next());
-    await res.Close();
+    public async Task TestCleanup()
+    {
+        var tableSessionPool = new TableSessionPool.Builder()
+                .SetNodeUrls(sessionPoolTest.nodeUrls)
+                .SetUsername(sessionPoolTest.username)
+                .SetPassword(sessionPoolTest.password)
+                .SetFetchSize(1024)
+                .Build();
 
-    await tableSessionPool.ExecuteNonQueryStatementAsync("use test2");
+        await tableSessionPool.Open(false);
 
-    // show tables from current database
-    res = await tableSessionPool.ExecuteQueryStatementAsync("SHOW TABLES");
-    res.ShowTableNames();
-    while (res.HasNext()) Console.WriteLine(res.Next());
-    await res.Close();
+        if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
 
-    await tableSessionPool.Close();
-  }
+        await tableSessionPool.ExecuteNonQueryStatementAsync("drop database test1");
+        await tableSessionPool.ExecuteNonQueryStatementAsync("drop database test2");
 
-  public async Task TestCleanup()
-  {
-    var tableSessionPool = new TableSessionPool.Builder()
-            .SetNodeUrls(sessionPoolTest.nodeUrls)
-            .SetUsername(sessionPoolTest.username)
-            .SetPassword(sessionPoolTest.password)
-            .SetFetchSize(1024)
-            .Build();
-
-    await tableSessionPool.Open(false);
-
-    if (sessionPoolTest.debug) tableSessionPool.OpenDebugMode();
-
-    await tableSessionPool.ExecuteNonQueryStatementAsync("drop database test1");
-    await tableSessionPool.ExecuteNonQueryStatementAsync("drop database test2");
-
-    await tableSessionPool.Close();
-  }
+        await tableSessionPool.Close();
+    }
 }
diff --git a/src/Apache.IoTDB.Data/DataReaderExtensions.cs b/src/Apache.IoTDB.Data/DataReaderExtensions.cs
index 75f1137..afb8eb7 100644
--- a/src/Apache.IoTDB.Data/DataReaderExtensions.cs
+++ b/src/Apache.IoTDB.Data/DataReaderExtensions.cs
@@ -32,7 +32,7 @@
     {
         public static SessionPool CreateSession(this IoTDBConnectionStringBuilder db)
         {
-            return new SessionPool(db.DataSource, db.Port, db.Username, db.Password, db.FetchSize, db.ZoneId, db.PoolSize,db.Compression,db.TimeOut);
+            return new SessionPool(db.DataSource, db.Port, db.Username, db.Password, db.FetchSize, db.ZoneId, db.PoolSize, db.Compression, db.TimeOut);
         }
 
         public static List<T> ToObject<T>(this IDataReader dataReader)
diff --git a/src/Apache.IoTDB.Data/IoTDBCommand.cs b/src/Apache.IoTDB.Data/IoTDBCommand.cs
index adc9159..8daf86a 100644
--- a/src/Apache.IoTDB.Data/IoTDBCommand.cs
+++ b/src/Apache.IoTDB.Data/IoTDBCommand.cs
@@ -314,7 +314,7 @@
                 Debug.WriteLine($"_commandText:{_commandText}");
 #endif
                 int _affectRows = 0;
-                SessionDataSet dataSet=null;
+                SessionDataSet dataSet = null;
                 bool isok = false;
                 Task<SessionDataSet> taskDataSet = null;
                 if (_parameters.IsValueCreated)
@@ -336,9 +336,9 @@
                     }
                 }
 
-                if (isok && dataSet != null  )
+                if (isok && dataSet != null)
                 {
-                    dataReader = new IoTDBDataReader(this, dataSet, closeConnection  );
+                    dataReader = new IoTDBDataReader(this, dataSet, closeConnection);
                 }
                 else if (taskDataSet.Status == TaskStatus.Running || !isok)
                 {
@@ -354,7 +354,7 @@
                 }
                 else
                 {
-                    IoTDBException.ThrowExceptionForRC(_commandText, new IoTDBErrorResult() { Code = -10007, Error = $"Unknow Exception" });
+                    IoTDBException.ThrowExceptionForRC(_commandText, new IoTDBErrorResult() { Code = -10007, Error = $"Unknown Exception" });
                 }
             }
             catch when (unprepared)
@@ -367,7 +367,7 @@
         private RowRecord BindParamters(IoTDBParameterCollection pms)
         {
             var measures = new List<string>();
-            var values = new List<object> ();
+            var values = new List<object>();
 
 
             for (int i = 0; i < pms.Count; i++)
@@ -375,11 +375,11 @@
 
                 var tp = pms[i];
                 measures.Add(tp.ParameterName);
-             //   _commandText = _commandText.Replace(tp.ParameterName, "?");
+                //   _commandText = _commandText.Replace(tp.ParameterName, "?");
                 switch (TypeInfo.GetTypeCode(tp.Value?.GetType()))
                 {
                     case TypeCode.Boolean:
-                       values.Add ((tp.Value as bool?).GetValueOrDefault());
+                        values.Add((tp.Value as bool?).GetValueOrDefault());
                         break;
                     case TypeCode.Char:
                         values.Add(tp.Value as string);
@@ -431,7 +431,7 @@
                 }
             }
 
-            return   new RowRecord(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),values,measures);
+            return new RowRecord(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), values, measures);
         }
 
         /// <summary>
@@ -523,8 +523,8 @@
                 throw new InvalidOperationException($"CallRequiresSetCommandText{nameof(ExecuteNonQuery)}");
             }
             var result = Task.Run(() => _IoTDB.ExecuteNonQueryStatementAsync(_commandText));
-             var ok = result.Wait(TimeSpan.FromSeconds(CommandTimeout));
-            if (!ok) throw new  TimeoutException();
+            var ok = result.Wait(TimeSpan.FromSeconds(CommandTimeout));
+            if (!ok) throw new TimeoutException();
             return result.Result;
         }
 
diff --git a/src/Apache.IoTDB.Data/IoTDBConnection.cs b/src/Apache.IoTDB.Data/IoTDBConnection.cs
index 860f25e..96b3154 100644
--- a/src/Apache.IoTDB.Data/IoTDBConnection.cs
+++ b/src/Apache.IoTDB.Data/IoTDBConnection.cs
@@ -45,7 +45,7 @@
 
         private string _connectionString;
         private ConnectionState _state;
-        internal SessionPool  _IoTDB;
+        internal SessionPool _IoTDB;
 
 
 
@@ -125,7 +125,7 @@
                 throw new NotImplementedException();
             }
         }
-        public   string ClientVersion
+        public string ClientVersion
         {
             get
             {
@@ -177,7 +177,7 @@
         {
             OpenAsync().GetAwaiter().GetResult();
         }
-        public   override   async Task OpenAsync(CancellationToken cancellationToken=default)
+        public override async Task OpenAsync(CancellationToken cancellationToken = default)
         {
 
             if (State == ConnectionState.Open)
@@ -190,7 +190,7 @@
             }
 
             await _IoTDB.Open(ConnectionStringBuilder.Compression, cancellationToken);
-           if (!_IoTDB.IsOpen())
+            if (!_IoTDB.IsOpen())
             {
                 IoTDBException.ThrowExceptionForRC(-1, "Can't open IoTDB server.");
             }
@@ -214,7 +214,7 @@
 #endif
         {
             if (State != ConnectionState.Closed)
-                await  _IoTDB.Close();
+                await _IoTDB.Close();
             Transaction?.Dispose();
             _nowdatabase = string.Empty;
             foreach (var reference in _commands)
@@ -343,9 +343,9 @@
         }
         internal string _nowdatabase = string.Empty;
 
-        internal bool SelectedDataBase => _nowdatabase != string.Empty ;
+        internal bool SelectedDataBase => _nowdatabase != string.Empty;
 
-        public override string Database => throw new  NotSupportedException();
+        public override string Database => throw new NotSupportedException();
 
         /// <summary>
         ///     Changes the current database.
diff --git a/src/Apache.IoTDB.Data/IoTDBConnectionStringBuilder.cs b/src/Apache.IoTDB.Data/IoTDBConnectionStringBuilder.cs
index 8c71b5e..c2cac87 100644
--- a/src/Apache.IoTDB.Data/IoTDBConnectionStringBuilder.cs
+++ b/src/Apache.IoTDB.Data/IoTDBConnectionStringBuilder.cs
@@ -65,24 +65,24 @@
         private string _userName = "root";
         private string _password = "root";
         private bool _enableRpcCompression = false;
-        private int  _fetchSize = 1800;
+        private int _fetchSize = 1800;
         private string _zoneId = "UTC+08:00";
-        private int  _port = 6667;
-      private   int  _poolSize =8;
-        private int _timeOut=10000;
+        private int _port = 6667;
+        private int _poolSize = 8;
+        private int _timeOut = 10000;
 
         static IoTDBConnectionStringBuilder()
         {
             var validKeywords = new string[9];
             validKeywords[(int)Keywords.DataSource] = DataSourceKeyword;
-             validKeywords[(int)Keywords.Username] = UserNameKeyword;
+            validKeywords[(int)Keywords.Username] = UserNameKeyword;
             validKeywords[(int)Keywords.Password] = PasswordKeyword;
             validKeywords[(int)Keywords.Port] = PortKeyword;
             validKeywords[(int)Keywords.FetchSize] = FetchSizeKeyword;
             validKeywords[(int)Keywords.Compression] = CompressionKeyword;
             validKeywords[(int)Keywords.PoolSize] = PoolSizeKeyword;
             validKeywords[(int)Keywords.ZoneId] = ZoneIdKeyword;
-            validKeywords[(int)Keywords.TimeOut] =TimeOutKeyword;
+            validKeywords[(int)Keywords.TimeOut] = TimeOutKeyword;
             _validKeywords = validKeywords;
 
             _keywords = new Dictionary<string, Keywords>(9, StringComparer.OrdinalIgnoreCase)
@@ -129,13 +129,13 @@
             get => _userName;
             set => base[UserNameKeyword] = _userName = value;
         }
-  
+
         public virtual string Password
         {
             get => _password;
             set => base[PasswordKeyword] = _password = value;
         }
-        public virtual int  Port
+        public virtual int Port
         {
             get => _port;
             set => base[PortKeyword] = _port = value;
@@ -163,7 +163,7 @@
         }
 
         public virtual int TimeOut
-    {
+        {
             get => _timeOut;
             set => base[PoolSizeKeyword] = _timeOut = value;
         }
@@ -215,19 +215,19 @@
 
                     return;
                 }
-           
+
                 switch (GetIndex(keyword))
                 {
                     case Keywords.DataSource:
                         DataSource = Convert.ToString(value, CultureInfo.InvariantCulture);
                         return;
                     case Keywords.Username:
-                        Username= Convert.ToString(value, CultureInfo.InvariantCulture);
+                        Username = Convert.ToString(value, CultureInfo.InvariantCulture);
                         return;
                     case Keywords.Password:
                         Password = Convert.ToString(value, CultureInfo.InvariantCulture);
                         return;
-      
+
                     case Keywords.Port:
                         Port = Convert.ToInt32(value, CultureInfo.InvariantCulture);
                         return;
@@ -354,7 +354,7 @@
 
         private object GetAt(Keywords index)
         {
-  
+
             switch (index)
             {
                 case Keywords.DataSource:
@@ -363,7 +363,7 @@
                     return Password;
                 case Keywords.Username:
                     return Username;
-    
+
                 case Keywords.Port:
                     return Port;
                 case Keywords.FetchSize:
@@ -401,7 +401,7 @@
                     _userName = "root";
                     return;
                 case Keywords.Port:
-                    _port=6667;
+                    _port = 6667;
                     return;
                 case Keywords.FetchSize:
                     _fetchSize = 1800;
diff --git a/src/Apache.IoTDB.Data/IoTDBDataReader.cs b/src/Apache.IoTDB.Data/IoTDBDataReader.cs
index 88c4de2..da4f107 100644
--- a/src/Apache.IoTDB.Data/IoTDBDataReader.cs
+++ b/src/Apache.IoTDB.Data/IoTDBDataReader.cs
@@ -41,12 +41,12 @@
         private bool _hasRows;
         private readonly int _recordsAffected;
         private bool _closed;
-        private readonly  List<string> _metas;
+        private readonly List<string> _metas;
         private bool _closeConnection;
 
         private int _fieldCount;
 
-        RowRecord rowdata= null;
+        RowRecord rowdata = null;
 
 
         SessionDataSet _dataSet;
@@ -57,7 +57,7 @@
             _closeConnection = closeConnection;
             _fieldCount = dataSet.ColumnNames.Count;
             _hasRows = dataSet.RowCount > 0;
-            _recordsAffected =dataSet.RowCount;
+            _recordsAffected = dataSet.RowCount;
             _closed = _closeConnection;
             _metas = dataSet.ColumnNames;
             _dataSet = dataSet;
@@ -73,7 +73,7 @@
         ///     Gets the number of columns in the current row.
         /// </summary>
         /// <value>The number of columns in the current row.</value>
-        public override int FieldCount => _fieldCount+1;
+        public override int FieldCount => _fieldCount + 1;
 
         /// <summary>
         ///     Gets a value indicating whether the data reader contains any rows.
@@ -178,7 +178,7 @@
             _dataSet.Close().GetAwaiter().GetResult();
             _command.DataReader = null;
 
-            if (_closeConnection  )
+            if (_closeConnection)
             {
                 _command.Connection.Close();
                 _closed = true;
@@ -194,7 +194,7 @@
         /// <returns>The name of the column.</returns>
         public override string GetName(int ordinal)
         {
-            return ordinal==0? "timestamp" : rowdata.Measurements[ordinal-1];
+            return ordinal == 0 ? "timestamp" : rowdata.Measurements[ordinal - 1];
         }
 
         /// <summary>
@@ -203,7 +203,7 @@
         /// <param name="name">The name of the column.</param>
         /// <returns>The zero-based column ordinal.</returns>
         public override int GetOrdinal(string name)
-            => "timestamp"==name?0: rowdata.Measurements.IndexOf(  name)+1;
+            => "timestamp" == name ? 0 : rowdata.Measurements.IndexOf(name) + 1;
 
         public override string GetDataTypeName(int ordinal)
         {
@@ -218,7 +218,7 @@
         public override Type GetFieldType(int ordinal)
         {
 
-            return ordinal==0?typeof(DateTime): rowdata.GetCrlType(ordinal-1);
+            return ordinal == 0 ? typeof(DateTime) : rowdata.GetCrlType(ordinal - 1);
         }
 
         /// <summary>
@@ -438,9 +438,9 @@
             for (int i = 0; i < _fieldCount; i++)
             {
                 var obj = rowdata.Values[i];
-                if (obj != null  )
+                if (obj != null)
                 {
-                    values[i+1] = obj;
+                    values[i + 1] = obj;
                     count++;
                 }
             }
@@ -458,8 +458,8 @@
             {
                 rowdata = _dataSet.GetRow();
             }
-                   var schemaTable = new DataTable("SchemaTable");
-            if (_metas != null && rowdata !=null)
+            var schemaTable = new DataTable("SchemaTable");
+            if (_metas != null && rowdata != null)
             {
                 var ColumnName = new DataColumn(SchemaTableColumn.ColumnName, typeof(string));
                 var ColumnOrdinal = new DataColumn(SchemaTableColumn.ColumnOrdinal, typeof(int));
@@ -534,11 +534,11 @@
                 schemaTable.Rows.Add(schemaRow1);
 
 
-                for (var i = 1; i < rowdata.Measurements.Count+1; i++)
+                for (var i = 1; i < rowdata.Measurements.Count + 1; i++)
                 {
                     var schemaRow = schemaTable.NewRow();
 
-                    var columnName = rowdata.Measurements[i-1] ;
+                    var columnName = rowdata.Measurements[i - 1];
                     schemaRow[ColumnName] = columnName;
                     schemaRow[ColumnOrdinal] = i;
 
@@ -554,7 +554,7 @@
                     schemaRow[DataTypeName] = GetDataTypeName(i);
                     schemaRow[IsExpression] = columnName == null;
                     schemaRow[IsLong] = DBNull.Value;
-                    schemaRow[IsKey]= false;
+                    schemaRow[IsKey] = false;
                     schemaRow[AllowDBNull] = true;
                     schemaTable.Rows.Add(schemaRow);
                 }
diff --git a/src/Apache.IoTDB.Data/IoTDBException.cs b/src/Apache.IoTDB.Data/IoTDBException.cs
index 978c9e8..2f39125 100644
--- a/src/Apache.IoTDB.Data/IoTDBException.cs
+++ b/src/Apache.IoTDB.Data/IoTDBException.cs
@@ -47,7 +47,7 @@
 
 
         public override string Message => _IoTDBError?.Error;
-        public override int ErrorCode =>   (int) _IoTDBError?.Code;
+        public override int ErrorCode => (int)_IoTDBError?.Code;
         /// <summary>
         ///     Throws an exception with a specific IoTDB error code value.
         /// </summary>
@@ -58,29 +58,29 @@
         /// </remarks>
         public static void ThrowExceptionForRC(string _commandText, IoTDBErrorResult IoTDBError)
         {
-            var te = new IoTDBException(IoTDBError);
-            te.Data.Add("commandText", _commandText);
-            throw te;
+            var tmp_exception = new IoTDBException(IoTDBError);
+            tmp_exception.Data.Add("commandText", _commandText);
+            throw tmp_exception;
         }
-        public static void ThrowExceptionForRC( IoTDBErrorResult IoTDBError)
+        public static void ThrowExceptionForRC(IoTDBErrorResult IoTDBError)
         {
-            var te = new IoTDBException(IoTDBError);
-            throw te;
+            var tmp_exception = new IoTDBException(IoTDBError);
+            throw tmp_exception;
         }
         public static void ThrowExceptionForRC(IntPtr _IoTDB)
         {
-            var te = new IoTDBException(new IoTDBErrorResult() {   });
-            throw te;
+            var tmp_exception = new IoTDBException(new IoTDBErrorResult() { });
+            throw tmp_exception;
         }
         public static void ThrowExceptionForRC(int code, string message, Exception ex)
         {
-            var te = new IoTDBException(new IoTDBErrorResult() { Code = code, Error = message }, ex);
-            throw te;
+            var tmp_exception = new IoTDBException(new IoTDBErrorResult() { Code = code, Error = message }, ex);
+            throw tmp_exception;
         }
         public static void ThrowExceptionForRC(int code, string message)
         {
-            var te = new IoTDBException(new IoTDBErrorResult() { Code = code, Error = message });
-            throw te;
+            var tmp_exception = new IoTDBException(new IoTDBErrorResult() { Code = code, Error = message });
+            throw tmp_exception;
         }
     }
 }
diff --git a/src/Apache.IoTDB.Data/IoTDBParameter.cs b/src/Apache.IoTDB.Data/IoTDBParameter.cs
index 03b7667..f49ea99 100644
--- a/src/Apache.IoTDB.Data/IoTDBParameter.cs
+++ b/src/Apache.IoTDB.Data/IoTDBParameter.cs
@@ -17,7 +17,7 @@
  * under the License.
  */
 
- using System;
+using System;
 using System.Data;
 using System.Data.Common;
 
@@ -42,7 +42,7 @@
         public IoTDBParameter()
         {
         }
-       
+
         /// <summary>
         ///     Initializes a new instance of the <see cref="IoTDBParameter" /> class.
         /// </summary>
@@ -101,7 +101,7 @@
         /// </summary>
         /// <value>The type of the parameter.</value>
         /// <remarks>Due to IoTDB's dynamic type system, parameter values are not converted.</remarks>
- 
+
         public override DbType DbType { get; set; } = DbType.String;
 
         /// <summary>
@@ -221,6 +221,6 @@
             IoTDBType = TSDataType.NONE;
         }
 
-        
+
     }
 }
diff --git a/src/Apache.IoTDB.Data/IoTDBParameterCollection.cs b/src/Apache.IoTDB.Data/IoTDBParameterCollection.cs
index 201448d..830e1e6 100644
--- a/src/Apache.IoTDB.Data/IoTDBParameterCollection.cs
+++ b/src/Apache.IoTDB.Data/IoTDBParameterCollection.cs
@@ -183,7 +183,7 @@
         /// <param name="parameterName">The name of the parameter.</param>
         /// <param name="value">The value of the parameter. Can be null.</param>
         /// <returns>The parameter that was added.</returns>
-        public virtual IoTDBParameter AddWithValue( object value)
+        public virtual IoTDBParameter AddWithValue(object value)
         {
             var parameter = new IoTDBParameter(Guid.NewGuid().ToString(), value);
             Add(parameter);
@@ -354,7 +354,7 @@
         protected override void SetParameter(string parameterName, DbParameter value)
             => SetParameter(IndexOfChecked(parameterName), value);
 
-      
+
 
         private int IndexOfChecked(string parameterName)
         {
diff --git a/src/Apache.IoTDB.Data/IoTDBResult.cs b/src/Apache.IoTDB.Data/IoTDBResult.cs
index 1da73f2..fae9066 100644
--- a/src/Apache.IoTDB.Data/IoTDBResult.cs
+++ b/src/Apache.IoTDB.Data/IoTDBResult.cs
@@ -26,10 +26,10 @@
     public class IoTDBErrorResult
     {
 
-        public int Code  { get; set; }
+        public int Code { get; set; }
         /// <summary>
         ///
         /// </summary>
-        public string Error  { get; set; }
+        public string Error { get; set; }
     }
 }
diff --git a/src/Apache.IoTDB.Data/IoTDBTransaction.cs b/src/Apache.IoTDB.Data/IoTDBTransaction.cs
index a0a4c79..34fc547 100644
--- a/src/Apache.IoTDB.Data/IoTDBTransaction.cs
+++ b/src/Apache.IoTDB.Data/IoTDBTransaction.cs
@@ -62,7 +62,7 @@
         /// </summary>
         /// <value>The isolation level for the transaction.</value>
         public override IsolationLevel IsolationLevel => IsolationLevel.Unspecified;
-         
+
 
         /// <summary>
         ///     Applies the changes made in the transaction.
@@ -73,7 +73,7 @@
             //{
             //    throw new InvalidOperationException(Resources.TransactionCompleted);
             //}
- 
+
             //_connection.ExecuteNonQuery("COMMIT;");
             Complete();
         }
@@ -109,7 +109,7 @@
 
         private void Complete()
         {
-            if (_connection!=null)_connection.Transaction = null;
+            if (_connection != null) _connection.Transaction = null;
             _connection = null;
             _completed = true;
         }
diff --git a/src/Apache.IoTDB/Client.cs b/src/Apache.IoTDB/Client.cs
index dead7b6..03238d2 100644
--- a/src/Apache.IoTDB/Client.cs
+++ b/src/Apache.IoTDB/Client.cs
@@ -38,4 +38,4 @@
             EndPoint = endpoint;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/ConcurrentClientQueue.cs b/src/Apache.IoTDB/ConcurrentClientQueue.cs
index 0c54a12..e53d3f3 100644
--- a/src/Apache.IoTDB/ConcurrentClientQueue.cs
+++ b/src/Apache.IoTDB/ConcurrentClientQueue.cs
@@ -71,7 +71,8 @@
         {
             Client client = null;
             Monitor.Enter(ClientQueue);
-            while(true){
+            while (true)
+            {
                 bool timeout = false;
                 if (ClientQueue.IsEmpty)
                 {
@@ -79,7 +80,8 @@
                 }
                 ClientQueue.TryDequeue(out client);
 
-                if(client != null || timeout){
+                if (client != null || timeout)
+                {
                     break;
                 }
             }
@@ -91,4 +93,4 @@
             return client;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/DataStructure/BitMap.cs b/src/Apache.IoTDB/DataStructure/BitMap.cs
index d5a66c6..5a1b607 100644
--- a/src/Apache.IoTDB/DataStructure/BitMap.cs
+++ b/src/Apache.IoTDB/DataStructure/BitMap.cs
@@ -146,4 +146,4 @@
         }
         return true;
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/DataStructure/ByteBuffer.cs b/src/Apache.IoTDB/DataStructure/ByteBuffer.cs
index b97583f..a3e1823 100644
--- a/src/Apache.IoTDB/DataStructure/ByteBuffer.cs
+++ b/src/Apache.IoTDB/DataStructure/ByteBuffer.cs
@@ -135,10 +135,10 @@
 
         public byte[] GetBinary()
         {
-          var length = GetInt();
-          var buff = _buffer[_readPos..(_readPos + length)];
-          _readPos += length;
-          return buff;
+            var length = GetInt();
+            var buff = _buffer[_readPos..(_readPos + length)];
+            _readPos += length;
+            return buff;
         }
 
         public byte[] GetBuffer()
@@ -225,7 +225,7 @@
             _writePos += strBuf.Length;
         }
 
-         public void AddBinary(byte[] value)
+        public void AddBinary(byte[] value)
         {
             AddInt(value.Length);
 
@@ -251,4 +251,4 @@
             _writePos += 1;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/DataStructure/RowRecord.cs b/src/Apache.IoTDB/DataStructure/RowRecord.cs
index 9674f49..c5853bf 100644
--- a/src/Apache.IoTDB/DataStructure/RowRecord.cs
+++ b/src/Apache.IoTDB/DataStructure/RowRecord.cs
@@ -32,18 +32,18 @@
         public List<TSDataType> DataTypes { get; }
 
         public RowRecord(DateTime timestamp, List<object> values, List<string> measurements, List<string> dataTypes)
-            :this(new DateTimeOffset(timestamp.ToUniversalTime()).ToUnixTimeMilliseconds(), values,measurements, dataTypes)
+            : this(new DateTimeOffset(timestamp.ToUniversalTime()).ToUnixTimeMilliseconds(), values, measurements, dataTypes)
         {
         }
 
         public RowRecord(DateTime timestamp, List<object> values, List<string> measurements, List<TSDataType> dataTypes)
-            :this(new DateTimeOffset(timestamp.ToUniversalTime()).ToUnixTimeMilliseconds(), values,measurements, dataTypes)
+            : this(new DateTimeOffset(timestamp.ToUniversalTime()).ToUnixTimeMilliseconds(), values, measurements, dataTypes)
         {
         }
 
         [Obsolete("Use the constructor with List<TSDataType> instead")]
         public RowRecord(DateTime timestamp, List<object> values, List<string> measurements)
-            :this(new DateTimeOffset(timestamp.ToUniversalTime()).ToUnixTimeMilliseconds(), values,measurements)
+            : this(new DateTimeOffset(timestamp.ToUniversalTime()).ToUnixTimeMilliseconds(), values, measurements)
         {
         }
         [Obsolete("Use the constructor with List<TSDataType> instead")]
@@ -53,7 +53,8 @@
             Values = values;
             Measurements = measurements;
         }
-        public RowRecord(long timestamps, List<object> values, List<string> measurements, List<string> dataTypes){
+        public RowRecord(long timestamps, List<object> values, List<string> measurements, List<string> dataTypes)
+        {
             Timestamps = timestamps;
             Values = values;
             Measurements = measurements;
@@ -132,27 +133,27 @@
             foreach (var rowValue in Values)
             {
                 str += "\t\t";
-                if(rowValue is byte[] bytes)
+                if (rowValue is byte[] bytes)
                 {
-                  str += Utils.ByteArrayToHexString(bytes);
+                    str += Utils.ByteArrayToHexString(bytes);
                 }
                 else
                 {
-                  str += rowValue.ToString();
+                    str += rowValue.ToString();
                 }
             }
 
             return str;
         }
-        
+
         public Type GetCrlType(int index)
         {
-            Type tSDataType =  typeof(object);
+            Type tSDataType = typeof(object);
             var valueType = Values[index];
             switch (valueType)
             {
                 case bool _:
-                    tSDataType = typeof( bool);
+                    tSDataType = typeof(bool);
                     break;
                 case int _:
                     tSDataType = typeof(int);
@@ -190,43 +191,43 @@
                 switch (dataType)
                 {
                     case TSDataType.BOOLEAN:
-                        buffer.AddByte((byte) TSDataType.BOOLEAN);
+                        buffer.AddByte((byte)TSDataType.BOOLEAN);
                         buffer.AddBool((bool)value);
                         break;
                     case TSDataType.INT32:
-                        buffer.AddByte((byte) TSDataType.INT32);
+                        buffer.AddByte((byte)TSDataType.INT32);
                         buffer.AddInt((int)value);
                         break;
                     case TSDataType.INT64:
-                        buffer.AddByte((byte) TSDataType.INT64);
+                        buffer.AddByte((byte)TSDataType.INT64);
                         buffer.AddLong((long)value);
                         break;
                     case TSDataType.FLOAT:
-                        buffer.AddByte((byte) TSDataType.FLOAT);
+                        buffer.AddByte((byte)TSDataType.FLOAT);
                         buffer.AddFloat((float)value);
                         break;
                     case TSDataType.DOUBLE:
-                        buffer.AddByte((byte) TSDataType.DOUBLE);
+                        buffer.AddByte((byte)TSDataType.DOUBLE);
                         buffer.AddDouble((double)value);
                         break;
                     case TSDataType.TEXT:
-                        buffer.AddByte((byte) TSDataType.TEXT);
+                        buffer.AddByte((byte)TSDataType.TEXT);
                         buffer.AddStr((string)value);
                         break;
                     case TSDataType.TIMESTAMP:
-                        buffer.AddByte((byte) TSDataType.TIMESTAMP);
+                        buffer.AddByte((byte)TSDataType.TIMESTAMP);
                         buffer.AddLong((long)value);
                         break;
                     case TSDataType.BLOB:
-                        buffer.AddByte((byte) TSDataType.BLOB);
+                        buffer.AddByte((byte)TSDataType.BLOB);
                         buffer.AddBinary((byte[])value);
                         break;
                     case TSDataType.DATE:
-                        buffer.AddByte((byte) TSDataType.DATE);
+                        buffer.AddByte((byte)TSDataType.DATE);
                         buffer.AddInt(Utils.ParseDateToInt((DateTime)value));
                         break;
                     case TSDataType.STRING:
-                        buffer.AddByte((byte) TSDataType.STRING);
+                        buffer.AddByte((byte)TSDataType.STRING);
                         buffer.AddStr((string)value);
                         break;
                     default:
@@ -262,4 +263,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/DataStructure/SessionDataSet.cs b/src/Apache.IoTDB/DataStructure/SessionDataSet.cs
index 7ba49ea..3d606f4 100644
--- a/src/Apache.IoTDB/DataStructure/SessionDataSet.cs
+++ b/src/Apache.IoTDB/DataStructure/SessionDataSet.cs
@@ -81,18 +81,25 @@
 
             int deduplicateIdx = 0;
             Dictionary<string, int> columnToFirstIndexMap = new Dictionary<string, int>();
-            for(var i = 0; i < _columnSize; i++){
+            for (var i = 0; i < _columnSize; i++)
+            {
                 var columnName = _columnNames[i];
-                if(_columnNameIndexMap.ContainsKey(columnName)){
+                if (_columnNameIndexMap.ContainsKey(columnName))
+                {
                     _duplicateLocation[i] = columnToFirstIndexMap[columnName];
-                } else {
+                }
+                else
+                {
                     columnToFirstIndexMap[columnName] = i;
-                    if(resp.ColumnNameIndexMap != null) {
+                    if (resp.ColumnNameIndexMap != null)
+                    {
                         int valueIndex = resp.ColumnNameIndexMap[columnName];
                         _columnNameIndexMap[columnName] = valueIndex;
                         _valueBufferLst.Add(new ByteBuffer(_queryDataset.ValueList[valueIndex]));
                         _bitmapBufferLst.Add(new ByteBuffer(_queryDataset.BitmapList[valueIndex]));
-                    } else {
+                    }
+                    else
+                    {
                         _columnNameIndexMap[columnName] = deduplicateIdx;
                         _valueBufferLst.Add(new ByteBuffer(_queryDataset.ValueList[deduplicateIdx]));
                         _bitmapBufferLst.Add(new ByteBuffer(_queryDataset.BitmapList[deduplicateIdx]));
@@ -182,14 +189,14 @@
 
         private void ConstructOneRow()
         {
-            List<object> fieldLst = new List<Object>();
+            List<object> fieldList = new List<Object>();
 
             for (int i = 0; i < _columnSize; i++)
             {
                 if (_duplicateLocation.ContainsKey(i))
                 {
-                    var field = fieldLst[_duplicateLocation[i]];
-                    fieldLst.Add(field);
+                    var field = fieldList[_duplicateLocation[i]];
+                    fieldList.Add(field);
                 }
                 else
                 {
@@ -213,7 +220,7 @@
                                 localField = columnValueBuffer.GetBool();
                                 break;
                             case TSDataType.INT32:
-                            // case TSDataType.DATE:
+                                // case TSDataType.DATE:
                                 localField = columnValueBuffer.GetInt();
                                 break;
                             case TSDataType.DATE:
@@ -231,7 +238,7 @@
                                 break;
                             case TSDataType.TEXT:
                             case TSDataType.STRING:
-                            // case TSDataType.BLOB:
+                                // case TSDataType.BLOB:
                                 localField = columnValueBuffer.GetStr();
                                 break;
                             case TSDataType.BLOB:
@@ -243,19 +250,19 @@
                                 throw new TException(err_msg, null);
                         }
 
-                        fieldLst.Add(localField);
+                        fieldList.Add(localField);
                     }
                     else
                     {
                         localField = null;
-                        fieldLst.Add(DBNull.Value);
+                        fieldList.Add(DBNull.Value);
                     }
                 }
             }
 
             long timestamp = _timeBuffer.GetLong();
             _rowIndex += 1;
-            _cachedRowRecord = new RowRecord(timestamp, fieldLst, _columnNames);
+            _cachedRowRecord = new RowRecord(timestamp, fieldList, _columnNames);
         }
 
         private bool IsNull(int loc, int row_index)
@@ -359,4 +366,4 @@
             GC.SuppressFinalize(this);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/DataStructure/Tablet.cs b/src/Apache.IoTDB/DataStructure/Tablet.cs
index b6e2ca1..34007ee 100644
--- a/src/Apache.IoTDB/DataStructure/Tablet.cs
+++ b/src/Apache.IoTDB/DataStructure/Tablet.cs
@@ -38,7 +38,7 @@
     *
     * @deprecated
     * Notice: The tablet should not have empty cell
-    * 
+    *
     * From 0.13 IoTDB Server, tablet could have empty cell
     *
     */
@@ -471,4 +471,4 @@
             return buffer.GetBuffer();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/IoTDBConstants.cs b/src/Apache.IoTDB/IoTDBConstants.cs
index 7dddd72..13fe80e 100644
--- a/src/Apache.IoTDB/IoTDBConstants.cs
+++ b/src/Apache.IoTDB/IoTDBConstants.cs
@@ -96,8 +96,9 @@
 
         private TsFileConstant() { }
     }
-    public class IoTDBConstant {
+    public class IoTDBConstant
+    {
         public static string TREE_SQL_DIALECT = "tree";
         public static string TABLE_SQL_DIALECT = "table";
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/SessionPool.Builder.cs b/src/Apache.IoTDB/SessionPool.Builder.cs
index fcd10ce..69b8e42 100644
--- a/src/Apache.IoTDB/SessionPool.Builder.cs
+++ b/src/Apache.IoTDB/SessionPool.Builder.cs
@@ -24,116 +24,116 @@
 
 public partial class SessionPool
 {
-  public class Builder
-  {
-    private string _host = "localhost";
-    private int _port = 6667;
-    private string _username = "root";
-    private string _password = "root";
-    private int _fetchSize = 1024;
-    private string _zoneId = "UTC+08:00";
-    private int _poolSize = 8;
-    private bool _enableRpcCompression = false;
-    private int _connectionTimeoutInMs = 500;
-    private string _sqlDialect = IoTDBConstant.TREE_SQL_DIALECT;
-    private string _database = "";
-    private List<string> _nodeUrls = new List<string>();
-
-    public Builder SetHost(string host)
+    public class Builder
     {
-      _host = host;
-      return this;
-    }
+        private string _host = "localhost";
+        private int _port = 6667;
+        private string _username = "root";
+        private string _password = "root";
+        private int _fetchSize = 1024;
+        private string _zoneId = "UTC+08:00";
+        private int _poolSize = 8;
+        private bool _enableRpcCompression = false;
+        private int _connectionTimeoutInMs = 500;
+        private string _sqlDialect = IoTDBConstant.TREE_SQL_DIALECT;
+        private string _database = "";
+        private List<string> _nodeUrls = new List<string>();
 
-    public Builder SetPort(int port)
-    {
-      _port = port;
-      return this;
-    }
+        public Builder SetHost(string host)
+        {
+            _host = host;
+            return this;
+        }
 
-    public Builder SetUsername(string username)
-    {
-      _username = username;
-      return this;
-    }
+        public Builder SetPort(int port)
+        {
+            _port = port;
+            return this;
+        }
 
-    public Builder SetPassword(string password)
-    {
-      _password = password;
-      return this;
-    }
+        public Builder SetUsername(string username)
+        {
+            _username = username;
+            return this;
+        }
 
-    public Builder SetFetchSize(int fetchSize)
-    {
-      _fetchSize = fetchSize;
-      return this;
-    }
+        public Builder SetPassword(string password)
+        {
+            _password = password;
+            return this;
+        }
 
-    public Builder SetZoneId(string zoneId)
-    {
-      _zoneId = zoneId;
-      return this;
-    }
+        public Builder SetFetchSize(int fetchSize)
+        {
+            _fetchSize = fetchSize;
+            return this;
+        }
 
-    public Builder SetPoolSize(int poolSize)
-    {
-      _poolSize = poolSize;
-      return this;
-    }
+        public Builder SetZoneId(string zoneId)
+        {
+            _zoneId = zoneId;
+            return this;
+        }
 
-    public Builder SetEnableRpcCompression(bool enableRpcCompression)
-    {
-      _enableRpcCompression = enableRpcCompression;
-      return this;
-    }
+        public Builder SetPoolSize(int poolSize)
+        {
+            _poolSize = poolSize;
+            return this;
+        }
 
-    public Builder SetConnectionTimeoutInMs(int timeout)
-    {
-      _connectionTimeoutInMs = timeout;
-      return this;
-    }
+        public Builder SetEnableRpcCompression(bool enableRpcCompression)
+        {
+            _enableRpcCompression = enableRpcCompression;
+            return this;
+        }
 
-    public Builder SetNodeUrl(List<string> nodeUrls)
-    {
-      _nodeUrls = nodeUrls;
-      return this;
-    }
+        public Builder SetConnectionTimeoutInMs(int timeout)
+        {
+            _connectionTimeoutInMs = timeout;
+            return this;
+        }
 
-    protected internal Builder SetSqlDialect(string sqlDialect)
-    {
-      _sqlDialect = sqlDialect;
-      return this;
-    }
+        public Builder SetNodeUrl(List<string> nodeUrls)
+        {
+            _nodeUrls = nodeUrls;
+            return this;
+        }
 
-    protected internal Builder SetDatabase(string database)
-    {
-      _database = database;
-      return this;
-    }
+        protected internal Builder SetSqlDialect(string sqlDialect)
+        {
+            _sqlDialect = sqlDialect;
+            return this;
+        }
 
-    public Builder()
-    {
-      _host = "localhost";
-      _port = 6667;
-      _username = "root";
-      _password = "root";
-      _fetchSize = 1024;
-      _zoneId = "UTC+08:00";
-      _poolSize = 8;
-      _enableRpcCompression = false;
-      _connectionTimeoutInMs = 500;
-      _sqlDialect = IoTDBConstant.TREE_SQL_DIALECT;
-      _database = "";
-    }
+        protected internal Builder SetDatabase(string database)
+        {
+            _database = database;
+            return this;
+        }
 
-    public SessionPool Build()
-    {
-      // if nodeUrls is not empty, use nodeUrls to create session pool
-      if (_nodeUrls.Count > 0)
-      {
-        return new SessionPool(_nodeUrls, _username, _password, _fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs, _sqlDialect, _database);
-      }
-      return new SessionPool(_host, _port, _username, _password, _fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs, _sqlDialect, _database);
+        public Builder()
+        {
+            _host = "localhost";
+            _port = 6667;
+            _username = "root";
+            _password = "root";
+            _fetchSize = 1024;
+            _zoneId = "UTC+08:00";
+            _poolSize = 8;
+            _enableRpcCompression = false;
+            _connectionTimeoutInMs = 500;
+            _sqlDialect = IoTDBConstant.TREE_SQL_DIALECT;
+            _database = "";
+        }
+
+        public SessionPool Build()
+        {
+            // if nodeUrls is not empty, use nodeUrls to create session pool
+            if (_nodeUrls.Count > 0)
+            {
+                return new SessionPool(_nodeUrls, _username, _password, _fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs, _sqlDialect, _database);
+            }
+            return new SessionPool(_host, _port, _username, _password, _fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs, _sqlDialect, _database);
+        }
     }
-  }
 }
diff --git a/src/Apache.IoTDB/SessionPool.cs b/src/Apache.IoTDB/SessionPool.cs
index c6bd70f..0fb9089 100644
--- a/src/Apache.IoTDB/SessionPool.cs
+++ b/src/Apache.IoTDB/SessionPool.cs
@@ -35,1750 +35,1749 @@
 namespace Apache.IoTDB
 {
 
-  public partial class SessionPool : IDisposable
-  {
-    private static readonly TSProtocolVersion ProtocolVersion = TSProtocolVersion.IOTDB_SERVICE_PROTOCOL_V3;
+    public partial class SessionPool : IDisposable
+    {
+        private static readonly TSProtocolVersion ProtocolVersion = TSProtocolVersion.IOTDB_SERVICE_PROTOCOL_V3;
 
-    private readonly string _username;
-    private readonly string _password;
-    private bool _enableRpcCompression;
-    private string _zoneId;
-    private readonly List<string> _nodeUrls = new();
-    private readonly List<TEndPoint> _endPoints = new();
-    private readonly string _host;
-    private readonly int _port;
-    private readonly int _fetchSize;
-    /// <summary>
-    /// _timeout is the amount of time a Session will wait for a send operation to complete successfully.
-    /// </summary>
-    private readonly int _timeout;
-    private readonly int _poolSize = 4;
-    private readonly string _sqlDialect = IoTDBConstant.TREE_SQL_DIALECT;
-    private string _database;
-    private readonly Utils _utilFunctions = new();
-    private const int RetryNum = 3;
-    private bool _debugMode;
-    private bool _isClose = true;
-    private ConcurrentClientQueue _clients;
-    private ILogger _logger;
-    public delegate Task<TResult> AsyncOperation<TResult>(Client client);
+        private readonly string _username;
+        private readonly string _password;
+        private bool _enableRpcCompression;
+        private string _zoneId;
+        private readonly List<string> _nodeUrls = new();
+        private readonly List<TEndPoint> _endPoints = new();
+        private readonly string _host;
+        private readonly int _port;
+        private readonly int _fetchSize;
+        /// <summary>
+        /// _timeout is the amount of time a Session will wait for a send operation to complete successfully.
+        /// </summary>
+        private readonly int _timeout;
+        private readonly int _poolSize = 4;
+        private readonly string _sqlDialect = IoTDBConstant.TREE_SQL_DIALECT;
+        private string _database;
+        private readonly Utils _utilFunctions = new();
+        private const int RetryNum = 3;
+        private bool _debugMode;
+        private bool _isClose = true;
+        private ConcurrentClientQueue _clients;
+        private ILogger _logger;
+        public delegate Task<TResult> AsyncOperation<TResult>(Client client);
 
 
-    [Obsolete("This method is deprecated, please use new SessionPool.Builder().")]
-    public SessionPool(string host, int port, int poolSize)
-                    : this(host, port, "root", "root", 1024, "UTC+08:00", poolSize, true, 60)
-    {
-    }
-
-    [Obsolete(" This method is deprecated, please use new SessionPool.Builder().")]
-    public SessionPool(string host, int port, string username, string password)
-                    : this(host, port, username, password, 1024, "UTC+08:00", 8, true, 60)
-    {
-    }
-
-    public SessionPool(string host, int port, string username, string password, int fetchSize)
-                    : this(host, port, username, password, fetchSize, "UTC+08:00", 8, true, 60)
-    {
-
-    }
-
-    public SessionPool(string host, int port) : this(host, port, "root", "root", 1024, "UTC+08:00", 8, true, 60)
-    {
-    }
-    public SessionPool(string host, int port, string username, string password, int fetchSize, string zoneId, int poolSize, bool enableRpcCompression, int timeout)
-                     : this(host, port, username, password, fetchSize, zoneId, poolSize, enableRpcCompression, timeout, IoTDBConstant.TREE_SQL_DIALECT, "")
-    {
-    }
-    protected internal SessionPool(string host, int port, string username, string password, int fetchSize, string zoneId, int poolSize, bool enableRpcCompression, int timeout, string sqlDialect, string database)
-    {
-      _host = host;
-      _port = port;
-      _username = username;
-      _password = password;
-      _zoneId = zoneId;
-      _fetchSize = fetchSize;
-      _debugMode = false;
-      _poolSize = poolSize;
-      _enableRpcCompression = enableRpcCompression;
-      _timeout = timeout;
-      _sqlDialect = sqlDialect;
-      _database = database;
-    }
-    /// <summary>
-    ///  Initializes a new instance of the <see cref="SessionPool"/> class.
-    ///  </summary>
-    ///  <param name="nodeUrls">The list of node URLs to connect to, multiple ip:rpcPort eg.127.0.0.1:9001</param>
-    ///  <param name="poolSize">The size of the session pool.</param>
-    public SessionPool(List<string> nodeUrls, int poolSize)
-                    : this(nodeUrls, "root", "root", 1024, "UTC+08:00", poolSize, true, 60)
-    {
-    }
-    public SessionPool(List<string> nodeUrls, string username, string password)
-                    : this(nodeUrls, username, password, 1024, "UTC+08:00", 8, true, 60)
-    {
-    }
-    public SessionPool(List<string> nodeUrls, string username, string password, int fetchSize)
-                    : this(nodeUrls, username, password, fetchSize, "UTC+08:00", 8, true, 60)
-    {
-    }
-    public SessionPool(List<string> nodeUrls, string username, string password, int fetchSize, string zoneId)
-                    : this(nodeUrls, username, password, fetchSize, zoneId, 8, true, 60)
-    {
-    }
-    public SessionPool(List<string> nodeUrls, string username, string password, int fetchSize, string zoneId, int poolSize, bool enableRpcCompression, int timeout)
-                    : this(nodeUrls, username, password, fetchSize, zoneId, poolSize, enableRpcCompression, timeout, IoTDBConstant.TREE_SQL_DIALECT, "")
-    {
-
-    }
-    protected internal SessionPool(List<string> nodeUrls, string username, string password, int fetchSize, string zoneId, int poolSize, bool enableRpcCompression, int timeout, string sqlDialect, string database)
-    {
-      if (nodeUrls.Count == 0)
-      {
-        throw new ArgumentException("nodeUrls shouldn't be empty.");
-      }
-      _nodeUrls = nodeUrls;
-      _endPoints = _utilFunctions.ParseSeedNodeUrls(nodeUrls);
-      _username = username;
-      _password = password;
-      _zoneId = zoneId;
-      _fetchSize = fetchSize;
-      _debugMode = false;
-      _poolSize = poolSize;
-      _enableRpcCompression = enableRpcCompression;
-      _timeout = timeout;
-      _sqlDialect = sqlDialect;
-      _database = database;
-    }
-    public async Task<TResult> ExecuteClientOperationAsync<TResult>(AsyncOperation<TResult> operation, string errMsg, bool retryOnFailure = true, bool putClientBack=true)
-    {
-      Client client = _clients.Take();
-      try
-      {
-        var resp = await operation(client);
-        return resp;
-      }
-      catch (TException ex)
-      {
-        if (retryOnFailure)
+        [Obsolete("This method is deprecated, please use new SessionPool.Builder().")]
+        public SessionPool(string host, int port, int poolSize)
+                        : this(host, port, "root", "root", 1024, "UTC+08:00", poolSize, true, 60)
         {
-          try
-          {
-            client = await Reconnect(client);
-            return await operation(client);
-          }
-          catch (TException retryEx)
-          {
-            throw new TException(errMsg, retryEx);
-          }
         }
-        else
+
+        [Obsolete(" This method is deprecated, please use new SessionPool.Builder().")]
+        public SessionPool(string host, int port, string username, string password)
+                        : this(host, port, username, password, 1024, "UTC+08:00", 8, true, 60)
         {
-          throw new TException(errMsg, ex);
         }
-      }
-      catch (Exception ex)
-      {
-        if (retryOnFailure)
+
+        public SessionPool(string host, int port, string username, string password, int fetchSize)
+                        : this(host, port, username, password, fetchSize, "UTC+08:00", 8, true, 60)
         {
-          try
-          {
-            client = await Reconnect(client);
-            return await operation(client);
-          }
-          catch (TException retryEx)
-          {
-            throw new TException(errMsg, retryEx);
-          }
+
         }
-        else
+
+        public SessionPool(string host, int port) : this(host, port, "root", "root", 1024, "UTC+08:00", 8, true, 60)
         {
-          throw new TException(errMsg, ex);
         }
-      }
-      finally
-      {
-        if(putClientBack)
+        public SessionPool(string host, int port, string username, string password, int fetchSize, string zoneId, int poolSize, bool enableRpcCompression, int timeout)
+                         : this(host, port, username, password, fetchSize, zoneId, poolSize, enableRpcCompression, timeout, IoTDBConstant.TREE_SQL_DIALECT, "")
         {
-          _clients.Add(client);
         }
-      }
-    }
-    /// <summary>
-    ///   Gets or sets the amount of time a Session will wait for  a send operation to complete successfully.
-    /// </summary>
-    /// <remarks> The send time-out value, in milliseconds. The default is 10000.</remarks>
-    public int TimeOut { get; set; } = 10000;
-
-    ILoggerFactory factory;
-    private bool disposedValue;
-
-    public void OpenDebugMode(Action<ILoggingBuilder> configure)
-    {
-      _debugMode = true;
-      factory = LoggerFactory.Create(configure);
-      _logger = factory.CreateLogger(nameof(Apache.IoTDB));
-    }
-
-    public void CloseDebugMode()
-    {
-      _debugMode = false;
-    }
-
-    public async Task Open(bool enableRpcCompression, CancellationToken cancellationToken = default)
-    {
-      _enableRpcCompression = enableRpcCompression;
-      await Open(cancellationToken);
-    }
-
-    public async Task Open(CancellationToken cancellationToken = default)
-    {
-      _clients = new ConcurrentClientQueue();
-      _clients.Timeout = _timeout * 5;
-
-      if (_nodeUrls.Count == 0)
-      {
-        for (var index = 0; index < _poolSize; index++)
+        protected internal SessionPool(string host, int port, string username, string password, int fetchSize, string zoneId, int poolSize, bool enableRpcCompression, int timeout, string sqlDialect, string database)
         {
-          try
-          {
-            _clients.Add(await CreateAndOpen(_host, _port, _enableRpcCompression, _timeout, _sqlDialect, _database, cancellationToken));
-          }
-          catch (Exception e)
-          {
-            if (_debugMode)
+            _host = host;
+            _port = port;
+            _username = username;
+            _password = password;
+            _zoneId = zoneId;
+            _fetchSize = fetchSize;
+            _debugMode = false;
+            _poolSize = poolSize;
+            _enableRpcCompression = enableRpcCompression;
+            _timeout = timeout;
+            _sqlDialect = sqlDialect;
+            _database = database;
+        }
+        /// <summary>
+        ///  Initializes a new instance of the <see cref="SessionPool"/> class.
+        ///  </summary>
+        ///  <param name="nodeUrls">The list of node URLs to connect to, multiple ip:rpcPort eg.127.0.0.1:9001</param>
+        ///  <param name="poolSize">The size of the session pool.</param>
+        public SessionPool(List<string> nodeUrls, int poolSize)
+                        : this(nodeUrls, "root", "root", 1024, "UTC+08:00", poolSize, true, 60)
+        {
+        }
+        public SessionPool(List<string> nodeUrls, string username, string password)
+                        : this(nodeUrls, username, password, 1024, "UTC+08:00", 8, true, 60)
+        {
+        }
+        public SessionPool(List<string> nodeUrls, string username, string password, int fetchSize)
+                        : this(nodeUrls, username, password, fetchSize, "UTC+08:00", 8, true, 60)
+        {
+        }
+        public SessionPool(List<string> nodeUrls, string username, string password, int fetchSize, string zoneId)
+                        : this(nodeUrls, username, password, fetchSize, zoneId, 8, true, 60)
+        {
+        }
+        public SessionPool(List<string> nodeUrls, string username, string password, int fetchSize, string zoneId, int poolSize, bool enableRpcCompression, int timeout)
+                        : this(nodeUrls, username, password, fetchSize, zoneId, poolSize, enableRpcCompression, timeout, IoTDBConstant.TREE_SQL_DIALECT, "")
+        {
+
+        }
+        protected internal SessionPool(List<string> nodeUrls, string username, string password, int fetchSize, string zoneId, int poolSize, bool enableRpcCompression, int timeout, string sqlDialect, string database)
+        {
+            if (nodeUrls.Count == 0)
             {
-              _logger.LogWarning(e, "Currently connecting to {0}:{1} failed", _host, _port);
+                throw new ArgumentException("nodeUrls shouldn't be empty.");
             }
-          }
+            _nodeUrls = nodeUrls;
+            _endPoints = _utilFunctions.ParseSeedNodeUrls(nodeUrls);
+            _username = username;
+            _password = password;
+            _zoneId = zoneId;
+            _fetchSize = fetchSize;
+            _debugMode = false;
+            _poolSize = poolSize;
+            _enableRpcCompression = enableRpcCompression;
+            _timeout = timeout;
+            _sqlDialect = sqlDialect;
+            _database = database;
         }
-      }
-      else
-      {
-        int startIndex = 0;
-        for (var index = 0; index < _poolSize; index++)
+        public async Task<TResult> ExecuteClientOperationAsync<TResult>(AsyncOperation<TResult> operation, string errMsg, bool retryOnFailure = true, bool putClientBack = true)
         {
-          bool isConnected = false;
-          for (int i = 0; i < _endPoints.Count; i++)
-          {
-            var endPointIndex = (startIndex + i) % _endPoints.Count;
-            var endPoint = _endPoints[endPointIndex];
+            Client client = _clients.Take();
             try
             {
-              var client = await CreateAndOpen(endPoint.Ip, endPoint.Port, _enableRpcCompression, _timeout, _sqlDialect, _database, cancellationToken);
-              _clients.Add(client);
-              isConnected = true;
-              startIndex = (endPointIndex + 1) % _endPoints.Count;
-              break;
+                var resp = await operation(client);
+                return resp;
             }
-            catch (Exception e)
+            catch (TException ex)
             {
-              if (_debugMode)
-              {
-                _logger.LogWarning(e, "Currently connecting to {0}:{1} failed", endPoint.Ip, endPoint.Port);
-              }
+                if (retryOnFailure)
+                {
+                    try
+                    {
+                        client = await Reconnect(client);
+                        return await operation(client);
+                    }
+                    catch (TException retryEx)
+                    {
+                        throw new TException(errMsg, retryEx);
+                    }
+                }
+                else
+                {
+                    throw new TException(errMsg, ex);
+                }
             }
-          }
-          if (!isConnected) // current client could not connect to any endpoint
-          {
-            throw new TException("Error occurs when opening session pool. Could not connect to any server", null);
-          }
+            catch (Exception ex)
+            {
+                if (retryOnFailure)
+                {
+                    try
+                    {
+                        client = await Reconnect(client);
+                        return await operation(client);
+                    }
+                    catch (TException retryEx)
+                    {
+                        throw new TException(errMsg, retryEx);
+                    }
+                }
+                else
+                {
+                    throw new TException(errMsg, ex);
+                }
+            }
+            finally
+            {
+                if (putClientBack)
+                {
+                    _clients.Add(client);
+                }
+            }
         }
-      }
+        /// <summary>
+        ///   Gets or sets the amount of time a Session will wait for  a send operation to complete successfully.
+        /// </summary>
+        /// <remarks> The send time-out value, in milliseconds. The default is 10000.</remarks>
+        public int TimeOut { get; set; } = 10000;
 
-      if (_clients.ClientQueue.Count != _poolSize)
-      {
-        throw new TException(string.Format("Error occurs when opening session pool. Client pool size is not equal to the expected size. Client pool size: {0}, expected size: {1}, Please check the server status", _clients.ClientQueue.Count, _poolSize), null);
-      }
-      _isClose = false;
-    }
+        ILoggerFactory factory;
+        private bool disposedValue;
 
-
-    public async Task<Client> Reconnect(Client originalClient = null, CancellationToken cancellationToken = default)
-    {
-      originalClient?.Transport.Close();
-
-      if (_nodeUrls.Count == 0)
-      {
-        for (int attempt = 1; attempt <= RetryNum; attempt++)
+        public void OpenDebugMode(Action<ILoggingBuilder> configure)
         {
-          try
-          {
-            var client = await CreateAndOpen(_host, _port, _enableRpcCompression, _timeout, _sqlDialect, _database, cancellationToken);
-            return client;
-          }
-          catch (Exception e)
-          {
-            if (_debugMode)
-            {
-              _logger.LogWarning(e, "Attempt reconnecting to {0}:{1} failed", _host, _port);
-            }
-          }
+            _debugMode = true;
+            factory = LoggerFactory.Create(configure);
+            _logger = factory.CreateLogger(nameof(Apache.IoTDB));
         }
-      }
-      else
-      {
-        int startIndex = _endPoints.FindIndex(x => x.Ip == originalClient.EndPoint.Ip && x.Port == originalClient.EndPoint.Port);
-        if (startIndex == -1)
+
+        public void CloseDebugMode()
         {
-          throw new ArgumentException($"The original client is not in the list of endpoints. Original client: {originalClient.EndPoint.Ip}:{originalClient.EndPoint.Port}");
+            _debugMode = false;
         }
 
-        for (int attempt = 1; attempt <= RetryNum; attempt++)
+        public async Task Open(bool enableRpcCompression, CancellationToken cancellationToken = default)
         {
-          for (int i = 0; i < _endPoints.Count; i++)
-          {
-            int j = (startIndex + i) % _endPoints.Count;
-            try
-            {
-              var client = await CreateAndOpen(_endPoints[j].Ip, _endPoints[j].Port, _enableRpcCompression, _timeout, _sqlDialect, _database, cancellationToken);
-              return client;
-            }
-            catch (Exception e)
-            {
-              if (_debugMode)
-              {
-                _logger.LogWarning(e, "Attempt connecting to {0}:{1} failed", _endPoints[j].Ip, _endPoints[j].Port);
-              }
-            }
-          }
+            _enableRpcCompression = enableRpcCompression;
+            await Open(cancellationToken);
         }
-      }
 
-      throw new TException("Error occurs when reconnecting session pool. Could not connect to any server", null);
-    }
-
-
-    public bool IsOpen() => !_isClose;
-
-    public async Task Close()
-    {
-      if (_isClose)
-      {
-        return;
-      }
-
-      foreach (var client in _clients.ClientQueue.AsEnumerable())
-      {
-        var closeSessionRequest = new TSCloseSessionReq(client.SessionId);
-        try
+        public async Task Open(CancellationToken cancellationToken = default)
         {
-          await client.ServiceClient.closeSessionAsync(closeSessionRequest);
+            _clients = new ConcurrentClientQueue();
+            _clients.Timeout = _timeout * 5;
+
+            if (_nodeUrls.Count == 0)
+            {
+                for (var index = 0; index < _poolSize; index++)
+                {
+                    try
+                    {
+                        _clients.Add(await CreateAndOpen(_host, _port, _enableRpcCompression, _timeout, _sqlDialect, _database, cancellationToken));
+                    }
+                    catch (Exception e)
+                    {
+                        if (_debugMode)
+                        {
+                            _logger.LogWarning(e, "Currently connecting to {0}:{1} failed", _host, _port);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                int startIndex = 0;
+                for (var index = 0; index < _poolSize; index++)
+                {
+                    bool isConnected = false;
+                    for (int i = 0; i < _endPoints.Count; i++)
+                    {
+                        var endPointIndex = (startIndex + i) % _endPoints.Count;
+                        var endPoint = _endPoints[endPointIndex];
+                        try
+                        {
+                            var client = await CreateAndOpen(endPoint.Ip, endPoint.Port, _enableRpcCompression, _timeout, _sqlDialect, _database, cancellationToken);
+                            _clients.Add(client);
+                            isConnected = true;
+                            startIndex = (endPointIndex + 1) % _endPoints.Count;
+                            break;
+                        }
+                        catch (Exception e)
+                        {
+                            if (_debugMode)
+                            {
+                                _logger.LogWarning(e, "Currently connecting to {0}:{1} failed", endPoint.Ip, endPoint.Port);
+                            }
+                        }
+                    }
+                    if (!isConnected) // current client could not connect to any endpoint
+                    {
+                        throw new TException("Error occurs when opening session pool. Could not connect to any server", null);
+                    }
+                }
+            }
+
+            if (_clients.ClientQueue.Count != _poolSize)
+            {
+                throw new TException(string.Format("Error occurs when opening session pool. Client pool size is not equal to the expected size. Client pool size: {0}, expected size: {1}, Please check the server status", _clients.ClientQueue.Count, _poolSize), null);
+            }
+            _isClose = false;
         }
-        catch (TException e)
+
+
+        public async Task<Client> Reconnect(Client originalClient = null, CancellationToken cancellationToken = default)
         {
-          throw new TException("Error occurs when closing session at server. Maybe server is down", e);
+            originalClient?.Transport.Close();
+
+            if (_nodeUrls.Count == 0)
+            {
+                for (int attempt = 1; attempt <= RetryNum; attempt++)
+                {
+                    try
+                    {
+                        var client = await CreateAndOpen(_host, _port, _enableRpcCompression, _timeout, _sqlDialect, _database, cancellationToken);
+                        return client;
+                    }
+                    catch (Exception e)
+                    {
+                        if (_debugMode)
+                        {
+                            _logger.LogWarning(e, "Attempt reconnecting to {0}:{1} failed", _host, _port);
+                        }
+                    }
+                }
+            }
+            else
+            {
+                int startIndex = _endPoints.FindIndex(x => x.Ip == originalClient.EndPoint.Ip && x.Port == originalClient.EndPoint.Port);
+                if (startIndex == -1)
+                {
+                    throw new ArgumentException($"The original client is not in the list of endpoints. Original client: {originalClient.EndPoint.Ip}:{originalClient.EndPoint.Port}");
+                }
+
+                for (int attempt = 1; attempt <= RetryNum; attempt++)
+                {
+                    for (int i = 0; i < _endPoints.Count; i++)
+                    {
+                        int j = (startIndex + i) % _endPoints.Count;
+                        try
+                        {
+                            var client = await CreateAndOpen(_endPoints[j].Ip, _endPoints[j].Port, _enableRpcCompression, _timeout, _sqlDialect, _database, cancellationToken);
+                            return client;
+                        }
+                        catch (Exception e)
+                        {
+                            if (_debugMode)
+                            {
+                                _logger.LogWarning(e, "Attempt connecting to {0}:{1} failed", _endPoints[j].Ip, _endPoints[j].Port);
+                            }
+                        }
+                    }
+                }
+            }
+
+            throw new TException("Error occurs when reconnecting session pool. Could not connect to any server", null);
         }
-        finally
+
+        public bool IsOpen() => !_isClose;
+
+        public async Task Close()
         {
-          _isClose = true;
-
-          client.Transport?.Close();
-        }
-      }
-    }
-
-    public async Task SetTimeZone(string zoneId)
-    {
-      _zoneId = zoneId;
-
-      foreach (var client in _clients.ClientQueue.AsEnumerable())
-      {
-        var req = new TSSetTimeZoneReq(client.SessionId, zoneId);
-        try
-        {
-          var resp = await client.ServiceClient.setTimeZoneAsync(req);
-          if (_debugMode)
-          {
-            _logger.LogInformation("setting time zone_id as {0}, server message:{1}", zoneId, resp.Message);
-          }
-        }
-        catch (TException e)
-        {
-          throw new TException("could not set time zone", e);
-        }
-      }
-    }
-
-    public async Task<string> GetTimeZone()
-    {
-      if (_zoneId != "")
-      {
-        return _zoneId;
-      }
-
-      var client = _clients.Take();
-
-      try
-      {
-        var response = await client.ServiceClient.getTimeZoneAsync(client.SessionId);
-
-        return response?.TimeZone;
-      }
-      catch (TException e)
-      {
-        throw new TException("could not get time zone", e);
-      }
-      finally
-      {
-        _clients.Add(client);
-      }
-    }
-
-    private async Task<Client> CreateAndOpen(string host, int port, bool enableRpcCompression, int timeout, string sqlDialect, string database, CancellationToken cancellationToken = default)
-    {
-      var tcpClient = new TcpClient(host, port);
-      tcpClient.SendTimeout = timeout;
-      tcpClient.ReceiveTimeout = timeout;
-      var transport = new TFramedTransport(new TSocketTransport(tcpClient, null));
-
-      if (!transport.IsOpen)
-      {
-        await transport.OpenAsync(cancellationToken);
-      }
-
-      var client = enableRpcCompression ?
-          new IClientRPCService.Client(new TCompactProtocol(transport)) :
-          new IClientRPCService.Client(new TBinaryProtocol(transport));
-
-      var openReq = new TSOpenSessionReq(ProtocolVersion, _zoneId, _username)
-      {
-        Password = _password,
-      };
-      if (openReq.Configuration == null)
-      {
-        openReq.Configuration = new Dictionary<string, string>();
-      }
-      openReq.Configuration.Add("sql_dialect", sqlDialect);
-      if (!String.IsNullOrEmpty(database))
-      {
-        openReq.Configuration.Add("db", database);
-      }
-
-      try
-      {
-        var openResp = await client.openSessionAsync(openReq, cancellationToken);
-
-        if (openResp.ServerProtocolVersion != ProtocolVersion)
-        {
-          throw new TException($"Protocol Differ, Client version is {ProtocolVersion} but Server version is {openResp.ServerProtocolVersion}", null);
-        }
-
-        if (openResp.ServerProtocolVersion == 0)
-        {
-          throw new TException("Protocol not supported", null);
-        }
-
-        var sessionId = openResp.SessionId;
-        var statementId = await client.requestStatementIdAsync(sessionId, cancellationToken);
-
-        var endpoint = new TEndPoint(host, port);
-
-        var returnClient = new Client(
-            client,
-            sessionId,
-            statementId,
-            transport,
-            endpoint);
-
-        return returnClient;
-      }
-      catch (Exception)
-      {
-        transport.Close();
-
-        throw;
-      }
-    }
-
-    public async Task<int> CreateDatabase(string dbName)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var status = await client.ServiceClient.setStorageGroupAsync(client.SessionId, dbName);
-
-            if (_debugMode)
+            if (_isClose)
             {
-              _logger.LogInformation("create database {0} successfully, server message is {1}", dbName, status.Message);
+                return;
             }
 
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when creating database"
-      );
-    }
-
-    [Obsolete("This method is deprecated, please use createDatabase instead.")]
-    public async Task<int> SetStorageGroup(string groupName)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var status = await client.ServiceClient.setStorageGroupAsync(client.SessionId, groupName);
-            if (_debugMode)
+            foreach (var client in _clients.ClientQueue.AsEnumerable())
             {
-              _logger.LogInformation("set storage group {0} successfully, server message is {1}", groupName, status.Message);
-            }
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when setting storage group"
-      );
-    }
-    public async Task<int> CreateTimeSeries(
-        string tsPath,
-        TSDataType dataType,
-        TSEncoding encoding,
-        Compressor compressor)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = new TSCreateTimeseriesReq(
-                      client.SessionId,
-                      tsPath,
-                      (int)dataType,
-                      (int)encoding,
-                      (int)compressor);
-
-            var status = await client.ServiceClient.createTimeseriesAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("creating time series {0} successfully, server message is {1}", tsPath, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when creating time series"
-      );
-    }
-    public async Task<int> CreateAlignedTimeseriesAsync(
-        string prefixPath,
-        List<string> measurements,
-        List<TSDataType> dataTypeLst,
-        List<TSEncoding> encodingLst,
-        List<Compressor> compressorLst)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var dataTypes = dataTypeLst.ConvertAll(x => (int)x);
-            var encodings = encodingLst.ConvertAll(x => (int)x);
-            var compressors = compressorLst.ConvertAll(x => (int)x);
-
-            var req = new TSCreateAlignedTimeseriesReq(
-                      client.SessionId,
-                      prefixPath,
-                      measurements,
-                      dataTypes,
-                      encodings,
-                      compressors);
-
-            var status = await client.ServiceClient.createAlignedTimeseriesAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("creating aligned time series {0} successfully, server message is {1}", prefixPath, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when creating aligned time series"
-      );
-    }
-    public async Task<int> DeleteDatabaseAsync(string dbName)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var status = await client.ServiceClient.deleteStorageGroupsAsync(client.SessionId, new List<string> { dbName });
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("delete database {0} successfully, server message is {1}", dbName, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when deleting database"
-      );
-    }
-    [Obsolete("This method is deprecated, please use DeleteDatabaseAsync instead.")]
-    public async Task<int> DeleteStorageGroupAsync(string groupName)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var status = await client.ServiceClient.deleteStorageGroupsAsync(client.SessionId, new List<string> { groupName });
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("delete storage group {0} successfully, server message is {1}", groupName, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when deleting storage group"
-      );
-    }
-    public async Task<int> DeleteDatabasesAsync(List<string> dbNames)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var status = await client.ServiceClient.deleteStorageGroupsAsync(client.SessionId, dbNames);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("delete database(s) {0} successfully, server message is {1}", dbNames, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when deleting database(s)"
-      );
-    }
-    [Obsolete("This method is deprecated, please use DeleteDatabasesAsync instead.")]
-    public async Task<int> DeleteStorageGroupsAsync(List<string> groupNames)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var status = await client.ServiceClient.deleteStorageGroupsAsync(client.SessionId, groupNames);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("delete storage group(s) {0} successfully, server message is {1}", groupNames, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when deleting storage group(s)"
-      );
-    }
-    public async Task<int> CreateMultiTimeSeriesAsync(
-        List<string> tsPathLst,
-        List<TSDataType> dataTypeLst,
-        List<TSEncoding> encodingLst,
-        List<Compressor> compressorLst)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var dataTypes = dataTypeLst.ConvertAll(x => (int)x);
-            var encodings = encodingLst.ConvertAll(x => (int)x);
-            var compressors = compressorLst.ConvertAll(x => (int)x);
-
-            var req = new TSCreateMultiTimeseriesReq(client.SessionId, tsPathLst, dataTypes, encodings, compressors);
-
-            var status = await client.ServiceClient.createMultiTimeseriesAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("creating multiple time series {0}, server message is {1}", tsPathLst, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when creating multiple time series"
-      );
-    }
-    public async Task<int> DeleteTimeSeriesAsync(List<string> pathList)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var status = await client.ServiceClient.deleteTimeseriesAsync(client.SessionId, pathList);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("deleting multiple time series {0}, server message is {1}", pathList, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when deleting multiple time series"
-      );
-    }
-
-    public async Task<int> DeleteTimeSeriesAsync(string tsPath)
-    {
-      return await DeleteTimeSeriesAsync(new List<string> { tsPath });
-    }
-
-    public async Task<bool> CheckTimeSeriesExistsAsync(string tsPath)
-    {
-      try
-      {
-        var sql = "SHOW TIMESERIES " + tsPath;
-        var sessionDataset = await ExecuteQueryStatementAsync(sql);
-        bool timeSeriesExists = sessionDataset.HasNext();
-        await sessionDataset.Close(); // be sure to close the sessionDataset to put the client back to the pool
-        return timeSeriesExists;
-      }
-      catch (TException e)
-      {
-        throw new TException("could not check if certain time series exists", e);
-      }
-    }
-    public async Task<int> DeleteDataAsync(List<string> tsPathLst, long startTime, long endTime)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = new TSDeleteDataReq(client.SessionId, tsPathLst, startTime, endTime);
-
-            var status = await client.ServiceClient.deleteDataAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation(
-                        "delete data from {0}, server message is {1}",
-                        tsPathLst,
-                        status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when deleting data"
-      );
-    }
-    public async Task<int> InsertRecordAsync(string deviceId, RowRecord record)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = new TSInsertRecordReq(client.SessionId, deviceId, record.Measurements, record.ToBytes(), record.Timestamps);
-
-            var status = await client.ServiceClient.insertRecordAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert one record to device {0}， server message: {1}", deviceId, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting record"
-      );
-    }
-    public async Task<int> InsertAlignedRecordAsync(string deviceId, RowRecord record)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = new TSInsertRecordReq(client.SessionId, deviceId, record.Measurements, record.ToBytes(), record.Timestamps);
-            req.IsAligned = true;
-            // ASSERT that the insert plan is aligned
-            System.Diagnostics.Debug.Assert(req.IsAligned == true);
-
-            var status = await client.ServiceClient.insertRecordAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert one record to device {0}， server message: {1}", deviceId, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting record"
-      );
-    }
-
-    public TSInsertStringRecordReq GenInsertStrRecordReq(string deviceId, List<string> measurements,
-        List<string> values, long timestamp, long sessionId, bool isAligned = false)
-    {
-      if (values.Count() != measurements.Count())
-      {
-        throw new ArgumentException("length of data types does not equal to length of values!");
-      }
-
-      return new TSInsertStringRecordReq(sessionId, deviceId, measurements, values, timestamp)
-      {
-        IsAligned = isAligned
-      };
-    }
-    public TSInsertStringRecordsReq GenInsertStringRecordsReq(List<string> deviceIds, List<List<string>> measurementsList,
-        List<List<string>> valuesList, List<long> timestamps, long sessionId, bool isAligned = false)
-    {
-      if (valuesList.Count() != measurementsList.Count())
-      {
-        throw new ArgumentException("length of data types does not equal to length of values!");
-      }
-
-      return new TSInsertStringRecordsReq(sessionId, deviceIds, measurementsList, valuesList, timestamps)
-      {
-        IsAligned = isAligned
-      };
-    }
-
-    public TSInsertRecordsReq GenInsertRecordsReq(List<string> deviceId, List<RowRecord> rowRecords,
-        long sessionId)
-    {
-      var measurementLst = rowRecords.Select(x => x.Measurements).ToList();
-      var timestampLst = rowRecords.Select(x => x.Timestamps).ToList();
-      var valuesLstInBytes = rowRecords.Select(row => row.ToBytes()).ToList();
-
-      return new TSInsertRecordsReq(sessionId, deviceId, measurementLst, valuesLstInBytes, timestampLst);
-    }
-    public async Task<int> InsertStringRecordAsync(string deviceId, List<string> measurements, List<string> values,
-        long timestamp)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertStrRecordReq(deviceId, measurements, values, timestamp, client.SessionId);
-
-            var status = await client.ServiceClient.insertStringRecordAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert one string record to device {0}， server message: {1}", deviceId, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting a string record"
-      );
-    }
-    public async Task<int> InsertAlignedStringRecordAsync(string deviceId, List<string> measurements, List<string> values,
-        long timestamp)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertStrRecordReq(deviceId, measurements, values, timestamp, client.SessionId, true);
-
-            var status = await client.ServiceClient.insertStringRecordAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert one record to device {0}， server message: {1}", deviceId, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting a string record"
-      );
-    }
-    public async Task<int> InsertStringRecordsAsync(List<string> deviceIds, List<List<string>> measurements, List<List<string>> values,
-        List<long> timestamps)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertStringRecordsReq(deviceIds, measurements, values, timestamps, client.SessionId);
-
-            var status = await client.ServiceClient.insertStringRecordsAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert string records to devices {0}， server message: {1}", deviceIds, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting string records"
-      );
-    }
-    public async Task<int> InsertAlignedStringRecordsAsync(List<string> deviceIds, List<List<string>> measurements, List<List<string>> values,
-        List<long> timestamps)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertStringRecordsReq(deviceIds, measurements, values, timestamps, client.SessionId, true);
-
-            var status = await client.ServiceClient.insertStringRecordsAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert string records to devices {0}， server message: {1}", deviceIds, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting string records"
-      );
-    }
-    public async Task<int> InsertRecordsAsync(List<string> deviceId, List<RowRecord> rowRecords)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertRecordsReq(deviceId, rowRecords, client.SessionId);
-
-            var status = await client.ServiceClient.insertRecordsAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert multiple records to devices {0}, server message: {1}", deviceId, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting records"
-      );
-    }
-    public async Task<int> InsertAlignedRecordsAsync(List<string> deviceId, List<RowRecord> rowRecords)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertRecordsReq(deviceId, rowRecords, client.SessionId);
-            req.IsAligned = true;
-            // ASSERT that the insert plan is aligned
-            System.Diagnostics.Debug.Assert(req.IsAligned == true);
-
-            var status = await client.ServiceClient.insertRecordsAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert multiple records to devices {0}, server message: {1}", deviceId, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting records"
-      );
-    }
-    public TSInsertTabletReq GenInsertTabletReq(Tablet tablet, long sessionId)
-    {
-      return new TSInsertTabletReq(
-          sessionId,
-          tablet.InsertTargetName,
-          tablet.Measurements,
-          tablet.GetBinaryValues(),
-          tablet.GetBinaryTimestamps(),
-          tablet.GetDataTypes(),
-          tablet.RowNumber);
-    }
-    public async Task<int> InsertTabletAsync(Tablet tablet)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertTabletReq(tablet, client.SessionId);
-
-            var status = await client.ServiceClient.insertTabletAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert one tablet to device {0}, server message: {1}", tablet.InsertTargetName, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting tablet"
-      );
-    }
-    public async Task<int> InsertAlignedTabletAsync(Tablet tablet)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertTabletReq(tablet, client.SessionId);
-            req.IsAligned = true;
-
-            var status = await client.ServiceClient.insertTabletAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert one aligned tablet to device {0}, server message: {1}", tablet.InsertTargetName, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting aligned tablet"
-      );
-    }
-
-    protected internal async Task<int> InsertRelationalTabletAsync(Tablet tablet)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertTabletReq(tablet, client.SessionId);
-            req.ColumnCategories = tablet.GetColumnColumnCategories();
-            req.WriteToTable = true;
-
-            var status = await client.ServiceClient.insertTabletAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert one tablet to table {0}, server message: {1}", tablet.InsertTargetName, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting tablet"
-      );
-    }
-
-    public TSInsertTabletsReq GenInsertTabletsReq(List<Tablet> tabletLst, long sessionId)
-    {
-      var deviceIdLst = new List<string>();
-      var measurementsLst = new List<List<string>>();
-      var valuesLst = new List<byte[]>();
-      var timestampsLst = new List<byte[]>();
-      var typeLst = new List<List<int>>();
-      var sizeLst = new List<int>();
-
-      foreach (var tablet in tabletLst)
-      {
-        var dataTypeValues = tablet.GetDataTypes();
-        deviceIdLst.Add(tablet.InsertTargetName);
-        measurementsLst.Add(tablet.Measurements);
-        valuesLst.Add(tablet.GetBinaryValues());
-        timestampsLst.Add(tablet.GetBinaryTimestamps());
-        typeLst.Add(dataTypeValues);
-        sizeLst.Add(tablet.RowNumber);
-      }
-
-      return new TSInsertTabletsReq(
-          sessionId,
-          deviceIdLst,
-          measurementsLst,
-          valuesLst,
-          timestampsLst,
-          typeLst,
-          sizeLst);
-    }
-
-    public async Task<int> InsertTabletsAsync(List<Tablet> tabletLst)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertTabletsReq(tabletLst, client.SessionId);
-
-            var status = await client.ServiceClient.insertTabletsAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert multiple tablets, message: {0}", status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting tablets"
-      );
-    }
-    public async Task<int> InsertAlignedTabletsAsync(List<Tablet> tabletLst)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertTabletsReq(tabletLst, client.SessionId);
-            req.IsAligned = true;
-
-            var status = await client.ServiceClient.insertTabletsAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert multiple aligned tablets, message: {0}", status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting aligned tablets"
-      );
-    }
-
-    public async Task<int> InsertRecordsOfOneDeviceAsync(string deviceId, List<RowRecord> rowRecords)
-    {
-      var sortedRowRecords = rowRecords.OrderBy(x => x.Timestamps).ToList();
-      return await InsertRecordsOfOneDeviceSortedAsync(deviceId, sortedRowRecords);
-    }
-    public async Task<int> InsertAlignedRecordsOfOneDeviceAsync(string deviceId, List<RowRecord> rowRecords)
-    {
-      var sortedRowRecords = rowRecords.OrderBy(x => x.Timestamps).ToList();
-      return await InsertAlignedRecordsOfOneDeviceSortedAsync(deviceId, sortedRowRecords);
-    }
-    public async Task<int> InsertStringRecordsOfOneDeviceAsync(string deviceId, List<long> timestamps,
-        List<List<string>> measurementsList, List<List<string>> valuesList)
-    {
-      var joined = timestamps.Zip(measurementsList, (t, m) => new { t, m })
-          .Zip(valuesList, (tm, v) => new { tm.t, tm.m, v })
-          .OrderBy(x => x.t);
-
-      var sortedTimestamps = joined.Select(x => x.t).ToList();
-      var sortedMeasurementsList = joined.Select(x => x.m).ToList();
-      var sortedValuesList = joined.Select(x => x.v).ToList();
-
-      return await InsertStringRecordsOfOneDeviceSortedAsync(deviceId, sortedTimestamps, sortedMeasurementsList, sortedValuesList, false);
-    }
-    public async Task<int> InsertAlignedStringRecordsOfOneDeviceAsync(string deviceId, List<long> timestamps,
-        List<List<string>> measurementsList, List<List<string>> valuesList)
-    {
-      var joined = timestamps.Zip(measurementsList, (t, m) => new { t, m })
-          .Zip(valuesList, (tm, v) => new { tm.t, tm.m, v })
-          .OrderBy(x => x.t);
-
-      var sortedTimestamps = joined.Select(x => x.t).ToList();
-      var sortedMeasurementsList = joined.Select(x => x.m).ToList();
-      var sortedValuesList = joined.Select(x => x.v).ToList();
-
-      return await InsertStringRecordsOfOneDeviceSortedAsync(deviceId, sortedTimestamps, sortedMeasurementsList, sortedValuesList, true);
-    }
-    public async Task<int> InsertStringRecordsOfOneDeviceSortedAsync(string deviceId, List<long> timestamps,
-        List<List<string>> measurementsList, List<List<string>> valuesList, bool isAligned)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            if (!_utilFunctions.IsSorted(timestamps))
-            {
-              throw new ArgumentException("insert string records of one device error: timestamp not sorted");
-            }
-
-            var req = GenInsertStringRecordsOfOneDeviceReq(deviceId, timestamps, measurementsList, valuesList, client.SessionId, isAligned);
-
-            var status = await client.ServiceClient.insertStringRecordsOfOneDeviceAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert string records of one device, message: {0}", status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting string records of one device"
-      );
-    }
-    private TSInsertStringRecordsOfOneDeviceReq GenInsertStringRecordsOfOneDeviceReq(string deviceId,
-        List<long> timestamps, List<List<string>> measurementsList, List<List<string>> valuesList,
-         long sessionId, bool isAligned = false)
-    {
-      return new TSInsertStringRecordsOfOneDeviceReq(
-          sessionId,
-          deviceId,
-          measurementsList,
-          valuesList,
-          timestamps)
-      {
-        IsAligned = isAligned
-      };
-    }
-    private TSInsertRecordsOfOneDeviceReq GenInsertRecordsOfOneDeviceRequest(
-        string deviceId,
-        List<RowRecord> records,
-        long sessionId)
-    {
-      var values = records.Select(row => row.ToBytes());
-      var measurementsLst = records.Select(x => x.Measurements).ToList();
-      var timestampLst = records.Select(x => x.Timestamps).ToList();
-
-      return new TSInsertRecordsOfOneDeviceReq(
-          sessionId,
-          deviceId,
-          measurementsLst,
-          values.ToList(),
-          timestampLst);
-    }
-    public async Task<int> InsertRecordsOfOneDeviceSortedAsync(string deviceId, List<RowRecord> rowRecords)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var timestampLst = rowRecords.Select(x => x.Timestamps).ToList();
-
-            if (!_utilFunctions.IsSorted(timestampLst))
-            {
-              throw new ArgumentException("insert records of one device error: timestamp not sorted");
-            }
-
-            var req = GenInsertRecordsOfOneDeviceRequest(deviceId, rowRecords, client.SessionId);
-
-            var status = await client.ServiceClient.insertRecordsOfOneDeviceAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert records of one device, message: {0}", status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting records of one device"
-      );
-    }
-    public async Task<int> InsertAlignedRecordsOfOneDeviceSortedAsync(string deviceId, List<RowRecord> rowRecords)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var timestampLst = rowRecords.Select(x => x.Timestamps).ToList();
-
-            if (!_utilFunctions.IsSorted(timestampLst))
-            {
-              throw new ArgumentException("insert records of one device error: timestamp not sorted");
-            }
-
-            var req = GenInsertRecordsOfOneDeviceRequest(deviceId, rowRecords, client.SessionId);
-            req.IsAligned = true;
-
-            var status = await client.ServiceClient.insertRecordsOfOneDeviceAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert aligned records of one device, message: {0}", status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when inserting aligned records of one device"
-      );
-    }
-    public async Task<int> TestInsertRecordAsync(string deviceId, RowRecord record)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = new TSInsertRecordReq(
-                      client.SessionId,
-                      deviceId,
-                      record.Measurements,
-                      record.ToBytes(),
-                      record.Timestamps);
-
-            var status = await client.ServiceClient.testInsertRecordAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert one record to device {0}， server message: {1}", deviceId, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when test inserting one record"
-      );
-    }
-    public async Task<int> TestInsertRecordsAsync(List<string> deviceId, List<RowRecord> rowRecords)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertRecordsReq(deviceId, rowRecords, client.SessionId);
-
-            var status = await client.ServiceClient.testInsertRecordsAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert multiple records to devices {0}, server message: {1}", deviceId, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when test inserting multiple records"
-      );
-    }
-    public async Task<int> TestInsertTabletAsync(Tablet tablet)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertTabletReq(tablet, client.SessionId);
-
-            var status = await client.ServiceClient.testInsertTabletAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert one tablet to device {0}, server message: {1}", tablet.InsertTargetName, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when test inserting one tablet"
-      );
-    }
-    public async Task<int> TestInsertTabletsAsync(List<Tablet> tabletLst)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = GenInsertTabletsReq(tabletLst, client.SessionId);
-
-            var status = await client.ServiceClient.testInsertTabletsAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("insert multiple tablets, message: {0}", status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when test inserting multiple tablets"
-      );
-    }
-
-    public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
-    {
-      // default timeout is 60s
-      return await ExecuteQueryStatementAsync(sql, 60 * 1000);
-    }
-
-    public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql, long timeoutInMs)
-    {
-      return await ExecuteClientOperationAsync<SessionDataSet>(
-          async client =>
-          {
-            var req = new TSExecuteStatementReq(client.SessionId, sql, client.StatementId)
-            {
-              FetchSize = _fetchSize,
-              Timeout = timeoutInMs
-            };
-
-            var resp = await client.ServiceClient.executeQueryStatementAsync(req);
-            var status = resp.Status;
-
-            if (_utilFunctions.VerifySuccess(status) == -1)
-            {
-              throw new Exception(string.Format("execute query failed, sql: {0}, message: {1}", sql, status.Message));
-            }
-
-            return new SessionDataSet(sql, resp, client, _clients, client.StatementId)
-            {
-              FetchSize = _fetchSize,
-            };
-          },
-          errMsg: "Error occurs when executing query statement",
-          putClientBack: false
-      );
-    }
-
-    public async Task<SessionDataSet> ExecuteStatementAsync(string sql, long timeout)
-    {
-      return await ExecuteClientOperationAsync<SessionDataSet>(
-          async client =>
-          {
-            var req = new TSExecuteStatementReq(client.SessionId, sql, client.StatementId)
-            {
-              FetchSize = _fetchSize,
-              Timeout = timeout
-            };
-
-            var resp = await client.ServiceClient.executeStatementAsync(req);
-            var status = resp.Status;
-
-            if (_utilFunctions.VerifySuccess(status) == -1)
-            {
-              throw new Exception(string.Format("execute query failed, sql: {0}, message: {1}", sql, status.Message));
-            }
-
-            return new SessionDataSet(sql, resp, client, _clients, client.StatementId)
-            {
-              FetchSize = _fetchSize,
-            };
-          },
-          errMsg: "Error occurs when executing query statement",
-          putClientBack: false
-      );
-    }
-
-
-    public async Task<int> ExecuteNonQueryStatementAsync(string sql)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            String previousDB = _database;
-            var req = new TSExecuteStatementReq(client.SessionId, sql, client.StatementId);
-
-            var resp = await client.ServiceClient.executeUpdateStatementAsync(req);
-            var status = resp.Status;
-
-            if (resp.__isset.database)
-            {
-              this._database = resp.Database;
-            }
-            if (_database != previousDB)
-            {
-              // all client should switch to the same database
-              foreach (var c in _clients.ClientQueue)
-              {
+                var closeSessionRequest = new TSCloseSessionReq(client.SessionId);
                 try
                 {
-                  if (c != client)
-                  {
-                    var switchReq = new TSExecuteStatementReq(c.SessionId, sql, c.StatementId);
-                    await c.ServiceClient.executeUpdateStatementAsync(switchReq);
-                  }
+                    await client.ServiceClient.closeSessionAsync(closeSessionRequest);
                 }
-                catch (Exception e)
+                catch (TException e)
                 {
-                  _logger.LogError("switch database from {0} to {1} failed for {2}, error: {3}", previousDB, _database, c.SessionId, e.Message);
+                    throw new TException("Error occurs when closing session at server. Maybe server is down", e);
                 }
-              }
-              _logger.LogInformation("switch database from {0} to {1}", previousDB, _database);
+                finally
+                {
+                    _isClose = true;
+
+                    client.Transport?.Close();
+                }
             }
+        }
 
-            if (_debugMode)
-            {
-              _logger.LogInformation("execute non-query statement {0} message: {1}", sql, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when executing non-query statement"
-      );
-    }
-    public async Task<SessionDataSet> ExecuteRawDataQuery(List<string> paths, long startTime, long endTime)
-    {
-      return await ExecuteClientOperationAsync<SessionDataSet>(
-          async client =>
-          {
-            var req = new TSRawDataQueryReq(client.SessionId, paths, startTime, endTime, client.StatementId)
-            {
-              FetchSize = _fetchSize,
-              EnableRedirectQuery = false
-            };
-
-            var resp = await client.ServiceClient.executeRawDataQueryAsync(req);
-            var status = resp.Status;
-
-            if (_utilFunctions.VerifySuccess(status) == -1)
-            {
-              throw new Exception(string.Format("execute raw data query failed, message: {0}", status.Message));
-            }
-
-            return new SessionDataSet("", resp, client, _clients, client.StatementId)
-            {
-              FetchSize = _fetchSize,
-            };
-          },
-          errMsg: "Error occurs when executing raw data query",
-          putClientBack: false
-      );
-    }
-    public async Task<SessionDataSet> ExecuteLastDataQueryAsync(List<string> paths, long lastTime)
-    {
-      return await ExecuteClientOperationAsync<SessionDataSet>(
-          async client =>
-          {
-            var req = new TSLastDataQueryReq(client.SessionId, paths, lastTime, client.StatementId)
-            {
-              FetchSize = _fetchSize,
-              EnableRedirectQuery = false
-            };
-
-            var resp = await client.ServiceClient.executeLastDataQueryAsync(req);
-            var status = resp.Status;
-
-            if (_utilFunctions.VerifySuccess(status) == -1)
-            {
-              throw new Exception(string.Format("execute last data query failed, message: {0}", status.Message));
-            }
-
-            return new SessionDataSet("", resp, client, _clients, client.StatementId)
-            {
-              FetchSize = _fetchSize,
-            };
-          },
-          errMsg: "Error occurs when executing last data query",
-          putClientBack: false
-      );
-    }
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<int> CreateSchemaTemplateAsync(Template template)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = new TSCreateSchemaTemplateReq(client.SessionId, template.Name, template.ToBytes());
-
-            var status = await client.ServiceClient.createSchemaTemplateAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("create schema template {0} message: {1}", template.Name, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when creating schema template"
-      );
-    }
-
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<int> DropSchemaTemplateAsync(string templateName)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = new TSDropSchemaTemplateReq(client.SessionId, templateName);
-
-            var status = await client.ServiceClient.dropSchemaTemplateAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("drop schema template {0} message: {1}", templateName, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when dropping schema template"
-      );
-    }
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<int> SetSchemaTemplateAsync(string templateName, string prefixPath)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = new TSSetSchemaTemplateReq(client.SessionId, templateName, prefixPath);
-
-            var status = await client.ServiceClient.setSchemaTemplateAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("set schema template {0} message: {1}", templateName, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when setting schema template"
-      );
-    }
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<int> UnsetSchemaTemplateAsync(string prefixPath, string templateName)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = new TSUnsetSchemaTemplateReq(client.SessionId, prefixPath, templateName);
-
-            var status = await client.ServiceClient.unsetSchemaTemplateAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("unset schema template {0} message: {1}", templateName, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when unsetting schema template"
-      );
-    }
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<int> DeleteNodeInTemplateAsync(string templateName, string path)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = new TSPruneSchemaTemplateReq(client.SessionId, templateName, path);
-
-            var status = await client.ServiceClient.pruneSchemaTemplateAsync(req);
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("delete node in template {0} message: {1}", templateName, status.Message);
-            }
-
-            return _utilFunctions.VerifySuccess(status);
-          },
-          errMsg: "Error occurs when deleting node in template"
-      );
-    }
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<int> CountMeasurementsInTemplateAsync(string name)
-    {
-      return await ExecuteClientOperationAsync<int>(
-          async client =>
-          {
-            var req = new TSQueryTemplateReq(client.SessionId, name, (int)TemplateQueryType.COUNT_MEASUREMENTS);
-
-            var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
-            var status = resp.Status;
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("count measurements in template {0} message: {1}", name, status.Message);
-            }
-
-            if (_utilFunctions.VerifySuccess(status) == -1)
-            {
-              throw new Exception(string.Format("count measurements in template failed, template name: {0}, message: {1}", name, status.Message));
-            }
-            return resp.Count;
-          },
-          errMsg: "Error occurs when counting measurements in template"
-      );
-    }
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<bool> IsMeasurementInTemplateAsync(string templateName, string path)
-    {
-      return await ExecuteClientOperationAsync<bool>(
-          async client =>
-          {
-            var req = new TSQueryTemplateReq(client.SessionId, templateName, (int)TemplateQueryType.IS_MEASUREMENT);
-            req.Measurement = path;
-
-            var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
-            var status = resp.Status;
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("is measurement in template {0} message: {1}", templateName, status.Message);
-            }
-
-            if (_utilFunctions.VerifySuccess(status) == -1)
-            {
-              throw new Exception(string.Format("is measurement in template failed, template name: {0}, message: {1}", templateName, status.Message));
-            }
-            return resp.Result;
-          },
-          errMsg: "Error occurs when checking measurement in template"
-      );
-    }
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<bool> IsPathExistInTemplateAsync(string templateName, string path)
-    {
-      return await ExecuteClientOperationAsync<bool>(
-          async client =>
-          {
-            var req = new TSQueryTemplateReq(client.SessionId, templateName, (int)TemplateQueryType.PATH_EXIST);
-            req.Measurement = path;
-
-            var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
-            var status = resp.Status;
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("is path exist in template {0} message: {1}", templateName, status.Message);
-            }
-
-            if (_utilFunctions.VerifySuccess(status) == -1)
-            {
-              throw new Exception(string.Format("is path exist in template failed, template name: {0}, message: {1}", templateName, status.Message));
-            }
-            return resp.Result;
-          },
-          errMsg: "Error occurs when checking path exist in template"
-      );
-    }
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<List<string>> ShowMeasurementsInTemplateAsync(string templateName, string pattern = "")
-    {
-      return await ExecuteClientOperationAsync<List<string>>(
-          async client =>
-          {
-            var req = new TSQueryTemplateReq(client.SessionId, templateName, (int)TemplateQueryType.SHOW_MEASUREMENTS);
-            req.Measurement = pattern;
-
-            var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
-            var status = resp.Status;
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("get measurements in template {0} message: {1}", templateName, status.Message);
-            }
-
-            if (_utilFunctions.VerifySuccess(status) == -1)
-            {
-              throw new Exception(string.Format("show measurements in template failed, template name: {0}, pattern: {1}, message: {2}", templateName, pattern, status.Message));
-            }
-            return resp.Measurements;
-          },
-          errMsg: "Error occurs when showing measurements in template"
-      );
-    }
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<List<string>> ShowAllTemplatesAsync()
-    {
-      return await ExecuteClientOperationAsync<List<string>>(
-          async client =>
-          {
-            var req = new TSQueryTemplateReq(client.SessionId, "", (int)TemplateQueryType.SHOW_TEMPLATES);
-
-            var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
-            var status = resp.Status;
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("get all templates message: {0}", status.Message);
-            }
-
-            if (_utilFunctions.VerifySuccess(status) == -1)
-            {
-              throw new Exception(string.Format("show all templates failed, message: {0}", status.Message));
-            }
-            return resp.Measurements;
-          },
-          errMsg: "Error occurs when getting all templates"
-      );
-    }
-
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<List<string>> ShowPathsTemplateSetOnAsync(string templateName)
-    {
-      return await ExecuteClientOperationAsync<List<string>>(
-          async client =>
-          {
-            var req = new TSQueryTemplateReq(client.SessionId, templateName, (int)TemplateQueryType.SHOW_SET_TEMPLATES);
-
-            var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
-            var status = resp.Status;
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("get paths template set on {0} message: {1}", templateName, status.Message);
-            }
-
-            if (_utilFunctions.VerifySuccess(status) == -1)
-            {
-              throw new Exception(string.Format("show paths template set on failed, template name: {0}, message: {1}", templateName, status.Message));
-            }
-            return resp.Measurements;
-          },
-          errMsg: "Error occurs when getting paths template set on"
-      );
-    }
-    [Obsolete("This method is obsolete. Use SQL instead.", false)]
-    public async Task<List<string>> ShowPathsTemplateUsingOnAsync(string templateName)
-    {
-      return await ExecuteClientOperationAsync<List<string>>(
-          async client =>
-          {
-            var req = new TSQueryTemplateReq(client.SessionId, templateName, (int)TemplateQueryType.SHOW_USING_TEMPLATES);
-
-            var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
-            var status = resp.Status;
-
-            if (_debugMode)
-            {
-              _logger.LogInformation("get paths template using on {0} message: {1}", templateName, status.Message);
-            }
-
-            if (_utilFunctions.VerifySuccess(status) == -1)
-            {
-              throw new Exception(string.Format("show paths template using on failed, template name: {0}, message: {1}", templateName, status.Message));
-            }
-            return resp.Measurements;
-          },
-          errMsg: "Error occurs when getting paths template using on"
-      );
-    }
-
-    protected virtual void Dispose(bool disposing)
-    {
-      if (!disposedValue)
-      {
-        if (disposing)
+        public async Task SetTimeZone(string zoneId)
         {
+            _zoneId = zoneId;
+
+            foreach (var client in _clients.ClientQueue.AsEnumerable())
+            {
+                var req = new TSSetTimeZoneReq(client.SessionId, zoneId);
+                try
+                {
+                    var resp = await client.ServiceClient.setTimeZoneAsync(req);
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("setting time zone_id as {0}, server message:{1}", zoneId, resp.Message);
+                    }
+                }
+                catch (TException e)
+                {
+                    throw new TException("could not set time zone", e);
+                }
+            }
+        }
+
+        public async Task<string> GetTimeZone()
+        {
+            if (_zoneId != "")
+            {
+                return _zoneId;
+            }
+
+            var client = _clients.Take();
+
+            try
+            {
+                var response = await client.ServiceClient.getTimeZoneAsync(client.SessionId);
+
+                return response?.TimeZone;
+            }
+            catch (TException e)
+            {
+                throw new TException("could not get time zone", e);
+            }
+            finally
+            {
+                _clients.Add(client);
+            }
+        }
+
+        private async Task<Client> CreateAndOpen(string host, int port, bool enableRpcCompression, int timeout, string sqlDialect, string database, CancellationToken cancellationToken = default)
+        {
+            var tcpClient = new TcpClient(host, port);
+            tcpClient.SendTimeout = timeout;
+            tcpClient.ReceiveTimeout = timeout;
+            var transport = new TFramedTransport(new TSocketTransport(tcpClient, null));
+
+            if (!transport.IsOpen)
+            {
+                await transport.OpenAsync(cancellationToken);
+            }
+
+            var client = enableRpcCompression ?
+                new IClientRPCService.Client(new TCompactProtocol(transport)) :
+                new IClientRPCService.Client(new TBinaryProtocol(transport));
+
+            var openReq = new TSOpenSessionReq(ProtocolVersion, _zoneId, _username)
+            {
+                Password = _password,
+            };
+            if (openReq.Configuration == null)
+            {
+                openReq.Configuration = new Dictionary<string, string>();
+            }
+            openReq.Configuration.Add("sql_dialect", sqlDialect);
+            if (!String.IsNullOrEmpty(database))
+            {
+                openReq.Configuration.Add("db", database);
+            }
+
+            try
+            {
+                var openResp = await client.openSessionAsync(openReq, cancellationToken);
+
+                if (openResp.ServerProtocolVersion != ProtocolVersion)
+                {
+                    throw new TException($"Protocol Differ, Client version is {ProtocolVersion} but Server version is {openResp.ServerProtocolVersion}", null);
+                }
+
+                if (openResp.ServerProtocolVersion == 0)
+                {
+                    throw new TException("Protocol not supported", null);
+                }
+
+                var sessionId = openResp.SessionId;
+                var statementId = await client.requestStatementIdAsync(sessionId, cancellationToken);
+
+                var endpoint = new TEndPoint(host, port);
+
+                var returnClient = new Client(
+                    client,
+                    sessionId,
+                    statementId,
+                    transport,
+                    endpoint);
+
+                return returnClient;
+            }
+            catch (Exception)
+            {
+                transport.Close();
+
+                throw;
+            }
+        }
+
+        public async Task<int> CreateDatabase(string dbName)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var status = await client.ServiceClient.setStorageGroupAsync(client.SessionId, dbName);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("create database {0} successfully, server message is {1}", dbName, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when creating database"
+            );
+        }
+
+        [Obsolete("This method is deprecated, please use createDatabase instead.")]
+        public async Task<int> SetStorageGroup(string groupName)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var status = await client.ServiceClient.setStorageGroupAsync(client.SessionId, groupName);
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("set storage group {0} successfully, server message is {1}", groupName, status.Message);
+                    }
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when setting storage group"
+            );
+        }
+        public async Task<int> CreateTimeSeries(
+            string tsPath,
+            TSDataType dataType,
+            TSEncoding encoding,
+            Compressor compressor)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = new TSCreateTimeseriesReq(
+                        client.SessionId,
+                        tsPath,
+                        (int)dataType,
+                        (int)encoding,
+                        (int)compressor);
+
+                    var status = await client.ServiceClient.createTimeseriesAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("creating time series {0} successfully, server message is {1}", tsPath, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when creating time series"
+            );
+        }
+        public async Task<int> CreateAlignedTimeseriesAsync(
+            string prefixPath,
+            List<string> measurements,
+            List<TSDataType> dataTypeLst,
+            List<TSEncoding> encodingLst,
+            List<Compressor> compressorLst)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var dataTypes = dataTypeLst.ConvertAll(x => (int)x);
+                    var encodings = encodingLst.ConvertAll(x => (int)x);
+                    var compressors = compressorLst.ConvertAll(x => (int)x);
+
+                    var req = new TSCreateAlignedTimeseriesReq(
+                        client.SessionId,
+                        prefixPath,
+                        measurements,
+                        dataTypes,
+                        encodings,
+                        compressors);
+
+                    var status = await client.ServiceClient.createAlignedTimeseriesAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("creating aligned time series {0} successfully, server message is {1}", prefixPath, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when creating aligned time series"
+            );
+        }
+        public async Task<int> DeleteDatabaseAsync(string dbName)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var status = await client.ServiceClient.deleteStorageGroupsAsync(client.SessionId, new List<string> { dbName });
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("delete database {0} successfully, server message is {1}", dbName, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when deleting database"
+            );
+        }
+        [Obsolete("This method is deprecated, please use DeleteDatabaseAsync instead.")]
+        public async Task<int> DeleteStorageGroupAsync(string groupName)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var status = await client.ServiceClient.deleteStorageGroupsAsync(client.SessionId, new List<string> { groupName });
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("delete storage group {0} successfully, server message is {1}", groupName, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when deleting storage group"
+            );
+        }
+        public async Task<int> DeleteDatabasesAsync(List<string> dbNames)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var status = await client.ServiceClient.deleteStorageGroupsAsync(client.SessionId, dbNames);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("delete database(s) {0} successfully, server message is {1}", dbNames, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when deleting database(s)"
+            );
+        }
+        [Obsolete("This method is deprecated, please use DeleteDatabasesAsync instead.")]
+        public async Task<int> DeleteStorageGroupsAsync(List<string> groupNames)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var status = await client.ServiceClient.deleteStorageGroupsAsync(client.SessionId, groupNames);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("delete storage group(s) {0} successfully, server message is {1}", groupNames, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when deleting storage group(s)"
+            );
+        }
+        public async Task<int> CreateMultiTimeSeriesAsync(
+            List<string> tsPathLst,
+            List<TSDataType> dataTypeLst,
+            List<TSEncoding> encodingLst,
+            List<Compressor> compressorLst)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var dataTypes = dataTypeLst.ConvertAll(x => (int)x);
+                    var encodings = encodingLst.ConvertAll(x => (int)x);
+                    var compressors = compressorLst.ConvertAll(x => (int)x);
+
+                    var req = new TSCreateMultiTimeseriesReq(client.SessionId, tsPathLst, dataTypes, encodings, compressors);
+
+                    var status = await client.ServiceClient.createMultiTimeseriesAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("creating multiple time series {0}, server message is {1}", tsPathLst, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when creating multiple time series"
+            );
+        }
+        public async Task<int> DeleteTimeSeriesAsync(List<string> pathList)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var status = await client.ServiceClient.deleteTimeseriesAsync(client.SessionId, pathList);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("deleting multiple time series {0}, server message is {1}", pathList, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when deleting multiple time series"
+            );
+        }
+
+        public async Task<int> DeleteTimeSeriesAsync(string tsPath)
+        {
+            return await DeleteTimeSeriesAsync(new List<string> { tsPath });
+        }
+
+        public async Task<bool> CheckTimeSeriesExistsAsync(string tsPath)
+        {
+            try
+            {
+                var sql = "SHOW TIMESERIES " + tsPath;
+                var sessionDataset = await ExecuteQueryStatementAsync(sql);
+                bool timeSeriesExists = sessionDataset.HasNext();
+                await sessionDataset.Close(); // be sure to close the sessionDataset to put the client back to the pool
+                return timeSeriesExists;
+            }
+            catch (TException e)
+            {
+                throw new TException("could not check if certain time series exists", e);
+            }
+        }
+        public async Task<int> DeleteDataAsync(List<string> tsPathLst, long startTime, long endTime)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = new TSDeleteDataReq(client.SessionId, tsPathLst, startTime, endTime);
+
+                    var status = await client.ServiceClient.deleteDataAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation(
+                            "delete data from {0}, server message is {1}",
+                            tsPathLst,
+                            status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when deleting data"
+            );
+        }
+        public async Task<int> InsertRecordAsync(string deviceId, RowRecord record)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = new TSInsertRecordReq(client.SessionId, deviceId, record.Measurements, record.ToBytes(), record.Timestamps);
+
+                    var status = await client.ServiceClient.insertRecordAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert one record to device {0}， server message: {1}", deviceId, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting record"
+            );
+        }
+        public async Task<int> InsertAlignedRecordAsync(string deviceId, RowRecord record)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = new TSInsertRecordReq(client.SessionId, deviceId, record.Measurements, record.ToBytes(), record.Timestamps);
+                    req.IsAligned = true;
+                    // ASSERT that the insert plan is aligned
+                    System.Diagnostics.Debug.Assert(req.IsAligned == true);
+
+                    var status = await client.ServiceClient.insertRecordAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert one record to device {0}， server message: {1}", deviceId, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting record"
+            );
+        }
+
+        public TSInsertStringRecordReq GenInsertStrRecordReq(string deviceId, List<string> measurements,
+            List<string> values, long timestamp, long sessionId, bool isAligned = false)
+        {
+            if (values.Count() != measurements.Count())
+            {
+                throw new ArgumentException("length of data types does not equal to length of values!");
+            }
+
+            return new TSInsertStringRecordReq(sessionId, deviceId, measurements, values, timestamp)
+            {
+                IsAligned = isAligned
+            };
+        }
+        public TSInsertStringRecordsReq GenInsertStringRecordsReq(List<string> deviceIds, List<List<string>> measurementsList,
+            List<List<string>> valuesList, List<long> timestamps, long sessionId, bool isAligned = false)
+        {
+            if (valuesList.Count() != measurementsList.Count())
+            {
+                throw new ArgumentException("length of data types does not equal to length of values!");
+            }
+
+            return new TSInsertStringRecordsReq(sessionId, deviceIds, measurementsList, valuesList, timestamps)
+            {
+                IsAligned = isAligned
+            };
+        }
+
+        public TSInsertRecordsReq GenInsertRecordsReq(List<string> deviceId, List<RowRecord> rowRecords,
+            long sessionId)
+        {
+            var measurementLst = rowRecords.Select(x => x.Measurements).ToList();
+            var timestampLst = rowRecords.Select(x => x.Timestamps).ToList();
+            var valuesLstInBytes = rowRecords.Select(row => row.ToBytes()).ToList();
+
+            return new TSInsertRecordsReq(sessionId, deviceId, measurementLst, valuesLstInBytes, timestampLst);
+        }
+        public async Task<int> InsertStringRecordAsync(string deviceId, List<string> measurements, List<string> values,
+            long timestamp)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertStrRecordReq(deviceId, measurements, values, timestamp, client.SessionId);
+
+                    var status = await client.ServiceClient.insertStringRecordAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert one string record to device {0}， server message: {1}", deviceId, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting a string record"
+            );
+        }
+        public async Task<int> InsertAlignedStringRecordAsync(string deviceId, List<string> measurements, List<string> values,
+            long timestamp)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertStrRecordReq(deviceId, measurements, values, timestamp, client.SessionId, true);
+
+                    var status = await client.ServiceClient.insertStringRecordAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert one record to device {0}， server message: {1}", deviceId, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting a string record"
+            );
+        }
+        public async Task<int> InsertStringRecordsAsync(List<string> deviceIds, List<List<string>> measurements, List<List<string>> values,
+            List<long> timestamps)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertStringRecordsReq(deviceIds, measurements, values, timestamps, client.SessionId);
+
+                    var status = await client.ServiceClient.insertStringRecordsAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert string records to devices {0}， server message: {1}", deviceIds, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting string records"
+            );
+        }
+        public async Task<int> InsertAlignedStringRecordsAsync(List<string> deviceIds, List<List<string>> measurements, List<List<string>> values,
+            List<long> timestamps)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertStringRecordsReq(deviceIds, measurements, values, timestamps, client.SessionId, true);
+
+                    var status = await client.ServiceClient.insertStringRecordsAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert string records to devices {0}， server message: {1}", deviceIds, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting string records"
+            );
+        }
+        public async Task<int> InsertRecordsAsync(List<string> deviceId, List<RowRecord> rowRecords)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertRecordsReq(deviceId, rowRecords, client.SessionId);
+
+                    var status = await client.ServiceClient.insertRecordsAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert multiple records to devices {0}, server message: {1}", deviceId, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting records"
+            );
+        }
+        public async Task<int> InsertAlignedRecordsAsync(List<string> deviceId, List<RowRecord> rowRecords)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertRecordsReq(deviceId, rowRecords, client.SessionId);
+                    req.IsAligned = true;
+                    // ASSERT that the insert plan is aligned
+                    System.Diagnostics.Debug.Assert(req.IsAligned == true);
+
+                    var status = await client.ServiceClient.insertRecordsAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert multiple records to devices {0}, server message: {1}", deviceId, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting records"
+            );
+        }
+        public TSInsertTabletReq GenInsertTabletReq(Tablet tablet, long sessionId)
+        {
+            return new TSInsertTabletReq(
+                sessionId,
+                tablet.InsertTargetName,
+                tablet.Measurements,
+                tablet.GetBinaryValues(),
+                tablet.GetBinaryTimestamps(),
+                tablet.GetDataTypes(),
+                tablet.RowNumber);
+        }
+        public async Task<int> InsertTabletAsync(Tablet tablet)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertTabletReq(tablet, client.SessionId);
+
+                    var status = await client.ServiceClient.insertTabletAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert one tablet to device {0}, server message: {1}", tablet.InsertTargetName, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting tablet"
+            );
+        }
+        public async Task<int> InsertAlignedTabletAsync(Tablet tablet)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertTabletReq(tablet, client.SessionId);
+                    req.IsAligned = true;
+
+                    var status = await client.ServiceClient.insertTabletAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert one aligned tablet to device {0}, server message: {1}", tablet.InsertTargetName, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting aligned tablet"
+            );
+        }
+
+        protected internal async Task<int> InsertRelationalTabletAsync(Tablet tablet)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertTabletReq(tablet, client.SessionId);
+                    req.ColumnCategories = tablet.GetColumnColumnCategories();
+                    req.WriteToTable = true;
+
+                    var status = await client.ServiceClient.insertTabletAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert one tablet to table {0}, server message: {1}", tablet.InsertTargetName, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting tablet"
+            );
+        }
+
+        public TSInsertTabletsReq GenInsertTabletsReq(List<Tablet> tabletLst, long sessionId)
+        {
+            var deviceIdLst = new List<string>();
+            var measurementsLst = new List<List<string>>();
+            var valuesLst = new List<byte[]>();
+            var timestampsLst = new List<byte[]>();
+            var typeLst = new List<List<int>>();
+            var sizeLst = new List<int>();
+
+            foreach (var tablet in tabletLst)
+            {
+                var dataTypeValues = tablet.GetDataTypes();
+                deviceIdLst.Add(tablet.InsertTargetName);
+                measurementsLst.Add(tablet.Measurements);
+                valuesLst.Add(tablet.GetBinaryValues());
+                timestampsLst.Add(tablet.GetBinaryTimestamps());
+                typeLst.Add(dataTypeValues);
+                sizeLst.Add(tablet.RowNumber);
+            }
+
+            return new TSInsertTabletsReq(
+                sessionId,
+                deviceIdLst,
+                measurementsLst,
+                valuesLst,
+                timestampsLst,
+                typeLst,
+                sizeLst);
+        }
+
+        public async Task<int> InsertTabletsAsync(List<Tablet> tabletLst)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertTabletsReq(tabletLst, client.SessionId);
+
+                    var status = await client.ServiceClient.insertTabletsAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert multiple tablets, message: {0}", status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting tablets"
+            );
+        }
+        public async Task<int> InsertAlignedTabletsAsync(List<Tablet> tabletLst)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertTabletsReq(tabletLst, client.SessionId);
+                    req.IsAligned = true;
+
+                    var status = await client.ServiceClient.insertTabletsAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert multiple aligned tablets, message: {0}", status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting aligned tablets"
+            );
+        }
+
+        public async Task<int> InsertRecordsOfOneDeviceAsync(string deviceId, List<RowRecord> rowRecords)
+        {
+            var sortedRowRecords = rowRecords.OrderBy(x => x.Timestamps).ToList();
+            return await InsertRecordsOfOneDeviceSortedAsync(deviceId, sortedRowRecords);
+        }
+        public async Task<int> InsertAlignedRecordsOfOneDeviceAsync(string deviceId, List<RowRecord> rowRecords)
+        {
+            var sortedRowRecords = rowRecords.OrderBy(x => x.Timestamps).ToList();
+            return await InsertAlignedRecordsOfOneDeviceSortedAsync(deviceId, sortedRowRecords);
+        }
+        public async Task<int> InsertStringRecordsOfOneDeviceAsync(string deviceId, List<long> timestamps,
+            List<List<string>> measurementsList, List<List<string>> valuesList)
+        {
+            var joined = timestamps.Zip(measurementsList, (t, m) => new { t, m })
+                .Zip(valuesList, (tm, v) => new { tm.t, tm.m, v })
+                .OrderBy(x => x.t);
+
+            var sortedTimestamps = joined.Select(x => x.t).ToList();
+            var sortedMeasurementsList = joined.Select(x => x.m).ToList();
+            var sortedValuesList = joined.Select(x => x.v).ToList();
+
+            return await InsertStringRecordsOfOneDeviceSortedAsync(deviceId, sortedTimestamps, sortedMeasurementsList, sortedValuesList, false);
+        }
+        public async Task<int> InsertAlignedStringRecordsOfOneDeviceAsync(string deviceId, List<long> timestamps,
+            List<List<string>> measurementsList, List<List<string>> valuesList)
+        {
+            var joined = timestamps.Zip(measurementsList, (t, m) => new { t, m })
+                .Zip(valuesList, (tm, v) => new { tm.t, tm.m, v })
+                .OrderBy(x => x.t);
+
+            var sortedTimestamps = joined.Select(x => x.t).ToList();
+            var sortedMeasurementsList = joined.Select(x => x.m).ToList();
+            var sortedValuesList = joined.Select(x => x.v).ToList();
+
+            return await InsertStringRecordsOfOneDeviceSortedAsync(deviceId, sortedTimestamps, sortedMeasurementsList, sortedValuesList, true);
+        }
+        public async Task<int> InsertStringRecordsOfOneDeviceSortedAsync(string deviceId, List<long> timestamps,
+            List<List<string>> measurementsList, List<List<string>> valuesList, bool isAligned)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    if (!_utilFunctions.IsSorted(timestamps))
+                    {
+                        throw new ArgumentException("insert string records of one device error: timestamp not sorted");
+                    }
+
+                    var req = GenInsertStringRecordsOfOneDeviceReq(deviceId, timestamps, measurementsList, valuesList, client.SessionId, isAligned);
+
+                    var status = await client.ServiceClient.insertStringRecordsOfOneDeviceAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert string records of one device, message: {0}", status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting string records of one device"
+            );
+        }
+        private TSInsertStringRecordsOfOneDeviceReq GenInsertStringRecordsOfOneDeviceReq(string deviceId,
+            List<long> timestamps, List<List<string>> measurementsList, List<List<string>> valuesList,
+             long sessionId, bool isAligned = false)
+        {
+            return new TSInsertStringRecordsOfOneDeviceReq(
+                sessionId,
+                deviceId,
+                measurementsList,
+                valuesList,
+                timestamps)
+            {
+                IsAligned = isAligned
+            };
+        }
+        private TSInsertRecordsOfOneDeviceReq GenInsertRecordsOfOneDeviceRequest(
+            string deviceId,
+            List<RowRecord> records,
+            long sessionId)
+        {
+            var values = records.Select(row => row.ToBytes());
+            var measurementsLst = records.Select(x => x.Measurements).ToList();
+            var timestampLst = records.Select(x => x.Timestamps).ToList();
+
+            return new TSInsertRecordsOfOneDeviceReq(
+                sessionId,
+                deviceId,
+                measurementsLst,
+                values.ToList(),
+                timestampLst);
+        }
+        public async Task<int> InsertRecordsOfOneDeviceSortedAsync(string deviceId, List<RowRecord> rowRecords)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var timestampLst = rowRecords.Select(x => x.Timestamps).ToList();
+
+                    if (!_utilFunctions.IsSorted(timestampLst))
+                    {
+                        throw new ArgumentException("insert records of one device error: timestamp not sorted");
+                    }
+
+                    var req = GenInsertRecordsOfOneDeviceRequest(deviceId, rowRecords, client.SessionId);
+
+                    var status = await client.ServiceClient.insertRecordsOfOneDeviceAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert records of one device, message: {0}", status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting records of one device"
+            );
+        }
+        public async Task<int> InsertAlignedRecordsOfOneDeviceSortedAsync(string deviceId, List<RowRecord> rowRecords)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var timestampLst = rowRecords.Select(x => x.Timestamps).ToList();
+
+                    if (!_utilFunctions.IsSorted(timestampLst))
+                    {
+                        throw new ArgumentException("insert records of one device error: timestamp not sorted");
+                    }
+
+                    var req = GenInsertRecordsOfOneDeviceRequest(deviceId, rowRecords, client.SessionId);
+                    req.IsAligned = true;
+
+                    var status = await client.ServiceClient.insertRecordsOfOneDeviceAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert aligned records of one device, message: {0}", status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when inserting aligned records of one device"
+            );
+        }
+        public async Task<int> TestInsertRecordAsync(string deviceId, RowRecord record)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = new TSInsertRecordReq(
+                        client.SessionId,
+                        deviceId,
+                        record.Measurements,
+                        record.ToBytes(),
+                        record.Timestamps);
+
+                    var status = await client.ServiceClient.testInsertRecordAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert one record to device {0}， server message: {1}", deviceId, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when test inserting one record"
+            );
+        }
+        public async Task<int> TestInsertRecordsAsync(List<string> deviceId, List<RowRecord> rowRecords)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertRecordsReq(deviceId, rowRecords, client.SessionId);
+
+                    var status = await client.ServiceClient.testInsertRecordsAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert multiple records to devices {0}, server message: {1}", deviceId, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when test inserting multiple records"
+            );
+        }
+        public async Task<int> TestInsertTabletAsync(Tablet tablet)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertTabletReq(tablet, client.SessionId);
+
+                    var status = await client.ServiceClient.testInsertTabletAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert one tablet to device {0}, server message: {1}", tablet.InsertTargetName, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when test inserting one tablet"
+            );
+        }
+        public async Task<int> TestInsertTabletsAsync(List<Tablet> tabletLst)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = GenInsertTabletsReq(tabletLst, client.SessionId);
+
+                    var status = await client.ServiceClient.testInsertTabletsAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("insert multiple tablets, message: {0}", status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when test inserting multiple tablets"
+            );
+        }
+
+        public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
+        {
+            // default timeout is 60s
+            return await ExecuteQueryStatementAsync(sql, 60 * 1000);
+        }
+
+        public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql, long timeoutInMs)
+        {
+            return await ExecuteClientOperationAsync<SessionDataSet>(
+                async client =>
+                {
+                    var req = new TSExecuteStatementReq(client.SessionId, sql, client.StatementId)
+                    {
+                        FetchSize = _fetchSize,
+                        Timeout = timeoutInMs
+                    };
+
+                    var resp = await client.ServiceClient.executeQueryStatementAsync(req);
+                    var status = resp.Status;
+
+                    if (_utilFunctions.VerifySuccess(status) == -1)
+                    {
+                        throw new Exception(string.Format("execute query failed, sql: {0}, message: {1}", sql, status.Message));
+                    }
+
+                    return new SessionDataSet(sql, resp, client, _clients, client.StatementId)
+                    {
+                        FetchSize = _fetchSize,
+                    };
+                },
+                errMsg: "Error occurs when executing query statement",
+                putClientBack: false
+            );
+        }
+
+        public async Task<SessionDataSet> ExecuteStatementAsync(string sql, long timeout)
+        {
+            return await ExecuteClientOperationAsync<SessionDataSet>(
+                async client =>
+                {
+                    var req = new TSExecuteStatementReq(client.SessionId, sql, client.StatementId)
+                    {
+                        FetchSize = _fetchSize,
+                        Timeout = timeout
+                    };
+
+                    var resp = await client.ServiceClient.executeStatementAsync(req);
+                    var status = resp.Status;
+
+                    if (_utilFunctions.VerifySuccess(status) == -1)
+                    {
+                        throw new Exception(string.Format("execute query failed, sql: {0}, message: {1}", sql, status.Message));
+                    }
+
+                    return new SessionDataSet(sql, resp, client, _clients, client.StatementId)
+                    {
+                        FetchSize = _fetchSize,
+                    };
+                },
+                errMsg: "Error occurs when executing query statement",
+                putClientBack: false
+            );
+        }
+
+
+        public async Task<int> ExecuteNonQueryStatementAsync(string sql)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    String previousDB = _database;
+                    var req = new TSExecuteStatementReq(client.SessionId, sql, client.StatementId);
+
+                    var resp = await client.ServiceClient.executeUpdateStatementAsync(req);
+                    var status = resp.Status;
+
+                    if (resp.__isset.database)
+                    {
+                        this._database = resp.Database;
+                    }
+                    if (_database != previousDB)
+                    {
+                        // all client should switch to the same database
+                        foreach (var c in _clients.ClientQueue)
+                        {
+                            try
+                            {
+                                if (c != client)
+                                {
+                                    var switchReq = new TSExecuteStatementReq(c.SessionId, sql, c.StatementId);
+                                    await c.ServiceClient.executeUpdateStatementAsync(switchReq);
+                                }
+                            }
+                            catch (Exception e)
+                            {
+                                _logger.LogError("switch database from {0} to {1} failed for {2}, error: {3}", previousDB, _database, c.SessionId, e.Message);
+                            }
+                        }
+                        _logger.LogInformation("switch database from {0} to {1}", previousDB, _database);
+                    }
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("execute non-query statement {0} message: {1}", sql, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when executing non-query statement"
+            );
+        }
+        public async Task<SessionDataSet> ExecuteRawDataQuery(List<string> paths, long startTime, long endTime)
+        {
+            return await ExecuteClientOperationAsync<SessionDataSet>(
+                async client =>
+                {
+                    var req = new TSRawDataQueryReq(client.SessionId, paths, startTime, endTime, client.StatementId)
+                    {
+                        FetchSize = _fetchSize,
+                        EnableRedirectQuery = false
+                    };
+
+                    var resp = await client.ServiceClient.executeRawDataQueryAsync(req);
+                    var status = resp.Status;
+
+                    if (_utilFunctions.VerifySuccess(status) == -1)
+                    {
+                        throw new Exception(string.Format("execute raw data query failed, message: {0}", status.Message));
+                    }
+
+                    return new SessionDataSet("", resp, client, _clients, client.StatementId)
+                    {
+                        FetchSize = _fetchSize,
+                    };
+                },
+                errMsg: "Error occurs when executing raw data query",
+                putClientBack: false
+            );
+        }
+        public async Task<SessionDataSet> ExecuteLastDataQueryAsync(List<string> paths, long lastTime)
+        {
+            return await ExecuteClientOperationAsync<SessionDataSet>(
+                async client =>
+                {
+                    var req = new TSLastDataQueryReq(client.SessionId, paths, lastTime, client.StatementId)
+                    {
+                        FetchSize = _fetchSize,
+                        EnableRedirectQuery = false
+                    };
+
+                    var resp = await client.ServiceClient.executeLastDataQueryAsync(req);
+                    var status = resp.Status;
+
+                    if (_utilFunctions.VerifySuccess(status) == -1)
+                    {
+                        throw new Exception(string.Format("execute last data query failed, message: {0}", status.Message));
+                    }
+
+                    return new SessionDataSet("", resp, client, _clients, client.StatementId)
+                    {
+                        FetchSize = _fetchSize,
+                    };
+                },
+                errMsg: "Error occurs when executing last data query",
+                putClientBack: false
+            );
+        }
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<int> CreateSchemaTemplateAsync(Template template)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = new TSCreateSchemaTemplateReq(client.SessionId, template.Name, template.ToBytes());
+
+                    var status = await client.ServiceClient.createSchemaTemplateAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("create schema template {0} message: {1}", template.Name, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when creating schema template"
+            );
+        }
+
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<int> DropSchemaTemplateAsync(string templateName)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = new TSDropSchemaTemplateReq(client.SessionId, templateName);
+
+                    var status = await client.ServiceClient.dropSchemaTemplateAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("drop schema template {0} message: {1}", templateName, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when dropping schema template"
+            );
+        }
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<int> SetSchemaTemplateAsync(string templateName, string prefixPath)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = new TSSetSchemaTemplateReq(client.SessionId, templateName, prefixPath);
+
+                    var status = await client.ServiceClient.setSchemaTemplateAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("set schema template {0} message: {1}", templateName, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when setting schema template"
+            );
+        }
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<int> UnsetSchemaTemplateAsync(string prefixPath, string templateName)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = new TSUnsetSchemaTemplateReq(client.SessionId, prefixPath, templateName);
+
+                    var status = await client.ServiceClient.unsetSchemaTemplateAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("unset schema template {0} message: {1}", templateName, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when unsetting schema template"
+            );
+        }
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<int> DeleteNodeInTemplateAsync(string templateName, string path)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = new TSPruneSchemaTemplateReq(client.SessionId, templateName, path);
+
+                    var status = await client.ServiceClient.pruneSchemaTemplateAsync(req);
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("delete node in template {0} message: {1}", templateName, status.Message);
+                    }
+
+                    return _utilFunctions.VerifySuccess(status);
+                },
+                errMsg: "Error occurs when deleting node in template"
+            );
+        }
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<int> CountMeasurementsInTemplateAsync(string name)
+        {
+            return await ExecuteClientOperationAsync<int>(
+                async client =>
+                {
+                    var req = new TSQueryTemplateReq(client.SessionId, name, (int)TemplateQueryType.COUNT_MEASUREMENTS);
+
+                    var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
+                    var status = resp.Status;
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("count measurements in template {0} message: {1}", name, status.Message);
+                    }
+
+                    if (_utilFunctions.VerifySuccess(status) == -1)
+                    {
+                        throw new Exception(string.Format("count measurements in template failed, template name: {0}, message: {1}", name, status.Message));
+                    }
+                    return resp.Count;
+                },
+                errMsg: "Error occurs when counting measurements in template"
+            );
+        }
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<bool> IsMeasurementInTemplateAsync(string templateName, string path)
+        {
+            return await ExecuteClientOperationAsync<bool>(
+                async client =>
+                {
+                    var req = new TSQueryTemplateReq(client.SessionId, templateName, (int)TemplateQueryType.IS_MEASUREMENT);
+                    req.Measurement = path;
+
+                    var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
+                    var status = resp.Status;
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("is measurement in template {0} message: {1}", templateName, status.Message);
+                    }
+
+                    if (_utilFunctions.VerifySuccess(status) == -1)
+                    {
+                        throw new Exception(string.Format("is measurement in template failed, template name: {0}, message: {1}", templateName, status.Message));
+                    }
+                    return resp.Result;
+                },
+                errMsg: "Error occurs when checking measurement in template"
+            );
+        }
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<bool> IsPathExistInTemplateAsync(string templateName, string path)
+        {
+            return await ExecuteClientOperationAsync<bool>(
+                async client =>
+                {
+                    var req = new TSQueryTemplateReq(client.SessionId, templateName, (int)TemplateQueryType.PATH_EXIST);
+                    req.Measurement = path;
+
+                    var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
+                    var status = resp.Status;
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("is path exist in template {0} message: {1}", templateName, status.Message);
+                    }
+
+                    if (_utilFunctions.VerifySuccess(status) == -1)
+                    {
+                        throw new Exception(string.Format("is path exist in template failed, template name: {0}, message: {1}", templateName, status.Message));
+                    }
+                    return resp.Result;
+                },
+                errMsg: "Error occurs when checking path exist in template"
+            );
+        }
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<List<string>> ShowMeasurementsInTemplateAsync(string templateName, string pattern = "")
+        {
+            return await ExecuteClientOperationAsync<List<string>>(
+                async client =>
+                {
+                    var req = new TSQueryTemplateReq(client.SessionId, templateName, (int)TemplateQueryType.SHOW_MEASUREMENTS);
+                    req.Measurement = pattern;
+
+                    var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
+                    var status = resp.Status;
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("get measurements in template {0} message: {1}", templateName, status.Message);
+                    }
+
+                    if (_utilFunctions.VerifySuccess(status) == -1)
+                    {
+                        throw new Exception(string.Format("show measurements in template failed, template name: {0}, pattern: {1}, message: {2}", templateName, pattern, status.Message));
+                    }
+                    return resp.Measurements;
+                },
+                errMsg: "Error occurs when showing measurements in template"
+            );
+        }
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<List<string>> ShowAllTemplatesAsync()
+        {
+            return await ExecuteClientOperationAsync<List<string>>(
+                async client =>
+                {
+                    var req = new TSQueryTemplateReq(client.SessionId, "", (int)TemplateQueryType.SHOW_TEMPLATES);
+
+                    var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
+                    var status = resp.Status;
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("get all templates message: {0}", status.Message);
+                    }
+
+                    if (_utilFunctions.VerifySuccess(status) == -1)
+                    {
+                        throw new Exception(string.Format("show all templates failed, message: {0}", status.Message));
+                    }
+                    return resp.Measurements;
+                },
+                errMsg: "Error occurs when getting all templates"
+            );
+        }
+
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<List<string>> ShowPathsTemplateSetOnAsync(string templateName)
+        {
+            return await ExecuteClientOperationAsync<List<string>>(
+                async client =>
+                {
+                    var req = new TSQueryTemplateReq(client.SessionId, templateName, (int)TemplateQueryType.SHOW_SET_TEMPLATES);
+
+                    var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
+                    var status = resp.Status;
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("get paths template set on {0} message: {1}", templateName, status.Message);
+                    }
+
+                    if (_utilFunctions.VerifySuccess(status) == -1)
+                    {
+                        throw new Exception(string.Format("show paths template set on failed, template name: {0}, message: {1}", templateName, status.Message));
+                    }
+                    return resp.Measurements;
+                },
+                errMsg: "Error occurs when getting paths template set on"
+            );
+        }
+        [Obsolete("This method is obsolete. Use SQL instead.", false)]
+        public async Task<List<string>> ShowPathsTemplateUsingOnAsync(string templateName)
+        {
+            return await ExecuteClientOperationAsync<List<string>>(
+                async client =>
+                {
+                    var req = new TSQueryTemplateReq(client.SessionId, templateName, (int)TemplateQueryType.SHOW_USING_TEMPLATES);
+
+                    var resp = await client.ServiceClient.querySchemaTemplateAsync(req);
+                    var status = resp.Status;
+
+                    if (_debugMode)
+                    {
+                        _logger.LogInformation("get paths template using on {0} message: {1}", templateName, status.Message);
+                    }
+
+                    if (_utilFunctions.VerifySuccess(status) == -1)
+                    {
+                        throw new Exception(string.Format("show paths template using on failed, template name: {0}, message: {1}", templateName, status.Message));
+                    }
+                    return resp.Measurements;
+                },
+                errMsg: "Error occurs when getting paths template using on"
+            );
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!disposedValue)
+            {
+                if (disposing)
+                {
 #if NET461_OR_GREATER || NETSTANDARD2_0
 #else
-          _clients.ClientQueue.Clear();
+                    _clients.ClientQueue.Clear();
 #endif
+                }
+                _clients = null;
+                disposedValue = true;
+            }
         }
-        _clients = null;
-        disposedValue = true;
-      }
-    }
 
-    public void Dispose()
-    {
-      Dispose(disposing: true);
-      GC.SuppressFinalize(this);
+        public void Dispose()
+        {
+            Dispose(disposing: true);
+            GC.SuppressFinalize(this);
+        }
     }
-  }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/TableSessionPool.Builder.cs b/src/Apache.IoTDB/TableSessionPool.Builder.cs
index 0c32f4b..fdeb78e 100644
--- a/src/Apache.IoTDB/TableSessionPool.Builder.cs
+++ b/src/Apache.IoTDB/TableSessionPool.Builder.cs
@@ -26,121 +26,121 @@
 
 public partial class TableSessionPool
 {
-  public class Builder
-  {
-    private string _host = "localhost";
-    private int _port = 6667;
-    private string _username = "root";
-    private string _password = "root";
-    private int _fetchSize = 1024;
-    private string _zoneId = "UTC+08:00";
-    private int _poolSize = 8;
-    private bool _enableRpcCompression = false;
-    private int _connectionTimeoutInMs = 500;
-    private string _sqlDialect = IoTDBConstant.TREE_SQL_DIALECT;
-    private string _database = "";
-    private List<string> _nodeUrls = new List<string>();
-
-    public Builder SetHost(string host)
+    public class Builder
     {
-      _host = host;
-      return this;
-    }
+        private string _host = "localhost";
+        private int _port = 6667;
+        private string _username = "root";
+        private string _password = "root";
+        private int _fetchSize = 1024;
+        private string _zoneId = "UTC+08:00";
+        private int _poolSize = 8;
+        private bool _enableRpcCompression = false;
+        private int _connectionTimeoutInMs = 500;
+        private string _sqlDialect = IoTDBConstant.TREE_SQL_DIALECT;
+        private string _database = "";
+        private List<string> _nodeUrls = new List<string>();
 
-    public Builder SetPort(int port)
-    {
-      _port = port;
-      return this;
-    }
+        public Builder SetHost(string host)
+        {
+            _host = host;
+            return this;
+        }
 
-    public Builder SetUsername(string username)
-    {
-      _username = username;
-      return this;
-    }
+        public Builder SetPort(int port)
+        {
+            _port = port;
+            return this;
+        }
 
-    public Builder SetPassword(string password)
-    {
-      _password = password;
-      return this;
-    }
+        public Builder SetUsername(string username)
+        {
+            _username = username;
+            return this;
+        }
 
-    public Builder SetFetchSize(int fetchSize)
-    {
-      _fetchSize = fetchSize;
-      return this;
-    }
+        public Builder SetPassword(string password)
+        {
+            _password = password;
+            return this;
+        }
 
-    public Builder SetZoneId(string zoneId)
-    {
-      _zoneId = zoneId;
-      return this;
-    }
+        public Builder SetFetchSize(int fetchSize)
+        {
+            _fetchSize = fetchSize;
+            return this;
+        }
 
-    public Builder SetPoolSize(int poolSize)
-    {
-      _poolSize = poolSize;
-      return this;
-    }
+        public Builder SetZoneId(string zoneId)
+        {
+            _zoneId = zoneId;
+            return this;
+        }
 
-    public Builder SetEnableRpcCompression(bool enableRpcCompression)
-    {
-      _enableRpcCompression = enableRpcCompression;
-      return this;
-    }
+        public Builder SetPoolSize(int poolSize)
+        {
+            _poolSize = poolSize;
+            return this;
+        }
 
-    public Builder SetConnectionTimeoutInMs(int timeout)
-    {
-      _connectionTimeoutInMs = timeout;
-      return this;
-    }
+        public Builder SetEnableRpcCompression(bool enableRpcCompression)
+        {
+            _enableRpcCompression = enableRpcCompression;
+            return this;
+        }
 
-    public Builder SetNodeUrls(List<string> nodeUrls)
-    {
-      _nodeUrls = nodeUrls;
-      return this;
-    }
+        public Builder SetConnectionTimeoutInMs(int timeout)
+        {
+            _connectionTimeoutInMs = timeout;
+            return this;
+        }
 
-    protected internal Builder SetSqlDialect(string sqlDialect)
-    {
-      _sqlDialect = sqlDialect;
-      return this;
-    }
+        public Builder SetNodeUrls(List<string> nodeUrls)
+        {
+            _nodeUrls = nodeUrls;
+            return this;
+        }
 
-    public Builder SetDatabase(string database)
-    {
-      _database = database;
-      return this;
-    }
+        protected internal Builder SetSqlDialect(string sqlDialect)
+        {
+            _sqlDialect = sqlDialect;
+            return this;
+        }
 
-    public Builder()
-    {
-      _host = "localhost";
-      _port = 6667;
-      _username = "root";
-      _password = "root";
-      _fetchSize = 1024;
-      _zoneId = "UTC+08:00";
-      _poolSize = 8;
-      _enableRpcCompression = false;
-      _connectionTimeoutInMs = 500;
-      _sqlDialect = IoTDBConstant.TABLE_SQL_DIALECT;
-      _database = "";
-    }
+        public Builder SetDatabase(string database)
+        {
+            _database = database;
+            return this;
+        }
 
-    public TableSessionPool Build()
-    {
-      SessionPool sessionPool;
-      // if nodeUrls is not empty, use nodeUrls to create session pool
-      if (_nodeUrls.Count > 0)
-      {
-        sessionPool = new SessionPool(_nodeUrls, _username, _password, _fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs, _sqlDialect, _database);
-      }
-      else
-      {
-        sessionPool = new SessionPool(_host, _port, _username, _password, _fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs, _sqlDialect, _database);
-      }
-      return new TableSessionPool(sessionPool);
+        public Builder()
+        {
+            _host = "localhost";
+            _port = 6667;
+            _username = "root";
+            _password = "root";
+            _fetchSize = 1024;
+            _zoneId = "UTC+08:00";
+            _poolSize = 8;
+            _enableRpcCompression = false;
+            _connectionTimeoutInMs = 500;
+            _sqlDialect = IoTDBConstant.TABLE_SQL_DIALECT;
+            _database = "";
+        }
+
+        public TableSessionPool Build()
+        {
+            SessionPool sessionPool;
+            // if nodeUrls is not empty, use nodeUrls to create session pool
+            if (_nodeUrls.Count > 0)
+            {
+                sessionPool = new SessionPool(_nodeUrls, _username, _password, _fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs, _sqlDialect, _database);
+            }
+            else
+            {
+                sessionPool = new SessionPool(_host, _port, _username, _password, _fetchSize, _zoneId, _poolSize, _enableRpcCompression, _connectionTimeoutInMs, _sqlDialect, _database);
+            }
+            return new TableSessionPool(sessionPool);
+        }
     }
-  }
 }
diff --git a/src/Apache.IoTDB/TableSessionPool.cs b/src/Apache.IoTDB/TableSessionPool.cs
index ddc977f..921aba1 100644
--- a/src/Apache.IoTDB/TableSessionPool.cs
+++ b/src/Apache.IoTDB/TableSessionPool.cs
@@ -28,50 +28,50 @@
 
 public partial class TableSessionPool
 {
-  private SessionPool sessionPool;
+    private SessionPool sessionPool;
 
-  TableSessionPool(SessionPool sessionPool)
-  {
-    this.sessionPool = sessionPool;
-  }
+    TableSessionPool(SessionPool sessionPool)
+    {
+        this.sessionPool = sessionPool;
+    }
 
-  public async Task Open(bool enableRpcCompression, CancellationToken cancellationToken = default)
-  {
-    await sessionPool.Open(enableRpcCompression, cancellationToken);
-  }
+    public async Task Open(bool enableRpcCompression, CancellationToken cancellationToken = default)
+    {
+        await sessionPool.Open(enableRpcCompression, cancellationToken);
+    }
 
-  public async Task Open(CancellationToken cancellationToken = default)
-  {
-    await sessionPool.Open(cancellationToken);
-  }
+    public async Task Open(CancellationToken cancellationToken = default)
+    {
+        await sessionPool.Open(cancellationToken);
+    }
 
-  public async Task<int> InsertAsync(Tablet tablet)
-  {
-    return await sessionPool.InsertRelationalTabletAsync(tablet);
-  }
+    public async Task<int> InsertAsync(Tablet tablet)
+    {
+        return await sessionPool.InsertRelationalTabletAsync(tablet);
+    }
 
-  public async Task<int> ExecuteNonQueryStatementAsync(string sql)
-  {
-    return await sessionPool.ExecuteNonQueryStatementAsync(sql);
-  }
+    public async Task<int> ExecuteNonQueryStatementAsync(string sql)
+    {
+        return await sessionPool.ExecuteNonQueryStatementAsync(sql);
+    }
 
-  public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
-  {
-    return await sessionPool.ExecuteQueryStatementAsync(sql);
-  }
+    public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql)
+    {
+        return await sessionPool.ExecuteQueryStatementAsync(sql);
+    }
 
-  public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql, long timeoutInMs)
-  {
-    return await sessionPool.ExecuteQueryStatementAsync(sql, timeoutInMs);
-  }
+    public async Task<SessionDataSet> ExecuteQueryStatementAsync(string sql, long timeoutInMs)
+    {
+        return await sessionPool.ExecuteQueryStatementAsync(sql, timeoutInMs);
+    }
 
-  public void OpenDebugMode(Action<ILoggingBuilder> configure)
-  {
-    sessionPool.OpenDebugMode(configure);
-  }
+    public void OpenDebugMode(Action<ILoggingBuilder> configure)
+    {
+        sessionPool.OpenDebugMode(configure);
+    }
 
-  public async Task Close()
-  {
-    await sessionPool.Close();
-  }
+    public async Task Close()
+    {
+        await sessionPool.Close();
+    }
 }
diff --git a/src/Apache.IoTDB/Template/InternalNode.cs b/src/Apache.IoTDB/Template/InternalNode.cs
index f08ecf6..50a4cc4 100644
--- a/src/Apache.IoTDB/Template/InternalNode.cs
+++ b/src/Apache.IoTDB/Template/InternalNode.cs
@@ -58,4 +58,4 @@
             return this.shareTime;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/Template/MeasurementNode.cs b/src/Apache.IoTDB/Template/MeasurementNode.cs
index 790ca0f..bed6604 100644
--- a/src/Apache.IoTDB/Template/MeasurementNode.cs
+++ b/src/Apache.IoTDB/Template/MeasurementNode.cs
@@ -73,4 +73,4 @@
 
 
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/Template/Template.cs b/src/Apache.IoTDB/Template/Template.cs
index 74830a2..b14e51f 100644
--- a/src/Apache.IoTDB/Template/Template.cs
+++ b/src/Apache.IoTDB/Template/Template.cs
@@ -141,4 +141,4 @@
 
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/Template/TemplateNode.cs b/src/Apache.IoTDB/Template/TemplateNode.cs
index 325e43c..c2614e5 100644
--- a/src/Apache.IoTDB/Template/TemplateNode.cs
+++ b/src/Apache.IoTDB/Template/TemplateNode.cs
@@ -57,4 +57,4 @@
             return null;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/Apache.IoTDB/Utils.cs b/src/Apache.IoTDB/Utils.cs
index d50a08d..627314c 100644
--- a/src/Apache.IoTDB/Utils.cs
+++ b/src/Apache.IoTDB/Utils.cs
@@ -106,15 +106,15 @@
 
         public static int ParseDateToInt(DateTime? dateTime)
         {
-          if (dateTime == null)
-          {
-              throw new ArgumentException("Date expression is none or empty.");
-          }
-          if(dateTime.Value.Year<1000)
-          {
-              throw new ArgumentException("Year must be between 1000 and 9999.");
-          }
-          return dateTime.Value.Year * 10000 + dateTime.Value.Month * 100 + dateTime.Value.Day;
+            if (dateTime == null)
+            {
+                throw new ArgumentException("Date expression is none or empty.");
+            }
+            if (dateTime.Value.Year < 1000)
+            {
+                throw new ArgumentException("Year must be between 1000 and 9999.");
+            }
+            return dateTime.Value.Year * 10000 + dateTime.Value.Month * 100 + dateTime.Value.Day;
         }
 
         public static string ByteArrayToHexString(byte[] bytes)
@@ -122,4 +122,4 @@
             return "0x" + BitConverter.ToString(bytes).Replace("-", "").ToLowerInvariant();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/Apache.IoTDB.Integration.Tests/Tests.cs b/tests/Apache.IoTDB.Integration.Tests/Tests.cs
index 19b3dec..b180ab6 100644
--- a/tests/Apache.IoTDB.Integration.Tests/Tests.cs
+++ b/tests/Apache.IoTDB.Integration.Tests/Tests.cs
@@ -34,4 +34,4 @@
             Assert.Pass();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/Apache.IoTDB.Tests/Tests.cs b/tests/Apache.IoTDB.Tests/Tests.cs
index 6a78663..d796fa7 100644
--- a/tests/Apache.IoTDB.Tests/Tests.cs
+++ b/tests/Apache.IoTDB.Tests/Tests.cs
@@ -34,4 +34,4 @@
             Assert.Pass();
         }
     }
-}
\ No newline at end of file
+}
