This is an automated email from the ASF dual-hosted git repository.
jt2594838 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 c1843f2ff7e Fix C++ client tablet bounds and session close semantics
(#18005)
c1843f2ff7e is described below
commit c1843f2ff7effdf89578f1457358dc4d403e6bce
Author: Hongzhi Gao <[email protected]>
AuthorDate: Tue Jun 23 12:10:36 2026 +0800
Fix C++ client tablet bounds and session close semantics (#18005)
Add boundary checks for Tablet addTimestamp/addValue and validate
ts_tablet_set_row_count to prevent rowSize from exceeding maxRowNumber. Align
Session::close with Java by closing connections and routing all operations
through getDefaultSessionConnection(). Map C API out_of_range to
TS_ERR_INVALID_PARAM and add regression tests.
---
iotdb-client/client-cpp/src/include/Session.h | 20 +++-
iotdb-client/client-cpp/src/rpc/SessionImpl.h | 11 +-
iotdb-client/client-cpp/src/session/Session.cpp | 124 +++++++++++++--------
iotdb-client/client-cpp/src/session/SessionC.cpp | 16 ++-
iotdb-client/client-cpp/test/cpp/sessionCIT.cpp | 21 ++++
.../client-cpp/test/cpp/sessionCRelationalIT.cpp | 13 +++
iotdb-client/client-cpp/test/cpp/sessionIT.cpp | 25 +++++
.../client-cpp/test/cpp/sessionRelationalIT.cpp | 13 +++
8 files changed, 189 insertions(+), 54 deletions(-)
diff --git a/iotdb-client/client-cpp/src/include/Session.h
b/iotdb-client/client-cpp/src/include/Session.h
index bd9d77f3bba..a0910584e57 100644
--- a/iotdb-client/client-cpp/src/include/Session.h
+++ b/iotdb-client/client-cpp/src/include/Session.h
@@ -232,6 +232,14 @@ public:
}
void addTimestamp(size_t rowIndex, int64_t timestamp) {
+ if (rowIndex >= static_cast<size_t>(maxRowNumber)) {
+ char tmpStr[100];
+ snprintf(tmpStr, sizeof(tmpStr),
+ "Tablet::addTimestamp(), rowIndex >= maxRowNumber.
rowIndex=%ld, "
+ "maxRowNumber=%ld.",
+ (long)rowIndex, (long)maxRowNumber);
+ throw std::out_of_range(tmpStr);
+ }
timestamps[rowIndex] = timestamp;
rowSize = max(rowSize, rowIndex + 1);
}
@@ -248,10 +256,18 @@ public:
throw std::out_of_range(tmpStr);
}
- if (rowIndex >= rowSize) {
+ if (rowIndex >= static_cast<size_t>(maxRowNumber)) {
+ char tmpStr[100];
+ snprintf(tmpStr, sizeof(tmpStr),
+ "Tablet::addValue(), rowIndex >= maxRowNumber. rowIndex=%ld,
maxRowNumber=%ld.",
+ (long)rowIndex, (long)maxRowNumber);
+ throw std::out_of_range(tmpStr);
+ }
+
+ if (rowIndex >= static_cast<size_t>(rowSize)) {
char tmpStr[100];
snprintf(tmpStr, sizeof(tmpStr),
- "Tablet::addValue(), rowIndex >= rowSize. rowIndex=%ld,
rowSize.size()=%ld.",
+ "Tablet::addValue(), rowIndex >= rowSize. rowIndex=%ld,
rowSize=%ld.",
(long)rowIndex, (long)rowSize);
throw std::out_of_range(tmpStr);
}
diff --git a/iotdb-client/client-cpp/src/rpc/SessionImpl.h
b/iotdb-client/client-cpp/src/rpc/SessionImpl.h
index 4d14c99f381..9fc3d917293 100644
--- a/iotdb-client/client-cpp/src/rpc/SessionImpl.h
+++ b/iotdb-client/client-cpp/src/rpc/SessionImpl.h
@@ -60,6 +60,13 @@ public:
std::shared_ptr<INodesSupplier> nodesSupplier_;
std::shared_ptr<SessionConnection> defaultSessionConnection_;
+ std::shared_ptr<SessionConnection> getDefaultSessionConnection() {
+ if (isClosed_ || !defaultSessionConnection_) {
+ throw IoTDBConnectionException("Session is not open, please invoke
Session.open() first");
+ }
+ return defaultSessionConnection_;
+ }
+
TEndPoint defaultEndPoint_;
struct TEndPointHash {
@@ -168,7 +175,7 @@ void Session::Impl::insertByGroup(
if (endPointToSessionConnection.size() > 1) {
removeBrokenSessionConnection(connection);
try {
- insertConsumer(defaultSessionConnection_, req);
+ insertConsumer(getDefaultSessionConnection(), req);
} catch (const RedirectException&) {
}
} else {
@@ -216,7 +223,7 @@ void Session::Impl::insertOnce(
if (endPointToSessionConnection.size() > 1) {
removeBrokenSessionConnection(connection);
try {
- insertConsumer(defaultSessionConnection_, req);
+ insertConsumer(getDefaultSessionConnection(), req);
} catch (const RedirectException&) {
}
} else {
diff --git a/iotdb-client/client-cpp/src/session/Session.cpp
b/iotdb-client/client-cpp/src/session/Session.cpp
index 3af4de3bcce..7dd0a7813ed 100644
--- a/iotdb-client/client-cpp/src/session/Session.cpp
+++ b/iotdb-client/client-cpp/src/session/Session.cpp
@@ -1067,6 +1067,31 @@ void Session::close() {
if (impl_->isClosed_) {
return;
}
+ try {
+ if (impl_->enableRedirection_) {
+ for (auto& entry : impl_->endPointToSessionConnection) {
+ if (entry.second) {
+ try {
+ entry.second->close();
+ } catch (const exception& e) {
+ log_debug(e.what());
+ }
+ }
+ }
+ impl_->endPointToSessionConnection.clear();
+ }
+ if (impl_->defaultSessionConnection_) {
+ try {
+ impl_->defaultSessionConnection_->close();
+ } catch (const exception& e) {
+ log_debug(e.what());
+ }
+ impl_->defaultSessionConnection_.reset();
+ }
+ } catch (...) {
+ impl_->isClosed_ = true;
+ throw;
+ }
impl_->isClosed_ = true;
}
@@ -1087,7 +1112,7 @@ void Session::insertRecord(const string& deviceId,
int64_t time, const vector<st
impl_->deviceIdToEndpoint.find(deviceId) !=
impl_->deviceIdToEndpoint.end()) {
impl_->deviceIdToEndpoint.erase(deviceId);
try {
- impl_->defaultSessionConnection_->insertStringRecord(req);
+ impl_->getDefaultSessionConnection()->insertStringRecord(req);
} catch (RedirectException& e) {
}
} else {
@@ -1116,7 +1141,7 @@ void Session::insertRecord(const string& deviceId,
int64_t time, const vector<st
impl_->deviceIdToEndpoint.find(deviceId) !=
impl_->deviceIdToEndpoint.end()) {
impl_->deviceIdToEndpoint.erase(deviceId);
try {
- impl_->defaultSessionConnection_->insertRecord(req);
+ impl_->getDefaultSessionConnection()->insertRecord(req);
} catch (RedirectException& e) {
}
} else {
@@ -1143,7 +1168,7 @@ void Session::insertAlignedRecord(const string& deviceId,
int64_t time,
impl_->deviceIdToEndpoint.find(deviceId) !=
impl_->deviceIdToEndpoint.end()) {
impl_->deviceIdToEndpoint.erase(deviceId);
try {
- impl_->defaultSessionConnection_->insertStringRecord(req);
+ impl_->getDefaultSessionConnection()->insertStringRecord(req);
} catch (RedirectException& e) {
}
} else {
@@ -1173,7 +1198,7 @@ void Session::insertAlignedRecord(const string& deviceId,
int64_t time,
impl_->deviceIdToEndpoint.find(deviceId) !=
impl_->deviceIdToEndpoint.end()) {
impl_->deviceIdToEndpoint.erase(deviceId);
try {
- impl_->defaultSessionConnection_->insertRecord(req);
+ impl_->getDefaultSessionConnection()->insertRecord(req);
} catch (RedirectException& e) {
}
} else {
@@ -1202,7 +1227,7 @@ void Session::insertRecords(const vector<string>&
deviceIds, const vector<int64_
request.__set_valuesList(valuesList);
request.__set_isAligned(false);
try {
- impl_->defaultSessionConnection_->insertStringRecords(request);
+ impl_->getDefaultSessionConnection()->insertStringRecords(request);
} catch (RedirectException& e) {
}
}
@@ -1235,7 +1260,7 @@ void Session::insertRecords(const vector<string>&
deviceIds, const vector<int64_
request.__set_valuesList(bufferList);
request.__set_isAligned(false);
try {
- impl_->defaultSessionConnection_->insertRecords(request);
+ impl_->getDefaultSessionConnection()->insertRecords(request);
} catch (RedirectException& e) {
}
}
@@ -1260,7 +1285,7 @@ void Session::insertAlignedRecords(const vector<string>&
deviceIds, const vector
request.__set_valuesList(valuesList);
request.__set_isAligned(true);
try {
- impl_->defaultSessionConnection_->insertStringRecords(request);
+ impl_->getDefaultSessionConnection()->insertStringRecords(request);
} catch (RedirectException& e) {
}
}
@@ -1293,7 +1318,7 @@ void Session::insertAlignedRecords(const vector<string>&
deviceIds, const vector
request.__set_valuesList(bufferList);
request.__set_isAligned(false);
try {
- impl_->defaultSessionConnection_->insertRecords(request);
+ impl_->getDefaultSessionConnection()->insertRecords(request);
} catch (RedirectException& e) {
}
}
@@ -1345,7 +1370,7 @@ void Session::insertRecordsOfOneDevice(const string&
deviceId, vector<int64_t>&
impl_->deviceIdToEndpoint.find(deviceId) !=
impl_->deviceIdToEndpoint.end()) {
impl_->deviceIdToEndpoint.erase(deviceId);
try {
- impl_->defaultSessionConnection_->insertRecordsOfOneDevice(request);
+
impl_->getDefaultSessionConnection()->insertRecordsOfOneDevice(request);
} catch (RedirectException& e) {
}
} else {
@@ -1400,7 +1425,7 @@ void Session::insertAlignedRecordsOfOneDevice(const
string& deviceId, vector<int
impl_->deviceIdToEndpoint.find(deviceId) !=
impl_->deviceIdToEndpoint.end()) {
impl_->deviceIdToEndpoint.erase(deviceId);
try {
- impl_->defaultSessionConnection_->insertRecordsOfOneDevice(request);
+
impl_->getDefaultSessionConnection()->insertRecordsOfOneDevice(request);
} catch (RedirectException& e) {
}
} else {
@@ -1452,7 +1477,7 @@ void Session::Impl::insertTablet(TSInsertTabletReq
request) {
if (enableRedirection_ && deviceIdToEndpoint.find(deviceId) !=
deviceIdToEndpoint.end()) {
deviceIdToEndpoint.erase(deviceId);
try {
- defaultSessionConnection_->insertTablet(request);
+ getDefaultSessionConnection()->insertTablet(request);
} catch (RedirectException& e) {
}
} else {
@@ -1470,7 +1495,7 @@ void Session::insertTablet(Tablet& tablet, bool sorted) {
void Session::insertRelationalTablet(Tablet& tablet, bool sorted) {
std::unordered_map<std::shared_ptr<SessionConnection>, Tablet>
relationalTabletGroup;
if (impl_->tableModelDeviceIdToEndpoint.empty()) {
- relationalTabletGroup.insert(make_pair(impl_->defaultSessionConnection_,
tablet));
+
relationalTabletGroup.insert(make_pair(impl_->getDefaultSessionConnection(),
tablet));
} else if (SessionUtils::isTabletContainsSingleDevice(tablet)) {
relationalTabletGroup.insert(
make_pair(impl_->getSessionConnection(tablet.getDeviceID(0)), tablet));
@@ -1571,7 +1596,7 @@ void Session::Impl::insertRelationalTabletOnce(
removeBrokenSessionConnection(connection);
try {
TSStatus respStatus;
-
defaultSessionConnection_->getSessionClient()->insertTablet(respStatus,
request);
+
getDefaultSessionConnection()->getSessionClient()->insertTablet(respStatus,
request);
RpcUtils::verifySuccess(respStatus);
} catch (RedirectException& e) {
}
@@ -1693,7 +1718,7 @@ void Session::insertTablets(unordered_map<string,
Tablet*>& tablets, bool sorted
request.__set_isAligned(isAligned);
try {
TSStatus respStatus;
- impl_->defaultSessionConnection_->insertTablets(request);
+ impl_->getDefaultSessionConnection()->insertTablets(request);
RpcUtils::verifySuccess(respStatus);
} catch (RedirectException& e) {
}
@@ -1722,7 +1747,7 @@ void Session::testInsertRecord(const string& deviceId,
int64_t time,
req.__set_values(values);
TSStatus tsStatus;
try {
- impl_->defaultSessionConnection_->testInsertStringRecord(req);
+ impl_->getDefaultSessionConnection()->testInsertStringRecord(req);
RpcUtils::verifySuccess(tsStatus);
} catch (const TTransportException& e) {
log_debug(e.what());
@@ -1748,7 +1773,7 @@ void Session::testInsertTablet(const Tablet& tablet) {
request.__set_size(tablet.rowSize);
try {
TSStatus tsStatus;
- impl_->defaultSessionConnection_->testInsertTablet(request);
+ impl_->getDefaultSessionConnection()->testInsertTablet(request);
RpcUtils::verifySuccess(tsStatus);
} catch (const TTransportException& e) {
log_debug(e.what());
@@ -1778,7 +1803,8 @@ void Session::testInsertRecords(const vector<string>&
deviceIds, const vector<in
try {
TSStatus tsStatus;
-
impl_->defaultSessionConnection_->getSessionClient()->insertStringRecords(tsStatus,
request);
+
impl_->getDefaultSessionConnection()->getSessionClient()->insertStringRecords(tsStatus,
+
request);
RpcUtils::verifySuccess(tsStatus);
} catch (const TTransportException& e) {
log_debug(e.what());
@@ -1799,7 +1825,7 @@ void Session::deleteTimeseries(const string& path) {
}
void Session::deleteTimeseries(const vector<string>& paths) {
- impl_->defaultSessionConnection_->deleteTimeseries(paths);
+ impl_->getDefaultSessionConnection()->deleteTimeseries(paths);
}
void Session::deleteData(const string& path, int64_t endTime) {
@@ -1817,11 +1843,11 @@ void Session::deleteData(const vector<string>& paths,
int64_t startTime, int64_t
req.__set_paths(paths);
req.__set_startTime(startTime);
req.__set_endTime(endTime);
- impl_->defaultSessionConnection_->deleteData(req);
+ impl_->getDefaultSessionConnection()->deleteData(req);
}
void Session::setStorageGroup(const string& storageGroupId) {
- impl_->defaultSessionConnection_->setStorageGroup(storageGroupId);
+ impl_->getDefaultSessionConnection()->setStorageGroup(storageGroupId);
}
void Session::deleteStorageGroup(const string& storageGroup) {
@@ -1831,7 +1857,7 @@ void Session::deleteStorageGroup(const string&
storageGroup) {
}
void Session::deleteStorageGroups(const vector<string>& storageGroups) {
- impl_->defaultSessionConnection_->deleteStorageGroups(storageGroups);
+ impl_->getDefaultSessionConnection()->deleteStorageGroups(storageGroups);
}
void Session::createDatabase(const string& database) {
@@ -1880,7 +1906,7 @@ void Session::createTimeseries(const string& path,
TSDataType::TSDataType dataTy
if (!measurementAlias.empty()) {
req.__set_measurementAlias(measurementAlias);
}
- impl_->defaultSessionConnection_->createTimeseries(req);
+ impl_->getDefaultSessionConnection()->createTimeseries(req);
}
void Session::createMultiTimeseries(const vector<string>& paths,
@@ -1929,7 +1955,7 @@ void Session::createMultiTimeseries(const vector<string>&
paths,
request.__set_measurementAliasList(*measurementAliasList);
}
- impl_->defaultSessionConnection_->createMultiTimeseries(request);
+ impl_->getDefaultSessionConnection()->createMultiTimeseries(request);
}
void Session::createAlignedTimeseries(
@@ -1962,7 +1988,7 @@ void Session::createAlignedTimeseries(
}
request.__set_compressors(compressorsOrdinal);
- impl_->defaultSessionConnection_->createAlignedTimeseries(request);
+ impl_->getDefaultSessionConnection()->createAlignedTimeseries(request);
}
bool Session::checkTimeseriesExists(const string& path) {
@@ -1983,7 +2009,7 @@ bool Session::checkTimeseriesExists(const string& path) {
shared_ptr<SessionConnection> Session::Impl::getQuerySessionConnection() {
auto endPoint = nodesSupplier_->getQueryEndPoint();
if (!endPoint.is_initialized() || endPointToSessionConnection.empty()) {
- return defaultSessionConnection_;
+ return getDefaultSessionConnection();
}
auto it = endPointToSessionConnection.find(endPoint.value());
@@ -1991,6 +2017,7 @@ shared_ptr<SessionConnection>
Session::Impl::getQuerySessionConnection() {
return it->second;
}
+ getDefaultSessionConnection();
shared_ptr<SessionConnection> newConnection;
try {
newConnection =
@@ -2000,7 +2027,7 @@ shared_ptr<SessionConnection>
Session::Impl::getQuerySessionConnection() {
return newConnection;
} catch (exception& e) {
log_debug("Session::Impl::getQuerySessionConnection() exception: " +
e.what());
- return newConnection;
+ return getDefaultSessionConnection();
}
}
@@ -2008,7 +2035,7 @@ shared_ptr<SessionConnection>
Session::Impl::getSessionConnection(std::string de
if (!enableRedirection_ || deviceIdToEndpoint.find(deviceId) ==
deviceIdToEndpoint.end() ||
endPointToSessionConnection.find(deviceIdToEndpoint[deviceId]) ==
endPointToSessionConnection.end()) {
- return defaultSessionConnection_;
+ return getDefaultSessionConnection();
}
return
endPointToSessionConnection.find(deviceIdToEndpoint[deviceId])->second;
}
@@ -2019,21 +2046,21 @@
Session::Impl::getSessionConnection(std::shared_ptr<storage::IDeviceID> deviceId
tableModelDeviceIdToEndpoint.find(deviceId) ==
tableModelDeviceIdToEndpoint.end() ||
endPointToSessionConnection.find(tableModelDeviceIdToEndpoint[deviceId])
==
endPointToSessionConnection.end()) {
- return defaultSessionConnection_;
+ return getDefaultSessionConnection();
}
return
endPointToSessionConnection.find(tableModelDeviceIdToEndpoint[deviceId])->second;
}
string Session::getTimeZone() {
- auto ret = impl_->defaultSessionConnection_->getTimeZone();
+ auto ret = impl_->getDefaultSessionConnection()->getTimeZone();
return ret.timeZone;
}
void Session::setTimeZone(const string& zoneId) {
TSSetTimeZoneReq req;
- req.__set_sessionId(impl_->defaultSessionConnection_->sessionId);
+ req.__set_sessionId(impl_->getDefaultSessionConnection()->sessionId);
req.__set_timeZone(zoneId);
- impl_->defaultSessionConnection_->setTimeZone(req);
+ impl_->getDefaultSessionConnection()->setTimeZone(req);
}
unique_ptr<SessionDataSet> Session::executeQueryStatement(const string& sql) {
@@ -2047,6 +2074,7 @@ unique_ptr<SessionDataSet>
Session::executeQueryStatement(const string& sql, int
void Session::Impl::handleQueryRedirection(TEndPoint endPoint) {
if (!enableRedirection_)
return;
+ getDefaultSessionConnection();
shared_ptr<SessionConnection> newConnection;
auto it = endPointToSessionConnection.find(endPoint);
if (it != endPointToSessionConnection.end()) {
@@ -2070,6 +2098,7 @@ void Session::Impl::handleRedirection(const std::string&
deviceId, TEndPoint end
return;
if (endPoint.ip == "0.0.0.0")
return;
+ getDefaultSessionConnection();
deviceIdToEndpoint[deviceId] = endPoint;
shared_ptr<SessionConnection> newConnection;
@@ -2095,6 +2124,7 @@ void Session::Impl::handleRedirection(const
std::shared_ptr<storage::IDeviceID>&
return;
if (endPoint.ip == "0.0.0.0")
return;
+ getDefaultSessionConnection();
tableModelDeviceIdToEndpoint[deviceId] = endPoint;
shared_ptr<SessionConnection> newConnection;
@@ -2127,7 +2157,7 @@ std::unique_ptr<SessionDataSet>
Session::executeQueryStatementMayRedirect(const
log_warn("Session connection redirect exception: " + e.what());
impl_->handleQueryRedirection(endpointToThrift(e.endPoint));
try {
- return impl_->defaultSessionConnection_->executeQueryStatement(sql,
timeoutInMs);
+ return impl_->getDefaultSessionConnection()->executeQueryStatement(sql,
timeoutInMs);
} catch (exception& e) {
log_error("Exception while executing redirected query statement: %s",
e.what());
throw ExecutionException(e.what());
@@ -2140,7 +2170,9 @@ std::unique_ptr<SessionDataSet>
Session::executeQueryStatementMayRedirect(const
void Session::executeNonQueryStatement(const string& sql) {
try {
- impl_->defaultSessionConnection_->executeNonQueryStatement(sql);
+ impl_->getDefaultSessionConnection()->executeNonQueryStatement(sql);
+ } catch (const IoTDBConnectionException&) {
+ throw;
} catch (const exception& e) {
throw IoTDBException(e.what());
}
@@ -2148,7 +2180,7 @@ void Session::executeNonQueryStatement(const string& sql)
{
unique_ptr<SessionDataSet> Session::executeRawDataQuery(const vector<string>&
paths,
int64_t startTime,
int64_t endTime) {
- return impl_->defaultSessionConnection_->executeRawDataQuery(paths,
startTime, endTime);
+ return impl_->getDefaultSessionConnection()->executeRawDataQuery(paths,
startTime, endTime);
}
unique_ptr<SessionDataSet> Session::executeLastDataQuery(const vector<string>&
paths) {
@@ -2157,28 +2189,28 @@ unique_ptr<SessionDataSet>
Session::executeLastDataQuery(const vector<string>& p
unique_ptr<SessionDataSet> Session::executeLastDataQuery(const vector<string>&
paths,
int64_t lastTime) {
- return impl_->defaultSessionConnection_->executeLastDataQuery(paths,
lastTime);
+ return impl_->getDefaultSessionConnection()->executeLastDataQuery(paths,
lastTime);
}
void Session::createSchemaTemplate(const Template& templ) {
TSCreateSchemaTemplateReq req;
req.__set_name(templ.getName());
req.__set_serializedTemplate(templ.serialize());
- impl_->defaultSessionConnection_->createSchemaTemplate(req);
+ impl_->getDefaultSessionConnection()->createSchemaTemplate(req);
}
void Session::setSchemaTemplate(const string& template_name, const string&
prefix_path) {
TSSetSchemaTemplateReq req;
req.__set_templateName(template_name);
req.__set_prefixPath(prefix_path);
- impl_->defaultSessionConnection_->setSchemaTemplate(req);
+ impl_->getDefaultSessionConnection()->setSchemaTemplate(req);
}
void Session::unsetSchemaTemplate(const string& prefix_path, const string&
template_name) {
TSUnsetSchemaTemplateReq req;
req.__set_templateName(template_name);
req.__set_prefixPath(prefix_path);
- impl_->defaultSessionConnection_->unsetSchemaTemplate(req);
+ impl_->getDefaultSessionConnection()->unsetSchemaTemplate(req);
}
void Session::addAlignedMeasurementsInTemplate(
@@ -2212,7 +2244,7 @@ void Session::addAlignedMeasurementsInTemplate(
}
req.__set_compressors(compressorsOrdinal);
- impl_->defaultSessionConnection_->appendSchemaTemplate(req);
+ impl_->getDefaultSessionConnection()->appendSchemaTemplate(req);
}
void Session::addAlignedMeasurementsInTemplate(const string& template_name,
@@ -2258,7 +2290,7 @@ void Session::addUnalignedMeasurementsInTemplate(
}
req.__set_compressors(compressorsOrdinal);
- impl_->defaultSessionConnection_->appendSchemaTemplate(req);
+ impl_->getDefaultSessionConnection()->appendSchemaTemplate(req);
}
void Session::addUnalignedMeasurementsInTemplate(const string& template_name,
@@ -2278,14 +2310,14 @@ void Session::deleteNodeInTemplate(const string&
template_name, const string& pa
TSPruneSchemaTemplateReq req;
req.__set_name(template_name);
req.__set_path(path);
- impl_->defaultSessionConnection_->pruneSchemaTemplate(req);
+ impl_->getDefaultSessionConnection()->pruneSchemaTemplate(req);
}
int Session::countMeasurementsInTemplate(const string& template_name) {
TSQueryTemplateReq req;
req.__set_name(template_name);
req.__set_queryType(TemplateQueryType::COUNT_MEASUREMENTS);
- TSQueryTemplateResp resp =
impl_->defaultSessionConnection_->querySchemaTemplate(req);
+ TSQueryTemplateResp resp =
impl_->getDefaultSessionConnection()->querySchemaTemplate(req);
return resp.count;
}
@@ -2294,7 +2326,7 @@ bool Session::isMeasurementInTemplate(const string&
template_name, const string&
req.__set_name(template_name);
req.__set_measurement(path);
req.__set_queryType(TemplateQueryType::IS_MEASUREMENT);
- TSQueryTemplateResp resp =
impl_->defaultSessionConnection_->querySchemaTemplate(req);
+ TSQueryTemplateResp resp =
impl_->getDefaultSessionConnection()->querySchemaTemplate(req);
return resp.result;
}
@@ -2303,7 +2335,7 @@ bool Session::isPathExistInTemplate(const string&
template_name, const string& p
req.__set_name(template_name);
req.__set_measurement(path);
req.__set_queryType(TemplateQueryType::PATH_EXIST);
- TSQueryTemplateResp resp =
impl_->defaultSessionConnection_->querySchemaTemplate(req);
+ TSQueryTemplateResp resp =
impl_->getDefaultSessionConnection()->querySchemaTemplate(req);
return resp.result;
}
@@ -2312,7 +2344,7 @@ std::vector<std::string>
Session::showMeasurementsInTemplate(const string& templ
req.__set_name(template_name);
req.__set_measurement("");
req.__set_queryType(TemplateQueryType::SHOW_MEASUREMENTS);
- TSQueryTemplateResp resp =
impl_->defaultSessionConnection_->querySchemaTemplate(req);
+ TSQueryTemplateResp resp =
impl_->getDefaultSessionConnection()->querySchemaTemplate(req);
return resp.measurements;
}
@@ -2322,7 +2354,7 @@ std::vector<std::string>
Session::showMeasurementsInTemplate(const string& templ
req.__set_name(template_name);
req.__set_measurement(pattern);
req.__set_queryType(TemplateQueryType::SHOW_MEASUREMENTS);
- TSQueryTemplateResp resp =
impl_->defaultSessionConnection_->querySchemaTemplate(req);
+ TSQueryTemplateResp resp =
impl_->getDefaultSessionConnection()->querySchemaTemplate(req);
return resp.measurements;
}
diff --git a/iotdb-client/client-cpp/src/session/SessionC.cpp
b/iotdb-client/client-cpp/src/session/SessionC.cpp
index 7d86bd348f8..79287cf0252 100644
--- a/iotdb-client/client-cpp/src/session/SessionC.cpp
+++ b/iotdb-client/client-cpp/src/session/SessionC.cpp
@@ -26,11 +26,12 @@
#include "SessionDataSet.h"
#include <cstring>
-#include <string>
-#include <vector>
#include <map>
-#include <unordered_map>
#include <memory>
+#include <stdexcept>
+#include <string>
+#include <unordered_map>
+#include <vector>
/* ============================================================
* Internal wrapper structs — the opaque handles point to these
@@ -87,6 +88,10 @@ static TsStatus handleException(const std::exception& e) {
dynamic_cast<const BatchExecutionException*>(&e)) {
return setError(TS_ERR_EXECUTION, e);
}
+ if (dynamic_cast<const std::out_of_range*>(&e) ||
+ dynamic_cast<const std::invalid_argument*>(&e)) {
+ return setError(TS_ERR_INVALID_PARAM, e);
+ }
#endif
return setError(TS_ERR_UNKNOWN, e);
}
@@ -678,7 +683,10 @@ TsStatus ts_tablet_set_row_count(CTablet* tablet, int
rowCount) {
clearError();
if (!tablet)
return setError(TS_ERR_NULL_PTR, "tablet is null");
- tablet->cpp.rowSize = rowCount;
+ if (rowCount < 0 || static_cast<size_t>(rowCount) >
tablet->cpp.maxRowNumber) {
+ return setError(TS_ERR_INVALID_PARAM, "rowCount out of range [0,
maxRowNumber]");
+ }
+ tablet->cpp.rowSize = static_cast<size_t>(rowCount);
return TS_OK;
}
diff --git a/iotdb-client/client-cpp/test/cpp/sessionCIT.cpp
b/iotdb-client/client-cpp/test/cpp/sessionCIT.cpp
index 9db5361635d..0e0791c5d29 100644
--- a/iotdb-client/client-cpp/test/cpp/sessionCIT.cpp
+++ b/iotdb-client/client-cpp/test/cpp/sessionCIT.cpp
@@ -497,6 +497,27 @@ TEST_CASE("C API - Tablet row count and reset",
"[c_tabletReset]") {
ts_tablet_destroy(tablet);
}
+TEST_CASE("C API - Tablet index bounds", "[c_tabletBounds]") {
+ CaseReporter cr("c_tabletBounds");
+ const char* colNames[] = {"s1"};
+ TSDataType_C dts[] = {TS_TYPE_INT64};
+ CTablet* tablet = ts_tablet_new("root.ctest.d1", 1, colNames, dts, 10);
+ REQUIRE(tablet != nullptr);
+
+ REQUIRE(ts_tablet_add_timestamp(tablet, 0, 1) == TS_OK);
+ REQUIRE(ts_tablet_add_value_int64(tablet, 0, 0, 100) == TS_OK);
+ REQUIRE(ts_tablet_add_timestamp(tablet, 100, 2) != TS_OK);
+ REQUIRE(ts_tablet_add_value_int64(tablet, 1, 0, 100) != TS_OK);
+ REQUIRE(ts_tablet_add_value_int64(tablet, 0, 100, 100) != TS_OK);
+ REQUIRE(ts_tablet_set_row_count(tablet, -1) != TS_OK);
+ REQUIRE(ts_tablet_set_row_count(tablet, 11) != TS_OK);
+ REQUIRE(ts_tablet_set_row_count(tablet, 1000000) != TS_OK);
+ REQUIRE(ts_tablet_set_row_count(tablet, 5) == TS_OK);
+ REQUIRE(ts_tablet_get_row_count(tablet) == 5);
+
+ ts_tablet_destroy(tablet);
+}
+
TEST_CASE("C API - Aligned timeseries and aligned writes", "[c_aligned]") {
CaseReporter cr("c_aligned");
diff --git a/iotdb-client/client-cpp/test/cpp/sessionCRelationalIT.cpp
b/iotdb-client/client-cpp/test/cpp/sessionCRelationalIT.cpp
index 9a78f2512ed..4a298dd1c1a 100644
--- a/iotdb-client/client-cpp/test/cpp/sessionCRelationalIT.cpp
+++ b/iotdb-client/client-cpp/test/cpp/sessionCRelationalIT.cpp
@@ -254,6 +254,19 @@ TEST_CASE("C API Table - Multi-node table session",
"[c_table_multiNode][c_table
ts_table_session_destroy(localSession);
}
+TEST_CASE("C API Table - Reject SQL after close",
"[c_table_close][c_table_lifecycle]") {
+ CaseReporter cr("c_table_close");
+
+ CTableSession* localSession = ts_table_session_new("127.0.0.1", 6667,
"root", "root", "");
+ REQUIRE(localSession != nullptr);
+ REQUIRE(ts_table_session_open(localSession) == TS_OK);
+
+ ts_table_session_close(localSession);
+
+ REQUIRE(ts_table_session_execute_non_query(localSession, "SHOW DATABASES")
!= TS_OK);
+ ts_table_session_destroy(localSession);
+}
+
/* ============================================================
* Dataset column info (table model)
* ============================================================ */
diff --git a/iotdb-client/client-cpp/test/cpp/sessionIT.cpp
b/iotdb-client/client-cpp/test/cpp/sessionIT.cpp
index c0428f6e84a..3b19f2e2b25 100644
--- a/iotdb-client/client-cpp/test/cpp/sessionIT.cpp
+++ b/iotdb-client/client-cpp/test/cpp/sessionIT.cpp
@@ -28,6 +28,7 @@
#include "common_types.h"
#include <atomic>
+#include <stdexcept>
#include <thread>
using namespace std;
@@ -369,6 +370,30 @@ TEST_CASE("Test insertRecordsOfOneDevice",
"[testInsertRecordsOfOneDevice]") {
REQUIRE(count == 100);
}
+TEST_CASE("Tablet index bounds", "[tabletBounds]") {
+ CaseReporter cr("tabletBounds");
+ vector<pair<string, TSDataType::TSDataType>> schemaList;
+ schemaList.emplace_back("s1", TSDataType::INT64);
+ Tablet tablet("root.test.d1", schemaList, 10);
+ tablet.addTimestamp(0, 1);
+ tablet.addValue(0, 0, static_cast<int64_t>(100));
+
+ REQUIRE_THROWS_AS(tablet.addTimestamp(10, 11), out_of_range);
+ REQUIRE_THROWS_AS(tablet.addValue(1, 0, static_cast<int64_t>(1)),
out_of_range);
+ REQUIRE_THROWS_AS(tablet.addValue(0, 100, static_cast<int64_t>(1)),
out_of_range);
+}
+
+TEST_CASE("Session rejects SQL after close", "[sessionClose]") {
+ CaseReporter cr("sessionClose");
+ SessionBuilder builder;
+ auto localSession =
+
builder.host("127.0.0.1")->rpcPort(6667)->username("root")->password("root")->build();
+ localSession->open();
+ localSession->close();
+ REQUIRE_THROWS_AS(localSession->executeNonQueryStatement("show databases"),
+ IoTDBConnectionException);
+}
+
TEST_CASE("Test insertTablet ", "[testInsertTablet]") {
CaseReporter cr("testInsertTablet");
prepareTimeseries();
diff --git a/iotdb-client/client-cpp/test/cpp/sessionRelationalIT.cpp
b/iotdb-client/client-cpp/test/cpp/sessionRelationalIT.cpp
index 461a3ec8630..9ed3d334b1c 100644
--- a/iotdb-client/client-cpp/test/cpp/sessionRelationalIT.cpp
+++ b/iotdb-client/client-cpp/test/cpp/sessionRelationalIT.cpp
@@ -86,6 +86,19 @@ TEST_CASE("Test TableSession builder with nodeUrls",
"[SessionBuilderInit]") {
session->close();
}
+TEST_CASE("TableSession rejects SQL after close", "[tableSessionClose]") {
+ CaseReporter cr("tableSessionClose");
+
+ TableSessionBuilder builder;
+ auto localSession =
+
builder.host("127.0.0.1")->rpcPort(6667)->username("root")->password("root")->build();
+ localSession->open();
+ localSession->close();
+
+ REQUIRE_THROWS_AS(localSession->executeNonQueryStatement("SHOW DATABASES"),
+ IoTDBConnectionException);
+}
+
TEST_CASE("Test insertRelationalTablet", "[testInsertRelationalTablet]") {
CaseReporter cr("testInsertRelationalTablet");
session->executeNonQueryStatement("CREATE DATABASE IF NOT EXISTS db1");