# C Native API

1. Overview

The C Native API (SessionC) is a C language wrapper for the C++ Session SDK. It is used in the same way as the C++ driver. You only need to include the additional header file SessionC.h. Compilation, linking, and runtime deployment share the same iotdb_session shared library as the C++ driver.

Thrift and Boost are already packaged into iotdb_session. Applications do not need to install Thrift or Boost headers/libraries separately.

Note: This feature is supported since V2.0.10.

2. Installation

2.1 Option 1: Use the precompiled SDK package (recommended)

CI publishes zip packages by platform/toolchain. The file name is in the form iotdb-session-cpp-<version>-<classifier>.zip. After extraction, the directory structure is as follows:

iotdb-session-cpp-<version>-<classifier>/
├── include/
   ├── SessionC.h          # C Native API header file
   ├── Session.h           # C++ API header file
   └── ...
├── lib/
   ├── libiotdb_session.so       # Linux
   ├── libiotdb_session.dylib      # macOS
   └── iotdb_session.dll + .lib    # Windows
├── cmake/iotdb-session-config.cmake
├── pkgconfig/iotdb-session.pc
└── examples/                       # Includes tree_example.c

Select the classifier according to the target environment:

Target environmentclassifier suffix
Linux x86_64, glibc >= 2.28linux-x86_64-glibc2.28
Linux aarch64, glibc >= 2.28linux-aarch64-glibc2.28
macOS x86_64macos-x86_64
macOS arm64macos-aarch64
Windows + Visual Studio 2017windows-x86_64-msvc14.1
Windows + Visual Studio 2019windows-x86_64-msvc14.2
Windows + Visual Studio 2022windows-x86_64-msvc14.3
Windows + Visual Studio 2026windows-x86_64-msvc14.4

Note: Do not use a higher-version client to connect to a lower-version server.

2.1.1 C program compilation example

Linux / macOS:

gcc -std=c11 tree_example.c \
  -I"$IOTDB_SESSION_HOME/include" \
  -L"$IOTDB_SESSION_HOME/lib" \
  -liotdb_session -pthread \
  -Wl,-rpath,"$IOTDB_SESSION_HOME/lib" \
  -o tree_example

Windows + MSVC:

Compile in the x64 Native Tools Command Prompt (or run vcvars64.bat first to initialize the environment):

set IOTDB_SESSION_HOME=C:\path\to\iotdb-session-cpp-<version>-<classifier>
cd /d %IOTDB_SESSION_HOME%\examples
cl /TC /std:c11 tree_example.c /I "%IOTDB_SESSION_HOME%\include" ^
  /link /LIBPATH:"%IOTDB_SESSION_HOME%\lib" iotdb_session.lib
copy /Y "%IOTDB_SESSION_HOME%\lib\iotdb_session.dll" .

At runtime, place libiotdb_session.so / .dylib / .dll in the same directory as the executable, or configure the corresponding dynamic library search path for your platform.

2.1.2 Compile examples in the SDK package

Run the following commands in the root directory of the extracted SDK package. The examples/ directory must be at the same level as include/ and lib/.

cd iotdb-session-cpp-<version>-<classifier>
cmake -S examples -B examples-build -DCMAKE_BUILD_TYPE=Release
cmake --build examples-build

Windows + Visual Studio:

cd iotdb-session-cpp-<version>-<classifier>
cmake -S examples -B examples-build -G "Visual Studio 17 2022" -A x64
cmake --build examples-build --config Release

If the library is installed in another path, such as the source CMake installation directory iotdb-client/client-cpp/target/install, explicitly specify IOTDB_SDK_ROOT. This directory must contain include/ and lib/.

cmake -S iotdb-client/client-cpp/examples -B examples-build -DCMAKE_BUILD_TYPE=Release \
  -DIOTDB_SDK_ROOT=iotdb-client/client-cpp/target/install
cmake --build examples-build

Windows example:

cmake -S iotdb-client\client-cpp\examples -B examples-build -G "Visual Studio 17 2022" -A x64 ^
  -DIOTDB_SDK_ROOT=D:\iotdb\iotdb-client\client-cpp\target\install
cmake --build examples-build --config Release --target tree_example

2.2 Option 2: Build from source

2.2.1 Install build dependencies (required only for source builds)

  • macOS
brew install bison boost openssl
  • Ubuntu 16.04+ or other Debian distributions
sudo apt-get update
sudo apt-get install gcc g++ bison flex libboost-all-dev libssl-dev cmake
  • CentOS 7.7+/Fedora/Rocky Linux or other Red Hat distributions
sudo yum update
sudo yum install gcc gcc-c++ boost-devel bison flex openssl-devel cmake
  • Windows
  1. Install MS Visual Studio (2019+ recommended), and select the C/C++ IDE and compiler components with CMake support.

  2. Install CMake.

  3. Install Win_Flex_Bison, rename the executables to flex.exe and bison.exe, and add them to PATH.

  4. Install Boost (optional, CMake can also fetch it automatically) and OpenSSL.

    The CMake build compiles Thrift 0.23 from source. SSL is enabled by default. If system OpenSSL cannot be found, the build falls back to building OpenSSL from source.

2.2.2 Build

Clone the source code from git:

git clone https://github.com/apache/iotdb.git
cd iotdb

To use a specific release version, switch to the corresponding branch, such as 2.0.6:

git checkout rc/2.0.6

Run the Maven build in the IoTDB root directory (recommended):

# Linux / macOS: build and package the SDK
./mvnw -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests package

# Windows (Visual Studio 2022 example)
.\mvnw.cmd -P with-cpp -pl iotdb-client/client-cpp -am -DskipTests package

If Boost is not added to PATH on Windows, append a parameter such as:

-Dboost.include.dir="C:\boost_1_88_0"

You can also use CMake directly:

cmake -S iotdb-client/client-cpp -B build
cmake --build build --target install

Linux release packages are built in the manylinux_2_28 container. The target machine requires glibc 2.28 or later. The current build no longer uses old parameters such as -Diotdb-tools-thrift.version=0.14.1.1-gcc4-SNAPSHOT.

Full verification with integration tests:

./mvnw clean verify -P with-cpp -pl iotdb-client/client-cpp -am

2.3 Build artifacts

After a successful build, C API related files are located as follows:

  • C API header file (source): iotdb-client/client-cpp/src/include/SessionC.h

  • C API header file (installation/SDK package): include/SessionC.h

  • Library files:

    • Source build: iotdb-client/client-cpp/target/install/lib/

    • Maven package: iotdb-client/client-cpp/target/iotdb-session-cpp-<version>-<classifier>.zip

    • Linux: lib/libiotdb_session.so

    • Windows: lib/iotdb_session.dll / lib/iotdb_session.lib

  • Example source code:

    • Tree model: iotdb-client/client-cpp/examples/tree_example.c

    • Table model: iotdb-client/client-cpp/examples/table_example.c

  • Integration tests:

    • Tree model: iotdb-client/client-cpp/test/cpp/sessionCIT.cpp

    • Table model: iotdb-client/client-cpp/test/cpp/sessionCRelationalIT.cpp

3. Basic API description

Description: The C driver is used in the same way as the C++ driver. You only need to include the additional header file SessionC.h. Compilation, runtime behavior, and system dependencies are shared with the C++ driver.

3.1 Common conventions

3.1.1 Status codes and error messages

  • TsStatus: TS_OK (0) indicates success. Any non-zero value indicates failure.

  • Predefined error codes:

    • TS_ERR_CONNECTION (-1)

    • TS_ERR_EXECUTION (-2)

    • TS_ERR_INVALID_PARAM (-3)

    • TS_ERR_NULL_PTR (-4)

    • TS_ERR_UNKNOWN (-99)

  • The implementation may also return other negative values, which must be interpreted together with ts_get_last_error().

  • The Session C++ API reports many errors through exceptions and does not return a unified status code. The C API uniformly returns the integer type TsStatus, and fine-grained error information can be obtained through ts_get_last_error().

const char* ts_get_last_error(void);

Returns the error message of the last failed C API call in the current thread. The returned pointer is valid until the next C API call in the same thread.

3.1.2 Memory and handle rules

  • All char* buf + int bufLen output parameters must be allocated by the caller.

  • CSession*, CTablet*, CSessionDataSet*, and CRowRecord* are opaque pointers. After successful creation, the caller must release them according to the conventions of each API.

3.2 Enumerations and constants

  • TSDataType_C (data type)
Enumeration valueMeaning
TS_TYPE_BOOLEANBoolean
TS_TYPE_INT3232-bit integer
TS_TYPE_INT6464-bit integer
TS_TYPE_FLOATSingle-precision floating point
TS_TYPE_DOUBLEDouble-precision floating point
TS_TYPE_TEXTText
TS_TYPE_TIMESTAMPTimestamp
TS_TYPE_DATEDate
TS_TYPE_BLOBBinary large object
TS_TYPE_STRINGString
TS_TYPE_INVALIDInvalid parameter/error path (not a server-side type)
  • TSEncoding_C (encoding)

TS_ENCODING_PLAIN, TS_ENCODING_DICTIONARY, TS_ENCODING_RLE, TS_ENCODING_DIFF, TS_ENCODING_TS_2DIFF, TS_ENCODING_BITMAP, TS_ENCODING_GORILLA_V1, TS_ENCODING_REGULAR, TS_ENCODING_GORILLA, TS_ENCODING_ZIGZAG, TS_ENCODING_FREQ

  • TSCompressionType_C (compression)

TS_COMPRESSION_UNCOMPRESSED, TS_COMPRESSION_SNAPPY, TS_COMPRESSION_GZIP, TS_COMPRESSION_LZO, TS_COMPRESSION_SDT, TS_COMPRESSION_PAA, TS_COMPRESSION_PLA, TS_COMPRESSION_LZ4, TS_COMPRESSION_ZSTD, TS_COMPRESSION_LZMA2

3.3 Handles, status codes, and constants

NameC definitionMeaningLifecycle responsibility
CSession*typedef struct CSession_ CSession;Tree model sessionAfter ts_session_new / ts_session_new_with_zone / ts_session_new_multi_node succeeds, the caller calls ts_session_close if it has been opened, and then ts_session_destroy
CTablet*typedef struct CTablet_ CTablet; (opaque)Tablet batch writing, shared by tree and table modelsAfter ts_tablet_new / ts_tablet_new_with_category succeeds, the caller calls ts_tablet_destroy
CSessionDataSet*typedef struct CSessionDataSet_ CSessionDataSet; (opaque)Query result set, shared by tree and table modelsAfter a query API successfully returns *dataSet, the caller calls ts_dataset_destroy
CRowRecord*typedef struct CRowRecord_ CRowRecord; (opaque)Current rowWhen ts_dataset_next returns a non-null value, the caller calls ts_row_record_destroy
TsStatus
typedef int64_t TsStatus;API execution result codeTS_OK is 0. Any non-zero value indicates failure
ts_get_last_errorconst char* ts_get_last_error(void);Error message of the last failed C API call in the current threadThe returned pointer is valid until the next C API call in the same thread

3.4 Common Tablet APIs

3.4.1 Creation and destruction

API signatureFunctionInput parametersReturn valueSuccess conditionFailure conditionResource responsibility
CTablet* ts_tablet_new(const char* deviceId, int columnCount, const char* const* columnNames, const TSDataType_C* dataTypes, int maxRowNumber);Create a Tablet handledeviceId: device or table name; columnNames / dataTypes: arrays of column names and types; maxRowNumber: maximum number of rowsCTablet*Returns a non-null handleReturns a null handleCaller calls ts_tablet_destroy
void ts_tablet_destroy(CTablet* tablet);Destroy a Tablet handletablet: handle to releaseNoneThe handle must not be used after the call-Releases tablet

3.4.2 Data filling and state control

API signatureFunctionReturn valueSuccess conditionRemarks
int ts_tablet_get_row_count(CTablet* tablet);Query the current valid row count of the TabletintRow count >= 0Read-only query
TsStatus ts_tablet_set_row_count(CTablet* tablet, int rowCount);Set the valid row count of the TabletTsStatusTS_OKThe valid row count must be set before writing
TsStatus ts_tablet_add_timestamp(CTablet* tablet, int rowIndex, int64_t timestamp);Write a timestamp for the specified rowTsStatusTS_OK
TsStatus ts_tablet_add_value_bool(CTablet* tablet, int colIndex, int rowIndex, bool value);Write a Boolean valueTsStatusTS_OK
TsStatus ts_tablet_add_value_int32(CTablet* tablet, int colIndex, int rowIndex, int32_t value);Write an int32 valueTsStatusTS_OK
TsStatus ts_tablet_add_value_int64(CTablet* tablet, int colIndex, int rowIndex, int64_t value);Write an int64 valueTsStatusTS_OK
TsStatus ts_tablet_add_value_float(CTablet* tablet, int colIndex, int rowIndex, float value);Write a float valueTsStatusTS_OK
TsStatus ts_tablet_add_value_double(CTablet* tablet, int colIndex, int rowIndex, double value);Write a double valueTsStatusTS_OK
TsStatus ts_tablet_add_value_string(CTablet* tablet, int colIndex, int rowIndex, const char* value);Write a stringTsStatusTS_OKString memory is managed by the caller
void ts_tablet_reset(CTablet* tablet);Reset the internal state of the Tablet for reusevoid-Does not release the object. Only clears the state

Description: The current SessionC implementation does not provide ts_tablet_add_value_object. Use the C++ Session API to write OBJECT values.

3.5 Common DataSet APIs

3.5.1 Iteration control and metadata

API signatureFunctionReturn valueRemarks
void ts_dataset_set_fetch_size(CSessionDataSet* dataSet, int fetchSize);Set the fetch batch size of the result setNone
bool ts_dataset_has_next(CSessionDataSet* dataSet);Determine whether there may be another rowboolOn failure, check ts_get_last_error()
CRowRecord* ts_dataset_next(CSessionDataSet* dataSet);Get the next row record handleRow handle pointerNon-NULL indicates a valid row. NULL indicates end or failure
int ts_dataset_get_column_count(CSessionDataSet* dataSet);Get the number of columns in the result setint
const char* ts_dataset_get_column_name(CSessionDataSet* dataSet, int index);Get a column name by indexString pointerNo buf/bufLen output
const char* ts_dataset_get_column_type(CSessionDataSet* dataSet, int index);Get a column type name by indexType name string pointerNo buf/bufLen output
void ts_dataset_destroy(CSessionDataSet* dataSet);Release a query result set handleNoneAfter each non-null CRowRecord* returned by ts_dataset_next, call ts_row_record_destroy in time

3.5.2 Value access

API signatureFunctionReturn valueRemarks
void ts_row_record_destroy(CRowRecord* record);Release a row record handleNone
int64_t ts_row_record_get_timestamp(CRowRecord* record);Read the timestamp of the current rowint64_tThe timestamp is not read from DataSet
int ts_row_record_get_field_count(CRowRecord* record);Read the number of fields in the current rowint
bool ts_row_record_is_null(CRowRecord* record, int index);Determine whether the specified column is nullbool
bool ts_row_record_get_bool(CRowRecord* record, int index);Read a Boolean value by column indexbool
int32_t ts_row_record_get_int32(CRowRecord* record, int index);Read an int32 value by column indexint32_t
int64_t ts_row_record_get_int64(CRowRecord* record, int index);Read an int64 value by column indexint64_t
float ts_row_record_get_float(CRowRecord* record, int index);Read a float value by column indexfloat
double ts_row_record_get_double(CRowRecord* record, int index);Read a double value by column indexdouble
const char* ts_row_record_get_string(CRowRecord* record, int index);Read the byte view of a text/binary columnconst char.May contain .. Not a buf . bufLen pattern
int32_t ts_row_record_get_date_int32(CRowRecord* record, int index);Read a DATE column and return an integer in YYYYMMDD formatint32_tReturns 0 if the field is null, out of bounds, or not DATE
size_t ts_row_record_get_string_byte_length(CRowRecord* record, int index);Read the byte length of a string/binary fieldsize_tTEXT/BLOB/STRING, etc. Do not use strlen
TSDataType_C ts_row_record_get_data_type(CRowRecord* record, int index);Read the data type enumeration by column indexEnumerationReturns TS_TYPE_INVALID for invalid parameters or out-of-bounds indexes

3.6 Tree model CSession API matrix

3.6.1 Lifecycle and session properties

API signatureFunctionReturn valueSuccess conditionResource responsibility
CSession* ts_session_new(const char* host, int rpcPort, const char* username, const char* password);Create a tree model session (single host)CSession*Returns a non-null handleIf opened, call ts_session_close first, and then ts_session_destroy
CSession* ts_session_new_with_zone(const char* host, int rpcPort, const char* username, const char* password, const char* zoneId, int fetchSize);Create a session and specify the time zone and fetch sizeCSession*Returns a non-null handleSame as above
CSession* ts_session_new_multi_node(const char* const* nodeUrls, int urlCount, const char* username, const char* password);Create a tree model session (multi-node URL)CSession*Returns a non-null handleSame as above
void ts_session_destroy(CSession* session);Destroy a tree model session handleNone-Releases session
TsStatus ts_session_open(CSession* session);Open a tree model RPC connectionTsStatusTS_OKOn failure, read ts_get_last_error()
TsStatus ts_session_open_with_compression(CSession* session, bool enableRPCCompression);Open a connection and set whether to enable RPC compressionTsStatusTS_OKSame as above
TsStatus ts_session_close(CSession* session);Close a tree model connectionTsStatusTS_OKts_session_destroy is still required
TsStatus ts_session_set_timezone(CSession* session, const char* zoneId);Set the session time zoneTsStatusTS_OK
TsStatus ts_session_get_timezone(CSession* session, char* buf, int bufLen);Get the current session time zone string into a bufferTsStatusTS_OK and buf is validThe caller allocates the buffer

3.6.2 Schema management

API signatureFunctionReturn valueRemarks
TsStatus ts_session_create_database(CSession* session, const char* database);Create a databaseTsStatus
TsStatus ts_session_delete_database(CSession* session, const char* database);Delete a databaseTsStatus
TsStatus ts_session_delete_databases(CSession* session, const char* const* databases, int count);Delete databases in batchesTsStatus
TsStatus ts_session_create_timeseries(CSession* session, const char* path, TSDataType_C dataType, TSEncoding_C encoding, TSCompressionType_C compressor);Create a single timeseriesTsStatus
TsStatus ts_session_create_timeseries_ex(CSession* session, const char* path, TSDataType_C dataType, TSEncoding_C encoding, TSCompressionType_C compressor, int propsCount, const char* const* propKeys, const char* const* propValues, int tagsCount, const char* const* tagKeys, const char* const* tagValues, int attrsCount, const char* const* attrKeys, const char* const* attrValues, const char* measurementAlias);Create a timeseries with extensions such as properties, tags, attributes, and aliasTsStatuspropsCount/tagsCount/attrsCount must match their corresponding key/value arrays. measurementAlias can be NULL
TsStatus ts_session_create_multi_timeseries(CSession* session, int count, const char* const* paths, const TSDataType_C* dataTypes, const TSEncoding_C* encodings, const TSCompressionType_C* compressors);Create timeseries in batchesTsStatus
TsStatus ts_session_create_aligned_timeseries(CSession* session, const char* deviceId, int count, const char* const* measurements, const TSDataType_C* dataTypes, const TSEncoding_C* encodings, const TSCompressionType_C* compressors);Create aligned timeseries under the specified deviceTsStatus
TsStatus ts_session_check_timeseries_exists(CSession* session, const char* path, bool* exists);Check whether the timeseries for the path existsTsStatusExistence is output through bool*
TsStatus ts_session_delete_timeseries(CSession* session, const char* path);Delete a single timeseriesTsStatus
TsStatus ts_session_delete_timeseries_batch(CSession* session, const char* const* paths, int count);Delete timeseries in batchesTsStatus

3.6.3 Writing

API signatureFunctionReturn valueRemarks
TsStatus ts_session_insert_record_str(CSession* session, const char* deviceId, int64_t time, int count, const char* const* measurements, const char* const* values);Insert one record for one device (string values)TsStatusNo new handle
TsStatus ts_session_insert_record(CSession* session, const char* deviceId, int64_t time, int count, const char* const* measurements, const TSDataType_C* types, const void* const* values);Insert one record for one device (strongly typed values)TsStatusvalues[i] points to the value of the type corresponding to types[i]
TsStatus ts_session_insert_aligned_record_str(CSession* session, const char* deviceId, int64_t time, int count, const char* const* measurements, const char* const* values);Insert one record for an aligned device (string values)TsStatus
TsStatus ts_session_insert_aligned_record(CSession* session, const char* deviceId, int64_t time, int count, const char* const* measurements, const TSDataType_C* types, const void* const* values);Insert one record for an aligned device (strongly typed values)TsStatus
TsStatus ts_session_insert_records_str(CSession* session, int deviceCount, const char* const* deviceIds, const int64_t* times, const int* measurementCounts, const char* const* const* measurementsList, const char* const* const* valuesList);Batch insert for multiple devices (string values)TsStatusThe lengths of measurementsList[i] / valuesList[i] are determined by measurementCounts[i]
TsStatus ts_session_insert_aligned_records_str(CSession* session, int deviceCount, const char* const* deviceIds, const int64_t* times, const int* measurementCounts, const char* const* const* measurementsList, const char* const* const* valuesList);Batch insert for multiple aligned devices (string values)TsStatusSame as above
TsStatus ts_session_insert_records(CSession* session, int deviceCount, const char* const* deviceIds, const int64_t* times, const int* measurementCounts, const char* const* const* measurementsList, const TSDataType_C* const* typesList, const void* const* const* valuesList);Batch insert for multiple devices (strongly typed values)TsStatus
TsStatus ts_session_insert_aligned_records(CSession* session, int deviceCount, const char* const* deviceIds, const int64_t* times, const int* measurementCounts, const char* const* const* measurementsList, const TSDataType_C* const* typesList, const void* const* const* valuesList);Batch insert for multiple aligned devices (strongly typed values)TsStatus
TsStatus ts_session_insert_records_of_one_device(CSession* session, const char* deviceId, int rowCount, const int64_t* times, const int* measurementCounts, const char* const* const* measurementsList, const TSDataType_C* const* typesList, const void* const* const* valuesList, bool sorted);Batch insert multiple rows for one deviceTsStatussorted indicates whether timestamps are already sorted
TsStatus ts_session_insert_aligned_records_of_one_device(CSession* session, const char* deviceId, int rowCount, const int64_t* times, const int* measurementCounts, const char* const* const* measurementsList, const TSDataType_C* const* typesList, const void* const* const* valuesList, bool sorted);Batch insert multiple aligned rows for one deviceTsStatusSame as above
TsStatus ts_session_insert_tablet(CSession* session, CTablet* tablet, bool sorted);Batch write by Tablet in the tree modelTsStatusOwnership of tablet is not transferred
TsStatus ts_session_insert_aligned_tablet(CSession* session, CTablet* tablet, bool sorted);Batch write by Tablet in the aligned modelTsStatusOwnership of tablet is not transferred
TsStatus ts_session_insert_tablets(CSession* session, int tabletCount, const char* const* deviceIds, CTablet** tablets, bool sorted);Batch write multiple TabletsTsStatusOwnership of tablets is not transferred
TsStatus ts_session_insert_aligned_tablets(CSession* session, int tabletCount, const char* const* deviceIds, CTablet** tablets, bool sorted);Batch write multiple aligned TabletsTsStatusSame as above

3.6.4 Querying

API signatureFunctionReturn valueResource responsibility
TsStatus ts_session_execute_query(CSession* session, const char* sql, CSessionDataSet** dataSet);Execute query SQL and return a result setTsStatusCaller calls ts_dataset_destroy for *dataSet
TsStatus ts_session_execute_query_with_timeout(CSession* session, const char* sql, int64_t timeoutInMs, CSessionDataSet** dataSet);Execute a query with timeoutTsStatusSame as above
TsStatus ts_session_execute_non_query(CSession* session, const char* sql);Execute non-query SQLTsStatusNo new handle
TsStatus ts_session_execute_raw_data_query(CSession* session, int pathCount, const char* const* paths, int64_t startTime, int64_t endTime, CSessionDataSet** dataSet);Query raw data by paths and time rangeTsStatusCaller destroys *dataSet
TsStatus ts_session_execute_last_data_query(CSession* session, int pathCount, const char* const* paths, CSessionDataSet** dataSet);Query last point data for specified pathsTsStatusCaller destroys *dataSet
TsStatus ts_session_execute_last_data_query_with_time(CSession* session, int pathCount, const char* const* paths, int64_t lastTime, CSessionDataSet** dataSet);Query last point data with lastTimeTsStatusCaller destroys *dataSet

3.6.5 Data deletion

API signatureFunctionReturn value
TsStatus ts_session_delete_data(CSession* session, const char* path, int64_t endTime);Delete data by pathTsStatus
TsStatus ts_session_delete_data_batch(CSession* session, int pathCount, const char* const* paths, int64_t endTime);Delete data by multiple paths in batchesTsStatus
TsStatus ts_session_delete_data_range(CSession* session, int pathCount, const char* const* paths, int64_t startTime, int64_t endTime);Delete data by time rangeTsStatus

4. Sample code

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "SessionC.h"

#define HOST "127.0.0.1"
#define PORT 6667
#define USER "root"
#define PASS "root"

#define TS_PATH "root.cdemo.d0.s0"
#define DEVICE "root.cdemo.d0"

static void fail(const char* ctx, CSession* s) {
  fprintf(stderr, "[tree_example] %s failed: %s.", ctx, ts_get_last_error());
  if (s) {
    ts_session_close(s);
    ts_session_destroy(s);
  }
  exit(1);
}

int main(void) {
  const char* path = TS_PATH;
  CSession* session = ts_session_new(HOST, PORT, USER, PASS);
  if (!session) {
    fprintf(stderr, "[tree_example] ts_session_new returned NULL: %s.", ts_get_last_error());
    return 1;
  }
  if (ts_session_open(session) != TS_OK) {
    fail("ts_session_open", session);
  }

  bool exists = false;
  if (ts_session_check_timeseries_exists(session, path, &exists) != TS_OK) {
    fail("ts_session_check_timeseries_exists", session);
  }
  if (exists) {
    if (ts_session_delete_timeseries(session, path) != TS_OK) {
      fail("ts_session_delete_timeseries (cleanup old)", session);
    }
  }
  if (ts_session_create_timeseries(session, path, TS_TYPE_INT64, TS_ENCODING_RLE,
                                   TS_COMPRESSION_SNAPPY) != TS_OK) {
    fail("ts_session_create_timeseries", session);
  }

  const char* measurements[] = {"s0"};
  const char* values[] = {"100"};
  if (ts_session_insert_record_str(session, DEVICE, 1LL, 1, measurements, values) != TS_OK) {
    fail("ts_session_insert_record_str", session);
  }

  CSessionDataSet* dataSet = NULL;
  if (ts_session_execute_query(session, "select s0 from root.cdemo.d0", &dataSet) != TS_OK) {
    fail("ts_session_execute_query", session);
  }
  if (!dataSet) {
    fprintf(stderr, "[tree_example] dataSet is NULL.");
    ts_session_close(session);
    ts_session_destroy(session);
    return 1;
  }
  ts_dataset_set_fetch_size(dataSet, 1024);

  int rows = 0;
  while (ts_dataset_has_next(dataSet)) {
    CRowRecord* record = ts_dataset_next(dataSet);
    if (!record) {
      break;
    }
    int64_t v = ts_row_record_get_int64(record, 0);
    printf("[tree_example] row %d: s0 = %lld.", rows, (long long)v);
    ts_row_record_destroy(record);
    rows++;
  }
  ts_dataset_destroy(dataSet);

  printf("[tree_example] done, read %d row(s)..", rows);

  if (ts_session_delete_timeseries(session, path) != TS_OK) {
    fail("ts_session_delete_timeseries", session);
  }

  ts_session_close(session);
  ts_session_destroy(session);
  return 0;
}