You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ha...@apache.org on 2022/12/30 03:27:36 UTC

[iotdb] branch master updated: Revert "[IOTDB-4804] Cpp Client SDK bug-fix (#8555)" (#8675)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new d5b0b1127a Revert "[IOTDB-4804] Cpp Client SDK bug-fix (#8555)" (#8675)
d5b0b1127a is described below

commit d5b0b1127acb0124cfdfc4b564942fb6b588a83c
Author: Haonan <hh...@outlook.com>
AuthorDate: Fri Dec 30 11:27:29 2022 +0800

    Revert "[IOTDB-4804] Cpp Client SDK bug-fix (#8555)" (#8675)
    
    This reverts commit 7912781019539e3641622321b22a85c884430917.
---
 .github/workflows/client-cpp.yml                   |   4 +-
 client-cpp/compile_iotdb_session_lib.sh            |  57 ------
 client-cpp/cpp_demo/compile_demo.sh                |  32 ----
 client-cpp/cpp_demo/demo.cpp                       | 142 ---------------
 client-cpp/pom.xml                                 | 196 ++++++++++++++++++++
 client-cpp/src/main/Session.cpp                    |   5 +-
 client-cpp/src/main/Session.h                      | 125 ++++++-------
 client-cpp/src/test/CMakeLists.txt                 |   1 -
 client-cpp/src/test/compile_test.sh                |  29 ---
 client-cpp/src/test/cpp/sessionIT.cpp              |  90 +++-------
 client-cpp/src/test/main.cpp                       |   4 +-
 example/client-cpp-example/README.md               |  48 +++++
 example/client-cpp-example/pom.xml                 | 198 +++++++++++++++++++++
 .../src}/AlignedTimeseriesSessionExample.cpp       |   0
 example/client-cpp-example/src/CMakeLists.txt      |  47 +++++
 .../client-cpp-example/src}/SessionExample.cpp     |  26 +--
 16 files changed, 571 insertions(+), 433 deletions(-)

diff --git a/.github/workflows/client-cpp.yml b/.github/workflows/client-cpp.yml
index fdb510a6ce..167f13ebc8 100644
--- a/.github/workflows/client-cpp.yml
+++ b/.github/workflows/client-cpp.yml
@@ -63,7 +63,7 @@ jobs:
           key: client-${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
           restore-keys: ${{ runner.os }}-m2-
       - name: Test with Maven
-        run: mvn -B clean integration-test -P compile-cpp -Dtsfile.test.skip=true -Djdbc.test.skip=true -Diotdb.test.skip=true -Dconsensus.test.skip=true -Dcommons.test.skip=true -Dtest.port.closed=true -pl server,client-cpp -am
+        run: mvn -B clean integration-test -P compile-cpp -Dtsfile.test.skip=true -Djdbc.test.skip=true -Diotdb.test.skip=true -Dconsensus.test.skip=true -Dcommons.test.skip=true -Dtest.port.closed=true -pl server,client-cpp,example/client-cpp-example -am
 
   build-win:
     strategy:
@@ -103,4 +103,4 @@ jobs:
         run: cd /d/a/cpp && unzip win_flex_bison.zip && mv win_flex.exe flex.exe && mv win_bison.exe bison.exe  && echo 'export PATH=/d/a/cpp:$PATH' >> ~/.bash_profile && source ~/.bash_profile
       - name: Test with Maven
         shell: bash
-        run: source ~/.bash_profile && mvn -B clean integration-test -P compile-cpp -Dboost.include.dir=/c/local/boost_1_78_0 -Dboost.library.dir=/c/local/boost_1_78_0/stage/lib -Dtsfile.test.skip=true -Djdbc.test.skip=true -Diotdb.test.skip=true -Dconsensus.test.skip=true -Dcommons.test.skip=true -Dtest.port.closed=true -Denforcer.skip=true -pl server,client-cpp -am -Dcmake.url="https://github.com/Kitware/CMake/releases/download/v3.21.6/cmake-3.21.6-windows-x86_64.zip" -Dcmake.root.dir= [...]
+        run: source ~/.bash_profile && mvn -B clean integration-test -P compile-cpp -Dboost.include.dir=/c/local/boost_1_78_0 -Dboost.library.dir=/c/local/boost_1_78_0/stage/lib -Dtsfile.test.skip=true -Djdbc.test.skip=true -Diotdb.test.skip=true -Dconsensus.test.skip=true -Dcommons.test.skip=true -Dtest.port.closed=true -Denforcer.skip=true -pl server,client-cpp,example/client-cpp-example -am -Dcmake.url="https://github.com/Kitware/CMake/releases/download/v3.21.6/cmake-3.21.6-windows-x8 [...]
diff --git a/client-cpp/compile_iotdb_session_lib.sh b/client-cpp/compile_iotdb_session_lib.sh
deleted file mode 100755
index 5cd66e5539..0000000000
--- a/client-cpp/compile_iotdb_session_lib.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-thrift_bin=/usr/local/bin/thrift
-thrift_lib=/usr/local/lib
-
-### if you are compiling for 32bit CPU such as armv7l etc(maybe in an armv7l
-### server or using a cross-compile toolchain.
-### you should adefine ARCH32 to specify it.
-#
-# CXX_FLAGS_DEFINED="-DARCH32"
-
-CXX_FLAGS="-O2 -g -std=c++11 -lthrift"
-CXX_SO_FLAGS="-shared -fPIC"
-
-source_file="Session.cpp gen-cpp/common_types.cpp gen-cpp/IClientRPCService.cpp gen-cpp/client_types.cpp gen-cpp/IClientRPCService_server.skeleton.cpp"
-include_file="Session.h gen-cpp/common_types.h gen-cpp/IClientRPCService.h gen-cpp/client_types.h"
-
-common_thrift_dir=../thrift-commons/src/main/thrift
-client_thrift_dir=../thrift/src/main/thrift
-
-$thrift_bin --gen cpp -o src/main/ $common_thrift_dir/common.thrift
-$thrift_bin --gen cpp -o src/main/ -I $common_thrift_dir $client_thrift_dir/client.thrift
-
-cd src/main
-LD_LIBRARY_PATH=$thrift_lib g++ -Igen-cpp $CXX_FLAGS $CXX_SO_FLAGS $CXX_FLAGS_DEFINED -o libiotdb_session.so $source_file
-
-# back to iotdb/client-cpp
-cd ../../
-mkdir iotdb_cpp_client_sdk
-mkdir iotdb_cpp_client_sdk/include iotdb_cpp_client_sdk/lib
-cp $thrift_lib/libthrift-0.14.0.so  iotdb_cpp_client_sdk/lib/
-cp src/main/libiotdb_session.so iotdb_cpp_client_sdk/lib/
-
-cp src/main/Session.h iotdb_cpp_client_sdk/include/
-cp src/main/gen-cpp/*.h iotdb_cpp_client_sdk/include/
-
-tar cvf iotdb_cpp_client_sdk.tar iotdb_cpp_client_sdk
-
-
diff --git a/client-cpp/cpp_demo/compile_demo.sh b/client-cpp/cpp_demo/compile_demo.sh
deleted file mode 100755
index 1638e82ec3..0000000000
--- a/client-cpp/cpp_demo/compile_demo.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-CXX_FLAGS="-O2 -g -std=c++11 "
-IOTDB_SESSION_SDK=../iotdb_cpp_client_sdk
-
-export LD_LIBRARY_PATH=${IOTDB_SESSION_SDK}/lib
-g++ $CXX_FLAGS -o demo demo.cpp -liotdb_session -lthrift -L${IOTDB_SESSION_SDK}/lib -I${IOTDB_SESSION_SDK}/include
-g++ $CXX_FLAGS -o SessionExample SessionExample.cpp -liotdb_session -lthrift -L${IOTDB_SESSION_SDK}/lib -I${IOTDB_SESSION_SDK}/include
-g++ $CXX_FLAGS -o AlignedTimeseriesSessionExample AlignedTimeseriesSessionExample.cpp -liotdb_session -lthrift -L${IOTDB_SESSION_SDK}/lib -I${IOTDB_SESSION_SDK}/include
-
-## run test like this:
-# DEMO__total_row_count=20 DEMO__cmd='a' DEMO__max_row_num=5 DEMO__measurement_num=3 ./demo
-# ./SessionExample
-# ./AlignedTimeseriesSessionExample
diff --git a/client-cpp/cpp_demo/demo.cpp b/client-cpp/cpp_demo/demo.cpp
deleted file mode 100644
index fec61d244f..0000000000
--- a/client-cpp/cpp_demo/demo.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "Session.h" // from iotdb_session_sdk
-#include <string>
-#include <vector>
-#include <sstream>
-
-void print_sizeof()
-{
-  std::cout << "sizeof(bool) = " << sizeof(bool) << std::endl;
-  std::cout << "sizeof(char) = " << sizeof(char) << std::endl;
-  std::cout << "sizeof(int) = " << sizeof(int) << std::endl;
-  std::cout << "sizeof(long) = " << sizeof(long) << std::endl;
-  std::cout << "sizeof(void*) = " << sizeof(void*) << std::endl;
-  std::cout << "sizeof(int32_t) = " << sizeof(int32_t) << std::endl;
-  std::cout << "sizeof(int64_t) = " << sizeof(int64_t) << std::endl;
-}
-
-int64_t total_row_count = 0;
-char cmd = 'a';
-int max_row_num = 5;
-int measurement_num = 3;
-
-
-const char* parse_ev(const char *ev_name)
-{
-  const char *ev = getenv(ev_name);
-  if (ev == nullptr) {
-    printf("you need specify environment variable: %s\n", ev_name);
-    exit(1);
-  }
-  return ev;
-}
-
-void parse_param()
-{
-  printf("get param from enviroment variables: DEMO__total_row_count, "
-      "DEMO__cmd, DEMO__max_row_num, DEMO__measurement_num\n");
-
-  total_row_count = atol(parse_ev("DEMO__total_row_count"));
-  cmd = parse_ev("DEMO__cmd")[0];
-  max_row_num = atoi(parse_ev("DEMO__max_row_num"));
-  measurement_num = atoi(parse_ev("DEMO__measurement_num"));
-
-  printf("total_row_count=%lld, cmd=%c, max_row_num=%d, measurement_num=%d\n",
-      total_row_count, cmd, max_row_num, measurement_num);
-}
-
-int64_t get_ms()
-{
-  struct timeval tp;
-  gettimeofday(&tp, NULL);
-  return tp.tv_sec * 1000 + tp.tv_usec / 1000;
-}
-
-int main(int argc, char **args)
-{
-  print_sizeof();
-
-  parse_param();
-
-  const char *device_id = "root.sg01.d01";
-  Session *session = new Session("127.0.0.1", 6667, "root", "root");
-  session->open(false);
-
-  std::vector<std::pair<std::string, TSDataType::TSDataType>> schemas;
-  for (int i = 0; i < measurement_num; i++) {
-    char buf[16];
-    sprintf(buf, "sensor_%d", i);
-    std::pair<std::string, TSDataType::TSDataType> p(std::string(buf), TSDataType::INT64);
-    schemas.push_back(p);
-  }
-
-  Tablet tablet(device_id, schemas, max_row_num);
-
-  int64_t timestamp = 0;
-
-  if (cmd == 'a' || cmd == 'i') {
-    int64_t start_ms = get_ms();
-    for (int row = 0; row < total_row_count; row++) {
-      int64_t rowIndex = tablet.rowSize++;
-      tablet.timestamps[rowIndex] = timestamp;
-      for (int s = 0; s < measurement_num; s++) {
-        int64_t value = (row + 1) * 100 + s + 1;
-        tablet.addValue(s, rowIndex, &value);
-      }
-      if (tablet.rowSize >= max_row_num) {
-        session->insertTablet(tablet, /* sorted = */ true);
-        tablet.reset();
-      }
-      timestamp++;
-    }
-    if (tablet.rowSize > 0) {
-      session->insertTablet(tablet, /* sorted = */ true);
-      tablet.reset();
-    }
-    int64_t end_ms = get_ms();
-    printf("== PERF == insert %lld rows done, time spent = %lld ms.\n", total_row_count, end_ms - start_ms);
-  }
-
-  char buf[256];
-  size_t buf_sz = 256;
-  if (cmd == 'a' || cmd == 's') {
-    snprintf(buf, buf_sz, "select * from %s ;", device_id);
-    std::unique_ptr<SessionDataSet> res = session->executeQueryStatement(buf);
-    printf("execute %s done, res ptr=%p\n", buf, res.get());
-    while (res->hasNext()) {
-      std::cout << "--- RES: " << res->next()->toString() << std::endl;
-    }
-  }
-
-  if (cmd == 'a' || cmd == 'c') {
-    snprintf(buf, buf_sz, "select count(*) from %s ;", device_id);
-    int64_t start_ms = get_ms();
-    std::unique_ptr<SessionDataSet> res = session->executeQueryStatement(buf);
-    int64_t end_ms = get_ms();
-    printf("== PERF == execute %s done, time spent = %lld\n", buf, end_ms - start_ms);
-    while (res->hasNext()) {
-      std::cout << "--- RES: " << res->next()->toString() << std::endl;
-    }
-  }
-
-  session->close();
-}
-
diff --git a/client-cpp/pom.xml b/client-cpp/pom.xml
index 460f414ea7..2bb64eb3e3 100644
--- a/client-cpp/pom.xml
+++ b/client-cpp/pom.xml
@@ -41,6 +41,9 @@
         <cmake.build.type>Release</cmake.build.type>
         <catch2.url>https://github.com/catchorg/Catch2/releases/download/v2.13.0/catch.hpp</catch2.url>
     </properties>
+    <modules>
+        <module>../example/client-cpp-example</module>
+    </modules>
     <dependencies>
         <dependency>
             <groupId>org.apache.iotdb</groupId>
@@ -122,6 +125,199 @@
                 <boost.library.dir/>
             </properties>
         </profile>
+        <profile>
+            <id>compile-cpp</id>
+            <build>
+                <plugins>
+                    <!-- Build and do session integration test -->
+                    <plugin>
+                        <artifactId>maven-resources-plugin</artifactId>
+                        <version>2.6</version>
+                        <executions>
+                            <execution>
+                                <id>copy-test-resources</id>
+                                <phase>validate</phase>
+                                <goals>
+                                    <goal>copy-resources</goal>
+                                </goals>
+                                <configuration>
+                                    <outputDirectory>${project.build.directory}/build/test</outputDirectory>
+                                    <resources>
+                                        <resource>
+                                            <directory>${project.basedir}/src/test</directory>
+                                            <filtering>true</filtering>
+                                        </resource>
+                                    </resources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>com.coderplus.maven.plugins</groupId>
+                        <artifactId>copy-rename-maven-plugin</artifactId>
+                        <version>1.0.1</version>
+                        <executions>
+                            <execution>
+                                <id>copy-thrift-source</id>
+                                <goals>
+                                    <goal>copy</goal>
+                                </goals>
+                                <configuration>
+                                    <fileSets>
+                                        <fileSet>
+                                            <sourceFile>../thrift/src/main/thrift/client.thrift</sourceFile>
+                                            <destinationFile>${project.build.directory}/thrift/client.thrift</destinationFile>
+                                        </fileSet>
+                                        <fileSet>
+                                            <sourceFile>../thrift-commons/src/main/thrift/common.thrift</sourceFile>
+                                            <destinationFile>${project.build.directory}/thrift/common.thrift</destinationFile>
+                                        </fileSet>
+                                    </fileSets>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <!-- Copy source file and CmakeLists.txt into target directory -->
+                                <id>copy-cmakelist-file</id>
+                                <phase>compile</phase>
+                                <goals>
+                                    <goal>copy</goal>
+                                </goals>
+                                <configuration>
+                                    <fileSets>
+                                        <fileSet>
+                                            <sourceFile>${project.basedir}/src/main/CMakeLists.txt</sourceFile>
+                                            <destinationFile>${project.build.directory}/build/main/CMakeLists.txt</destinationFile>
+                                        </fileSet>
+                                        <fileSet>
+                                            <sourceFile>${project.basedir}/src/main/Session.h</sourceFile>
+                                            <destinationFile>${project.build.directory}/build/main/generated-sources-cpp/Session.h</destinationFile>
+                                        </fileSet>
+                                        <fileSet>
+                                            <sourceFile>${project.basedir}/src/main/Session.cpp</sourceFile>
+                                            <destinationFile>${project.build.directory}/build/main/generated-sources-cpp/Session.cpp</destinationFile>
+                                        </fileSet>
+                                    </fileSets>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.thrift.tools</groupId>
+                        <artifactId>maven-thrift-plugin</artifactId>
+                        <version>0.1.11</version>
+                        <executions>
+                            <execution>
+                                <id>generate-thrift-sources-cpp</id>
+                                <!-- Move from generate-sources to generate-resources to avoid double executions -->
+                                <phase>generate-resources</phase>
+                                <goals>
+                                    <goal>compile</goal>
+                                </goals>
+                                <configuration>
+                                    <generator>cpp:no_skeleton</generator>
+                                    <thriftExecutable>${thrift.exec.absolute.path}</thriftExecutable>
+                                    <thriftSourceRoot>${project.build.directory}/thrift</thriftSourceRoot>
+                                    <outputDirectory>${project.build.directory}/build/main/generated-sources-cpp</outputDirectory>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>com.googlecode.cmake-maven-project</groupId>
+                        <artifactId>cmake-maven-plugin</artifactId>
+                        <version>3.7.2-b1</version>
+                        <executions>
+                            <!-- Uses a CMake generator to generate the build using the build tool of choice -->
+                            <execution>
+                                <id>cmake-generate</id>
+                                <phase>compile</phase>
+                                <goals>
+                                    <goal>generate</goal>
+                                </goals>
+                                <configuration>
+                                    <classifier>${os.classifier}</classifier>
+                                    <!--
+                                      We need to use a newer version of cmake, so disable downloading. If we do not
+                                      set this to false, a cmake of version 3.7.2 will be downloaded.
+                                    -->
+                                    <downloadBinaries>false</downloadBinaries>
+                                    <sourcePath>${project.build.directory}/build/main</sourcePath>
+                                    <!--
+                                      Path to where the build configuration is generated
+                                      (This directory is then used in the compile step to actually perform the build)
+                                    -->
+                                    <targetPath>${project.build.directory}/build/main</targetPath>
+                                    <generator>${cmake.generator}</generator>
+                                    <options>
+                                        <option>-DBOOST_INCLUDEDIR=${boost.include.dir}</option>
+                                        <option>-DBOOST_LIBRARYDIR=${boost.library.dir}</option>
+                                    </options>
+                                </configuration>
+                            </execution>
+                            <!-- Actually executes the build -->
+                            <execution>
+                                <id>cmake-compile</id>
+                                <phase>compile</phase>
+                                <goals>
+                                    <goal>compile</goal>
+                                </goals>
+                                <configuration>
+                                    <classifier>${os.classifier}</classifier>
+                                    <config>${cmake.build.type}</config>
+                                    <!--
+                                      We need to use a newer version of cmake, so disable downloading
+                                      and tell the plugin where to find that version.
+                                    -->
+                                    <downloadBinaries>false</downloadBinaries>
+                                    <!-- The directory where the "generate" step generated the build configuration -->
+                                    <projectDirectory>${project.build.directory}/build/main</projectDirectory>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <!--Package all C++ header files and client library-->
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>package-client-cpp</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <finalName>${project.artifactId}-${project.version}</finalName>
+                                    <descriptors>
+                                        <descriptor>src/assembly/client-cpp.xml</descriptor>
+                                    </descriptors>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>com.googlecode.maven-download-plugin</groupId>
+                        <artifactId>download-maven-plugin</artifactId>
+                        <version>1.6.7</version>
+                        <executions>
+                            <!-- Download the Catch2 header file. -->
+                            <execution>
+                                <id>get-catch2</id>
+                                <phase>generate-resources</phase>
+                                <goals>
+                                    <goal>wget</goal>
+                                </goals>
+                                <configuration>
+                                    <url>${catch2.url}</url>
+                                    <unpack>false</unpack>
+                                    <outputDirectory>${project.build.directory}/build/test/catch2</outputDirectory>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
         <profile>
             <id>cppTest</id>
             <build>
diff --git a/client-cpp/src/main/Session.cpp b/client-cpp/src/main/Session.cpp
index 253c18039f..54840a1b69 100644
--- a/client-cpp/src/main/Session.cpp
+++ b/client-cpp/src/main/Session.cpp
@@ -42,8 +42,7 @@ void RpcUtils::verifySuccess(const TSStatus &status) {
         verifySuccess(status.subStatus);
         return;
     }
-    if (status.code != TSStatusCode::SUCCESS_STATUS
-        && status.code != TSStatusCode::REDIRECTION_RECOMMEND) {
+    if (status.code != TSStatusCode::SUCCESS_STATUS) {
         throw ExecutionException(to_string(status.code) + ": " + status.message);
     }
 }
@@ -1992,7 +1991,7 @@ bool Session::checkTemplateExists(const string& template_name) {
         return isExisted;
     }
     catch (const exception &e) {
-        if ( strstr(e.what(), "get template info error") != NULL ) {
+        if ( strstr(e.what(), "Undefined template name:") != NULL ) {
             return false;
         }
         log_debug(e.what());
diff --git a/client-cpp/src/main/Session.h b/client-cpp/src/main/Session.h
index 7ffa6fc3d3..9d9dc665f5 100644
--- a/client-cpp/src/main/Session.h
+++ b/client-cpp/src/main/Session.h
@@ -176,55 +176,60 @@ namespace TSEncoding {
 namespace TSStatusCode {
     enum TSStatusCode {
         SUCCESS_STATUS = 200,
-     
-        // System level
-        INCOMPATIBLE_VERSION = 201,
-        CONFIGURATION_ERROR = 202,
-        START_UP_ERROR = 203,
-        SHUT_DOWN_ERROR = 204,
-     
-        // General Error
-        UNSUPPORTED_OPERATION = 300,
-        EXECUTE_STATEMENT_ERROR = 301,
-        MULTIPLE_ERROR = 302,
-        ILLEGAL_PARAMETER = 303,
-        OVERLAP_WITH_EXISTING_TASK = 304,
-        INTERNAL_SERVER_ERROR = 305,
-     
-        // Client,
-        REDIRECTION_RECOMMEND = 400,
-     
-        // Schema Engine
-        DATABASE_NOT_EXIST = 500,
-        DATABASE_ALREADY_EXISTS = 501,
-        SERIES_OVERFLOW = 502,
-        TIMESERIES_ALREADY_EXIST = 503,
-        TIMESERIES_IN_BLACK_LIST = 504,
-        ALIAS_ALREADY_EXIST = 505,
-        PATH_ALREADY_EXIST = 506,
-        METADATA_ERROR = 507,
-        PATH_NOT_EXIST = 508,
-        ILLEGAL_PATH = 509,
-        CREATE_TEMPLATE_ERROR = 510,
-        DUPLICATED_TEMPLATE = 511,
-        UNDEFINED_TEMPLATE = 512,
-        TEMPLATE_NOT_SET = 513,
-        DIFFERENT_TEMPLATE = 514,
-        TEMPLATE_IS_IN_USE = 515,
-        TEMPLATE_INCOMPATIBLE = 516,
-        SEGMENT_NOT_FOUND = 517,
-        PAGE_OUT_OF_SPACE = 518,
-        RECORD_DUPLICATED=519,
-        SEGMENT_OUT_OF_SPACE = 520,
-        SCHEMA_FILE_NOT_EXISTS = 521,
-        OVERSIZE_RECORD = 522,
-        SCHEMA_FILE_REDO_LOG_BROKEN = 523,
-        TEMPLATE_NOT_ACTIVATED = 524,
-     
-        // Storage Engine
-        SYSTEM_READ_ONLY = 600,
-        STORAGE_ENGINE_ERROR = 601,
-        STORAGE_ENGINE_NOT_READY = 602,
+        STILL_EXECUTING_STATUS = 201,
+        INVALID_HANDLE_STATUS = 202,
+
+        NODE_DELETE_FAILED_ERROR = 298,
+        ALIAS_ALREADY_EXIST_ERROR = 299,
+        PATH_ALREADY_EXIST_ERROR = 300,
+        PATH_NOT_EXIST_ERROR = 301,
+        UNSUPPORTED_FETCH_METADATA_OPERATION_ERROR = 302,
+        METADATA_ERROR = 303,
+        OUT_OF_TTL_ERROR = 305,
+        CONFIG_ADJUSTER = 306,
+        MERGE_ERROR = 307,
+        SYSTEM_CHECK_ERROR = 308,
+        SYNC_DEVICE_OWNER_CONFLICT_ERROR = 309,
+        SYNC_CONNECTION_EXCEPTION = 310,
+        STORAGE_GROUP_PROCESSOR_ERROR = 311,
+        STORAGE_GROUP_ERROR = 312,
+        STORAGE_ENGINE_ERROR = 313,
+        TSFILE_PROCESSOR_ERROR = 314,
+        PATH_ILLEGAL = 315,
+        LOAD_FILE_ERROR = 316,
+        STORAGE_GROUP_NOT_READY = 317,
+
+        EXECUTE_STATEMENT_ERROR = 400,
+        SQL_PARSE_ERROR = 401,
+        GENERATE_TIME_ZONE_ERROR = 402,
+        SET_TIME_ZONE_ERROR = 403,
+        NOT_STORAGE_GROUP_ERROR = 404,
+        QUERY_NOT_ALLOWED = 405,
+        AST_FORMAT_ERROR = 406,
+        LOGICAL_OPERATOR_ERROR = 407,
+        LOGICAL_OPTIMIZE_ERROR = 408,
+        UNSUPPORTED_FILL_TYPE_ERROR = 409,
+        PATH_ERROR = 410,
+        QUERY_PROCESS_ERROR = 411,
+        WRITE_PROCESS_ERROR = 412,
+
+        INTERNAL_SERVER_ERROR = 500,
+        CLOSE_OPERATION_ERROR = 501,
+        READ_ONLY_SYSTEM_ERROR = 502,
+        DISK_SPACE_INSUFFICIENT_ERROR = 503,
+        START_UP_ERROR = 504,
+        SHUT_DOWN_ERROR = 505,
+        MULTIPLE_ERROR = 506,
+        WRONG_LOGIN_PASSWORD_ERROR = 600,
+        NOT_LOGIN_ERROR = 601,
+        NO_PERMISSION_ERROR = 602,
+        UNINITIALIZED_AUTH_ERROR = 603,
+        PARTITION_NOT_READY = 700,
+        TIME_OUT = 701,
+        NO_LEADER = 702,
+        UNSUPPORTED_OPERATION = 703,
+        NODE_READ_ONLY = 704,
+        INCOMPATIBLE_VERSION = 203,
     };
 }
 
@@ -289,18 +294,7 @@ public:
     }
 
     int64_t getInt64() {
-#ifdef ARCH32
-        const char *buf_addr = getOrderedByte(8);
-        if (reinterpret_cast<uint32_t>(buf_addr) % 4 == 0) {
-            return *(int64_t *)buf_addr;
-        } else {
-            char tmp_buf[8];
-            memcpy(tmp_buf, buf_addr, 8); 
-            return *(int64_t*)tmp_buf;
-        }
-#else
         return *(int64_t *) getOrderedByte(8);
-#endif
     }
 
     float getFloat() {
@@ -308,18 +302,7 @@ public:
     }
 
     double getDouble() {
-#ifdef ARCH32
-        const char *buf_addr = getOrderedByte(8);
-        if (reinterpret_cast<uint32_t>(buf_addr) % 4 == 0) {
-            return  *(double*)buf_addr;
-        } else {
-            char tmp_buf[8];
-            memcpy(tmp_buf, buf_addr, 8);
-            return *(double*)tmp_buf;
-        }
-#else
         return *(double *) getOrderedByte(8);
-#endif
     }
 
     char getChar() {
diff --git a/client-cpp/src/test/CMakeLists.txt b/client-cpp/src/test/CMakeLists.txt
index 7d6d18bcd5..c5c969a049 100644
--- a/client-cpp/src/test/CMakeLists.txt
+++ b/client-cpp/src/test/CMakeLists.txt
@@ -22,7 +22,6 @@ SET(CMAKE_CXX_STANDARD 11)
 SET(CMAKE_CXX_STANDARD_REQUIRED ON)
 SET(TARGET_NAME session_tests)
 SET(TOOLS_DIR "${CMAKE_SOURCE_DIR}/../../../../compile-tools")
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -g -O2")
 ENABLE_TESTING()
 
 # Add Boost include path for MacOS
diff --git a/client-cpp/src/test/compile_test.sh b/client-cpp/src/test/compile_test.sh
deleted file mode 100644
index 69a8f35c8e..0000000000
--- a/client-cpp/src/test/compile_test.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-CXX_FLAGS="-O2 -g -std=c++11 "
-IOTDB_SESSION_SDK=../../iotdb_cpp_client_sdk
-
-export LD_LIBRARY_PATH=${IOTDB_SESSION_SDK}/lib
-g++ $CXX_FLAGS -o test main.cpp cpp/sessionIT.cpp -liotdb_session -lthrift -L${IOTDB_SESSION_SDK}/lib -I${IOTDB_SESSION_SDK}/include
-
-./test
-
-
diff --git a/client-cpp/src/test/cpp/sessionIT.cpp b/client-cpp/src/test/cpp/sessionIT.cpp
index b3cd13e645..31f5daf0a9 100644
--- a/client-cpp/src/test/cpp/sessionIT.cpp
+++ b/client-cpp/src/test/cpp/sessionIT.cpp
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-#include <catch/catch.hpp>
+#include "catch.hpp"
 #include "Session.h"
 
 using namespace std;
@@ -35,26 +35,7 @@ void prepareTimeseries() {
     }
 }
 
-static int global_test_id = 0;
-class CaseReporter
-{
-public:
-    CaseReporter(const char *caseNameArg) : caseName(caseNameArg)
-    {
-        test_id = global_test_id++;
-        std::cout << "Test " << test_id << ": " << caseName << std::endl;
-    }
-    ~CaseReporter()
-    {
-        std::cout << "Test " << test_id << ": " << caseName << " Done"<< std::endl << std::endl;
-    }
-private:
-    const char *caseName;
-    int test_id;
-};
-
 TEST_CASE("Create timeseries success", "[createTimeseries]") {
-    CaseReporter cr("createTimeseries");
     if (!session->checkTimeseriesExists("root.test.d1.s1")) {
         session->createTimeseries("root.test.d1.s1", TSDataType::INT64, TSEncoding::RLE, CompressionType::SNAPPY);
     }
@@ -63,7 +44,6 @@ TEST_CASE("Create timeseries success", "[createTimeseries]") {
 }
 
 TEST_CASE("Delete timeseries success", "[deleteTimeseries]") {
-    CaseReporter cr("deleteTimeseries");
     if (!session->checkTimeseriesExists("root.test.d1.s1")) {
         session->createTimeseries("root.test.d1.s1", TSDataType::INT64, TSEncoding::RLE, CompressionType::SNAPPY);
     }
@@ -73,7 +53,6 @@ TEST_CASE("Delete timeseries success", "[deleteTimeseries]") {
 }
 
 TEST_CASE("Test insertRecord by string", "[testInsertRecord]") {
-    CaseReporter cr("testInsertRecord");
     prepareTimeseries();
     string deviceId = "root.test.d1";
     vector<string> measurements = {"s1", "s2", "s3"};
@@ -85,7 +64,7 @@ TEST_CASE("Test insertRecord by string", "[testInsertRecord]") {
 
     session->executeNonQueryStatement("insert into root.test.d1(timestamp,s1, s2, s3) values(100, 1,2,3)");
 
-    unique_ptr<SessionDataSet> sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d1");
+    unique_ptr<SessionDataSet> sessionDataSet = session->executeQueryStatement("select * from root.test.d1");
     sessionDataSet->setBatchSize(1024);
     int count = 0;
     while (sessionDataSet->hasNext()) {
@@ -100,7 +79,6 @@ TEST_CASE("Test insertRecord by string", "[testInsertRecord]") {
 }
 
 TEST_CASE("Test insertRecords ", "[testInsertRecords]") {
-    CaseReporter cr("testInsertRecords");
     prepareTimeseries();
     string deviceId = "root.test.d1";
     vector<string> measurements = {"s1", "s2", "s3"};
@@ -109,8 +87,7 @@ TEST_CASE("Test insertRecords ", "[testInsertRecords]") {
     vector<vector<string>> valuesList;
     vector<int64_t> timestamps;
 
-    int64_t COUNT = 500;
-    for (int64_t time = 1; time <= COUNT; time++) {
+    for (int64_t time = 0; time < 500; time++) {
         vector<string> values = {"1", "2", "3"};
 
         deviceIds.push_back(deviceId);
@@ -126,11 +103,9 @@ TEST_CASE("Test insertRecords ", "[testInsertRecords]") {
         }
     }
 
-    if (timestamps.size() > 0) {
-        session->insertRecords(deviceIds, timestamps, measurementsList, valuesList);
-    }
+    session->insertRecords(deviceIds, timestamps, measurementsList, valuesList);
 
-    unique_ptr<SessionDataSet> sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d1");
+    unique_ptr<SessionDataSet> sessionDataSet = session->executeQueryStatement("select * from root.test.d1");
     sessionDataSet->setBatchSize(1024);
     int count = 0;
     while (sessionDataSet->hasNext()) {
@@ -141,11 +116,10 @@ TEST_CASE("Test insertRecords ", "[testInsertRecords]") {
             index++;
         }
     }
-    REQUIRE(count == COUNT);
+    REQUIRE(count == 500);
 }
 
 TEST_CASE("Test insertRecord with types ", "[testTypedInsertRecord]") {
-    CaseReporter cr("testTypedInsertRecord");
     vector<string> timeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3"};
     vector<TSDataType::TSDataType> types = {TSDataType::INT32, TSDataType::DOUBLE, TSDataType::INT64};
 
@@ -177,7 +151,6 @@ TEST_CASE("Test insertRecord with types ", "[testTypedInsertRecord]") {
 }
 
 TEST_CASE("Test insertRecords with types ", "[testTypedInsertRecords]") {
-    CaseReporter cr("testTypedInsertRecords");
     vector<string> timeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3"};
     vector<TSDataType::TSDataType> types = {TSDataType::INT32, TSDataType::DOUBLE, TSDataType::INT64};
 
@@ -209,7 +182,7 @@ TEST_CASE("Test insertRecords with types ", "[testTypedInsertRecords]") {
 
     session->insertRecords(deviceIds, timestamps, measurementsList, typesList, valuesList);
 
-    unique_ptr<SessionDataSet> sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d1");
+    unique_ptr<SessionDataSet> sessionDataSet = session->executeQueryStatement("select * from root.test.d1");
     sessionDataSet->setBatchSize(1024);
     int count = 0;
     while (sessionDataSet->hasNext()) {
@@ -220,7 +193,6 @@ TEST_CASE("Test insertRecords with types ", "[testTypedInsertRecords]") {
 }
 
 TEST_CASE("Test insertRecordsOfOneDevice", "[testInsertRecordsOfOneDevice]") {
-    CaseReporter cr("testInsertRecordsOfOneDevice");
     vector<string> timeseries = {"root.test.d1.s1", "root.test.d1.s2", "root.test.d1.s3"};
     vector<TSDataType::TSDataType> types = {TSDataType::INT32, TSDataType::DOUBLE, TSDataType::INT64};
 
@@ -261,7 +233,6 @@ TEST_CASE("Test insertRecordsOfOneDevice", "[testInsertRecordsOfOneDevice]") {
 }
 
 TEST_CASE("Test insertTablet ", "[testInsertTablet]") {
-    CaseReporter cr("testInsertTablet");
     prepareTimeseries();
     string deviceId = "root.test.d1";
     vector<pair<string, TSDataType::TSDataType>> schemaList;
@@ -273,8 +244,9 @@ TEST_CASE("Test insertTablet ", "[testInsertTablet]") {
     for (int64_t time = 0; time < 100; time++) {
         int row = tablet.rowSize++;
         tablet.timestamps[row] = time;
-        for (int64_t i = 0; i < 3; i++) {
-            tablet.addValue(i, row, &i);
+        for (int i = 0; i < 3; i++) {
+            int64_t randVal = rand();
+            tablet.addValue(i, row, &randVal);
         }
         if (tablet.rowSize == tablet.maxRowNumber) {
             session->insertTablet(tablet);
@@ -286,7 +258,7 @@ TEST_CASE("Test insertTablet ", "[testInsertTablet]") {
         session->insertTablet(tablet);
         tablet.reset();
     }
-    unique_ptr<SessionDataSet> sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d1");
+    unique_ptr<SessionDataSet> sessionDataSet = session->executeQueryStatement("select * from root.test.d1");
     sessionDataSet->setBatchSize(1024);
     int count = 0;
     while (sessionDataSet->hasNext()) {
@@ -301,7 +273,6 @@ TEST_CASE("Test insertTablet ", "[testInsertTablet]") {
 }
 
 TEST_CASE("Test Last query ", "[testLastQuery]") {
-    CaseReporter cr("testLastQuery");
     prepareTimeseries();
     string deviceId = "root.test.d1";
     vector<string> measurements = {"s1", "s2", "s3"};
@@ -318,55 +289,36 @@ TEST_CASE("Test Last query ", "[testLastQuery]") {
     long index = 0;
     while (sessionDataSet->hasNext()) {
         vector<Field> fields = sessionDataSet->next()->fields;
-        REQUIRE("1" <= fields[1].stringV);
-        REQUIRE(fields[1].stringV <= "3");
+        REQUIRE(fields[0].stringV == deviceId + "." + measurements[index]);
+        REQUIRE(fields[1].stringV == measurementValues[index]);
         index++;
     }
 }
 
 TEST_CASE("Test Huge query ", "[testHugeQuery]") {
-    CaseReporter cr("testHugeQuery");
     prepareTimeseries();
     string deviceId = "root.test.d1";
     vector<string> measurements = {"s1", "s2", "s3"};
-    vector<TSDataType::TSDataType> types = {TSDataType::INT64, TSDataType::INT64, TSDataType::INT64};
-    int64_t value1 = 1, value2 = 2, value3 = 3;
+    vector<TSDataType::TSDataType> types = {TSDataType::INT32, TSDataType::INT32, TSDataType::INT32};
+    int value1 = 1, value2 = 2, value3 = 3;
     vector<char*> values = {(char*)&value1, (char*)&value2, (char*)&value3};
 
-    long total_count = 500000;
-    int print_count = 0;
-    std::cout.width(7);
-    std::cout << "inserting " << total_count << " rows:" << std::endl;
-    for (long time = 0; time < total_count; time++) {
+    for (long time = 0; time < 1000000; time++) {
         session->insertRecord(deviceId, time, measurements, types, values);
-        if (time != 0 && time % 1000 == 0) {
-            std::cout << time << "\t" << std::flush;
-            if (++print_count % 20 == 0) {
-                std::cout << std::endl;
-            }
-        }
     }
 	
-    unique_ptr<SessionDataSet> sessionDataSet = session->executeQueryStatement("select s1,s2,s3 from root.test.d1");
+    unique_ptr<SessionDataSet> sessionDataSet = session->executeQueryStatement("select * from root.test.d1");
     sessionDataSet->setBatchSize(1024);
     RowRecord* rowRecord;
     int count = 0;
-    print_count = 0;
-    std::cout << "\n\niterating " << total_count << " rows:" << std::endl;
     while (sessionDataSet->hasNext()) {
         rowRecord = sessionDataSet->next();
         REQUIRE(rowRecord->timestamp == count);
-        REQUIRE(rowRecord->fields[0].longV== 1);
-        REQUIRE(rowRecord->fields[1].longV == 2);
-        REQUIRE(rowRecord->fields[2].longV == 3);
+        REQUIRE(rowRecord->fields[0].intV == 1);
+        REQUIRE(rowRecord->fields[1].intV == 2);
+        REQUIRE(rowRecord->fields[2].intV == 3);
         count++;
-        if (count % 1000 == 0) {
-            std::cout << count << "\t" << std::flush;
-            if (++print_count % 20 == 0) {
-                std::cout << std::endl;
-            }
-        }
     }
 	
-    REQUIRE(count == total_count);
+    REQUIRE(count == 1000000);
 }
diff --git a/client-cpp/src/test/main.cpp b/client-cpp/src/test/main.cpp
index 8e19e7f5c4..9476343384 100644
--- a/client-cpp/src/test/main.cpp
+++ b/client-cpp/src/test/main.cpp
@@ -19,7 +19,7 @@
 
 #define CATCH_CONFIG_MAIN
 
-#include <catch/catch.hpp>
+#include <catch.hpp>
 #include "Session.h"
 
 Session *session = new Session("127.0.0.1", 6667, "root", "root");
@@ -39,4 +39,4 @@ struct SessionListener : Catch::TestEventListenerBase {
     }
 };
 
-CATCH_REGISTER_LISTENER( SessionListener )
+CATCH_REGISTER_LISTENER( SessionListener )
\ No newline at end of file
diff --git a/example/client-cpp-example/README.md b/example/client-cpp-example/README.md
new file mode 100644
index 0000000000..38d392633a
--- /dev/null
+++ b/example/client-cpp-example/README.md
@@ -0,0 +1,48 @@
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+
+# How to get a complete CPP client demo project
+
+## get a project
+
+using maven to build this example project:
+
+* cd the root path of the whole project
+* run `mvn package -DskipTests -P compile-cpp -pl example/client-cpp-example -am`
+* cd example/client-cpp-example/target
+
+You can find some files to form a complete project:
+```
++-- client
+|   +-- include
+|       +-- Session.h
+|       +-- IClientRPCService.h
+|       +-- rpc_types.h
+|       +-- rpc_constants.h
+|       +-- thrift
+|           +-- thrift_headers...
+|   +-- lib
+|       +-- libiotdb_session.dylib
++-- CMakeLists.txt
++-- SessionExample.cpp
+```
+
+
diff --git a/example/client-cpp-example/pom.xml b/example/client-cpp-example/pom.xml
new file mode 100644
index 0000000000..a55d9779d2
--- /dev/null
+++ b/example/client-cpp-example/pom.xml
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.iotdb</groupId>
+        <artifactId>iotdb-examples</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>client-cpp-example</artifactId>
+    <name>IoTDB-Client CPP Examples</name>
+    <properties>
+        <cmake-version>3.17.3</cmake-version>
+        <cmake.build.type>Release</cmake.build.type>
+    </properties>
+    <profiles>
+        <profile>
+            <id>os-unix</id>
+            <activation>
+                <os>
+                    <family>unix</family>
+                </os>
+            </activation>
+            <properties>
+                <cmake.generator>Unix Makefiles</cmake.generator>
+                <cmake.root.dir>${project.parent.basedir}/../compile-tools/thrift/target/cmake-${cmake-version}-Linux-x86_64/</cmake.root.dir>
+            </properties>
+        </profile>
+        <profile>
+            <id>os-unix-arm</id>
+            <activation>
+                <os>
+                    <family>unix</family>
+                    <arch>aarch64</arch>
+                </os>
+            </activation>
+            <properties>
+                <os.suffix>linux</os.suffix>
+                <os.classifier>linux-arm_32</os.classifier>
+                <cmake.generator>Unix Makefiles</cmake.generator>
+                <cmake.root.dir>${project.parent.basedir}/../compile-tools/thrift/target/cmake-3.21.2-linux-aarch64/</cmake.root.dir>
+            </properties>
+        </profile>
+        <profile>
+            <id>os-mac</id>
+            <activation>
+                <os>
+                    <family>mac</family>
+                </os>
+            </activation>
+            <properties>
+                <cmake.generator>Unix Makefiles</cmake.generator>
+                <cmake.root.dir>${project.parent.basedir}/../compile-tools/thrift/target/cmake-${cmake-version}-Darwin-x86_64/CMake.app/Contents</cmake.root.dir>
+                <boost.include.dir>/usr/local/include</boost.include.dir>
+            </properties>
+        </profile>
+        <profile>
+            <id>os-windows</id>
+            <activation>
+                <os>
+                    <family>windows</family>
+                </os>
+            </activation>
+            <properties>
+                <cmake.generator>Visual Studio 16 2019</cmake.generator>
+                <cmake.root.dir>${project.parent.basedir}/../compile-tools/thrift/target/cmake-${cmake-version}-win64-x64/</cmake.root.dir>
+                <boost.include.dir/>
+            </properties>
+        </profile>
+        <profile>
+            <id>compile-cpp</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>com.coderplus.maven.plugins</groupId>
+                        <artifactId>copy-rename-maven-plugin</artifactId>
+                        <version>1.0.1</version>
+                        <executions>
+                            <execution>
+                                <id>copy-thrift-source</id>
+                                <goals>
+                                    <goal>copy</goal>
+                                </goals>
+                                <configuration>
+                                    <fileSets>
+                                        <fileSet>
+                                            <sourceFile>${project.basedir}/src/SessionExample.cpp</sourceFile>
+                                            <destinationFile>${project.build.directory}/SessionExample.cpp</destinationFile>
+                                        </fileSet>
+                                        <fileSet>
+                                            <sourceFile>${project.basedir}/src/AlignedTimeseriesSessionExample.cpp</sourceFile>
+                                            <destinationFile>${project.build.directory}/AlignedTimeseriesSessionExample.cpp</destinationFile>
+                                        </fileSet>
+                                        <fileSet>
+                                            <sourceFile>${project.basedir}/src/CMakeLists.txt</sourceFile>
+                                            <destinationFile>${project.build.directory}/CMakeLists.txt</destinationFile>
+                                        </fileSet>
+                                    </fileSets>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-dependency-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>unpack-client</id>
+                                <goals>
+                                    <goal>unpack</goal>
+                                </goals>
+                                <configuration>
+                                    <artifactItems>
+                                        <artifactItem>
+                                            <groupId>org.apache.iotdb</groupId>
+                                            <artifactId>client-cpp</artifactId>
+                                            <version>${project.version}</version>
+                                            <type>zip</type>
+                                            <classifier>cpp-${os.classifier}</classifier>
+                                            <overWrite>true</overWrite>
+                                        </artifactItem>
+                                    </artifactItems>
+                                    <outputDirectory>${project.build.directory}/client</outputDirectory>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>com.googlecode.cmake-maven-project</groupId>
+                        <artifactId>cmake-maven-plugin</artifactId>
+                        <version>3.7.2-b1</version>
+                        <executions>
+                            <execution>
+                                <id>cmake-generate</id>
+                                <phase>compile</phase>
+                                <goals>
+                                    <goal>generate</goal>
+                                </goals>
+                                <configuration>
+                                    <classifier>${os.classifier}</classifier>
+                                    <downloadBinaries>false</downloadBinaries>
+                                    <sourcePath>${project.build.directory}</sourcePath>
+                                    <targetPath>${project.build.directory}</targetPath>
+                                    <generator>${cmake.generator}</generator>
+                                    <options>
+                                        <option>-DBOOST_INCLUDEDIR=${boost.include.dir}</option>
+                                    </options>
+                                </configuration>
+                            </execution>
+                            <execution>
+                                <id>cmake-compile</id>
+                                <phase>compile</phase>
+                                <goals>
+                                    <goal>compile</goal>
+                                </goals>
+                                <configuration>
+                                    <classifier>${os.classifier}</classifier>
+                                    <config>${cmake.build.type}</config>
+                                    <downloadBinaries>false</downloadBinaries>
+                                    <!-- The directory where the "generate" step generated the build configuration -->
+                                    <projectDirectory>${project.build.directory}</projectDirectory>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.iotdb</groupId>
+            <artifactId>client-cpp</artifactId>
+            <version>${project.version}</version>
+            <type>pom</type>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/client-cpp/cpp_demo/AlignedTimeseriesSessionExample.cpp b/example/client-cpp-example/src/AlignedTimeseriesSessionExample.cpp
similarity index 100%
rename from client-cpp/cpp_demo/AlignedTimeseriesSessionExample.cpp
rename to example/client-cpp-example/src/AlignedTimeseriesSessionExample.cpp
diff --git a/example/client-cpp-example/src/CMakeLists.txt b/example/client-cpp-example/src/CMakeLists.txt
new file mode 100644
index 0000000000..ad863bbff6
--- /dev/null
+++ b/example/client-cpp-example/src/CMakeLists.txt
@@ -0,0 +1,47 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+PROJECT(SessionExample)
+CMAKE_MINIMUM_REQUIRED(VERSION 3.7)
+
+SET(CMAKE_CXX_STANDARD 11)
+SET(CMAKE_CXX_STANDARD_REQUIRED ON)
+SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../target/client/include)
+
+FIND_PACKAGE(Boost REQUIRED)
+IF (DEFINED BOOST_INCLUDEDIR)
+    INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
+ENDIF()
+
+IF(MSVC)
+    LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/../target/client/lib/Release)
+ENDIF()
+LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/../target/client/lib)
+
+ADD_EXECUTABLE(SessionExample SessionExample.cpp)
+ADD_EXECUTABLE(AlignedTimeseriesSessionExample AlignedTimeseriesSessionExample.cpp)
+
+IF(MSVC)
+    TARGET_LINK_LIBRARIES(SessionExample iotdb_session thriftmd)
+    TARGET_LINK_LIBRARIES(AlignedTimeseriesSessionExample iotdb_session thriftmd)
+ELSE()
+    TARGET_LINK_LIBRARIES(SessionExample iotdb_session pthread)
+    TARGET_LINK_LIBRARIES(AlignedTimeseriesSessionExample iotdb_session pthread)
+ENDIF()
diff --git a/client-cpp/cpp_demo/SessionExample.cpp b/example/client-cpp-example/src/SessionExample.cpp
similarity index 95%
rename from client-cpp/cpp_demo/SessionExample.cpp
rename to example/client-cpp-example/src/SessionExample.cpp
index 27f7317dd2..e7a3c46b2b 100644
--- a/client-cpp/cpp_demo/SessionExample.cpp
+++ b/example/client-cpp-example/src/SessionExample.cpp
@@ -104,7 +104,6 @@ void createSchemaTemplate() {
         temp.addToTemplate(mNodeS2);
 
         session->createSchemaTemplate(temp);
-        session->setStorageGroup("root.sg3.d1");
         session->setSchemaTemplate("template1", "root.sg3.d1");
     }
 }
@@ -316,7 +315,7 @@ void nonQuery() {
 }
 
 void query() {
-    unique_ptr<SessionDataSet> dataSet = session->executeQueryStatement("select s1, s2, s3 from root.** limit 50");
+    unique_ptr<SessionDataSet> dataSet = session->executeQueryStatement("select s1, s2, s3 from root.**");
     cout << "timestamp" << "  ";
     for (const string &name: dataSet->getColumnNames()) {
         cout << name << "  ";
@@ -324,7 +323,6 @@ void query() {
     cout << endl;
 
     dataSet->setBatchSize(1024);
-    int count = 0;
     while (dataSet->hasNext()) {
         cout << dataSet->next()->toString();
     }
@@ -383,17 +381,6 @@ int main() {
     session->open(false);
 
     cout << "setStorageGroup: root.sg1\n" << endl;
-    // delete if exists
-    try {
-        session->deleteStorageGroup("root.sg1");
-    }
-    catch (IoTDBException &e) {
-        // may not exists
-        string errorMessage(e.what());
-        if (errorMessage.find("does not exist") == string::npos) {
-            throw e;
-        }
-    }
     try {
         session->setStorageGroup("root.sg1");
     }
@@ -406,17 +393,6 @@ int main() {
     }
 
     cout << "setStorageGroup: root.sg2\n" << endl;
-    // delete if exists
-    try {
-        session->deleteStorageGroup("root.sg2");
-    }
-    catch (IoTDBException &e) {
-        // may not exists
-        string errorMessage(e.what());
-        if (errorMessage.find("does not exist") == string::npos) {
-            throw e;
-        }
-    }
     try {
         session->setStorageGroup("root.sg2");
     }