Skip to content

Commit e15cef8

Browse files
committed
cpp client datatype OBJECT
1 parent 8763d57 commit e15cef8

7 files changed

Lines changed: 93 additions & 11 deletions

File tree

iotdb-client/client-cpp/src/main/Common.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ TSDataType::TSDataType getDataTypeByStr(const std::string& typeStr) {
8989
if (typeStr == "DATE") return TSDataType::DATE;
9090
if (typeStr == "BLOB") return TSDataType::BLOB;
9191
if (typeStr == "STRING") return TSDataType::STRING;
92+
if (typeStr == "OBJECT") return TSDataType::OBJECT;
9293
return TSDataType::UNKNOWN;
9394
}
9495

iotdb-client/client-cpp/src/main/Common.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ enum TSDataType {
9595
TIMESTAMP = (char)8,
9696
DATE = (char)9,
9797
BLOB = (char)10,
98-
STRING = (char)11
98+
STRING = (char)11,
99+
OBJECT = (char)12
99100
};
100101
}
101102

iotdb-client/client-cpp/src/main/IoTDBRpcDataSet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ std::string IoTDBRpcDataSet::getStringByTsBlockColumnIndexAndDataType(int32_t in
448448
return std::to_string(curTsBlock_->getColumn(index)->getDouble(tsBlockIndex_));
449449
case TSDataType::TEXT:
450450
case TSDataType::STRING:
451+
case TSDataType::OBJECT:
451452
case TSDataType::BLOB: {
452453
auto binary = curTsBlock_->getColumn(index)->getBinary(tsBlockIndex_);
453454
return binary->getStringValue();

iotdb-client/client-cpp/src/main/Session.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ TSDataType::TSDataType getTSDataTypeFromString(const string& str) {
5959
return TSDataType::BLOB;
6060
} else if (str == "STRING") {
6161
return TSDataType::STRING;
62+
} else if (str == "OBJECT") {
63+
return TSDataType::OBJECT;
6264
}
6365
return TSDataType::UNKNOWN;
6466
}
@@ -88,6 +90,7 @@ void Tablet::createColumns() {
8890
break;
8991
case TSDataType::STRING:
9092
case TSDataType::BLOB:
93+
case TSDataType::OBJECT:
9194
case TSDataType::TEXT:
9295
values[i] = new string[maxRowNumber];
9396
break;
@@ -135,6 +138,7 @@ void Tablet::deleteColumns() {
135138
}
136139
case TSDataType::STRING:
137140
case TSDataType::BLOB:
141+
case TSDataType::OBJECT:
138142
case TSDataType::TEXT: {
139143
string* valueBuf = (string*)(values[i]);
140144
delete[] valueBuf;
@@ -182,6 +186,7 @@ void Tablet::deepCopyTabletColValue(void* const* srcPtr, void** destPtr, TSDataT
182186
}
183187
case TSDataType::STRING:
184188
case TSDataType::TEXT:
189+
case TSDataType::OBJECT:
185190
case TSDataType::BLOB: {
186191
*destPtr = new std::string[maxRowNumber];
187192
std::string* srcStr = static_cast<std::string*>(src);
@@ -232,6 +237,7 @@ size_t Tablet::getValueByteSize() {
232237
break;
233238
case TSDataType::STRING:
234239
case TSDataType::BLOB:
240+
case TSDataType::OBJECT:
235241
case TSDataType::TEXT: {
236242
valueOccupation += rowSize * 4;
237243
string* valueBuf = (string*)(values[i]);
@@ -361,6 +367,7 @@ string SessionUtils::getValue(const Tablet& tablet) {
361367
}
362368
case TSDataType::STRING:
363369
case TSDataType::BLOB:
370+
case TSDataType::OBJECT:
364371
case TSDataType::TEXT: {
365372
string* valueBuf = (string*)(tablet.values[i]);
366373
for (size_t index = 0; index < tablet.rowSize; index++) {
@@ -582,6 +589,7 @@ void Session::sortTablet(Tablet& tablet) {
582589
}
583590
case TSDataType::STRING:
584591
case TSDataType::BLOB:
592+
case TSDataType::OBJECT:
585593
case TSDataType::TEXT: {
586594
sortValuesList((string*)(tablet.values[i]), index, tablet.rowSize);
587595
break;
@@ -654,6 +662,7 @@ Session::putValuesIntoBuffer(const vector<TSDataType::TSDataType>& types, const
654662
break;
655663
case TSDataType::STRING:
656664
case TSDataType::BLOB:
665+
case TSDataType::OBJECT:
657666
case TSDataType::TEXT: {
658667
int32_t len = (uint32_t)strlen(values[i]);
659668
appendValues(buf, (char*)(&len), sizeof(uint32_t));
@@ -689,6 +698,8 @@ int8_t Session::getDataTypeNumber(TSDataType::TSDataType type) {
689698
return 10;
690699
case TSDataType::STRING:
691700
return 11;
701+
case TSDataType::OBJECT:
702+
return 12;
692703
default:
693704
return -1;
694705
}
@@ -1295,16 +1306,20 @@ void Session::buildInsertTabletReq(TSInsertTabletReq& request, Tablet& tablet, b
12951306
sortTablet(tablet);
12961307
}
12971308

1298-
request.prefixPath = tablet.deviceId;
1309+
request.__set_prefixPath(tablet.deviceId);
12991310

1300-
request.measurements.reserve(tablet.schemas.size());
1301-
request.types.reserve(tablet.schemas.size());
1311+
std::vector<std::string> reqMeasurements;
1312+
reqMeasurements.reserve(tablet.schemas.size());
1313+
std::vector<int32_t> types;
1314+
types.reserve(tablet.schemas.size());
13021315
for (pair<string, TSDataType::TSDataType> schema : tablet.schemas) {
1303-
request.measurements.push_back(schema.first);
1304-
request.types.push_back(schema.second);
1316+
reqMeasurements.push_back(schema.first);
1317+
types.push_back(schema.second);
13051318
}
1306-
request.values = move(SessionUtils::getValue(tablet));
1307-
request.timestamps = move(SessionUtils::getTime(tablet));
1319+
request.__set_measurements(reqMeasurements);
1320+
request.__set_types(types);
1321+
request.__set_values(SessionUtils::getValue(tablet));
1322+
request.__set_timestamps(SessionUtils::getTime(tablet));
13081323
request.__set_size(tablet.rowSize);
13091324
request.__set_isAligned(tablet.isAligned);
13101325
}
@@ -1389,6 +1404,7 @@ void Session::insertRelationalTablet(Tablet& tablet, bool sorted) {
13891404
}
13901405
case TSDataType::STRING:
13911406
case TSDataType::TEXT:
1407+
case TSDataType::OBJECT:
13921408
case TSDataType::BLOB: {
13931409
currentTablet.addValue(tablet.schemas[col].first, rowIndex,
13941410
*(string*)tablet.getValue(col, row, tablet.schemas[col].second));

iotdb-client/client-cpp/src/main/Session.h

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,59 @@ class Tablet {
322322
}
323323
}
324324

325+
// Add a Binary value with extra metadata: [isEOF (1 byte)] + [offset (8 bytes)] + [actual content]
326+
void addValue(size_t schemaId, size_t rowIndex, bool isEOF, int64_t offset, const std::vector<uint8_t>& content) {
327+
// Check schemaId bounds
328+
if (schemaId >= schemas.size()) {
329+
char tmpStr[100];
330+
sprintf(tmpStr,
331+
"Tablet::addBinaryValueWithMeta(), schemaId >= schemas.size(). schemaId=%ld, schemas.size()=%ld.",
332+
schemaId, schemas.size());
333+
throw std::out_of_range(tmpStr);
334+
}
335+
336+
// Check rowIndex bounds
337+
if (rowIndex >= rowSize) {
338+
char tmpStr[100];
339+
sprintf(tmpStr, "Tablet::addBinaryValueWithMeta(), rowIndex >= rowSize. rowIndex=%ld, rowSize=%ld.",
340+
rowIndex, rowSize);
341+
throw std::out_of_range(tmpStr);
342+
}
343+
344+
// Validate data type: must be TEXT, STRING, or BLOB
345+
TSDataType::TSDataType dataType = schemas[schemaId].second;
346+
if (dataType != TSDataType::OBJECT) {
347+
throw std::invalid_argument("The data type of schemaId " + std::to_string(schemaId) + " is not OBJECT.");
348+
}
349+
350+
// Create a byte array of size [1 (isEOF) + 8 (offset) + content size]
351+
std::vector<uint8_t> val(content.size() + 9);
352+
353+
// Write the isEOF flag (1 byte)
354+
val[0] = isEOF ? 1 : 0;
355+
356+
// Write the 8-byte offset in big-endian order
357+
for (int i = 0; i < 8; ++i) {
358+
val[1 + i] = static_cast<uint8_t>((offset >> (56 - i * 8)) & 0xFF);
359+
}
360+
361+
// Append the content bytes
362+
std::copy(content.begin(), content.end(), val.begin() + 9);
363+
364+
// Cast the value array and assign the Binary data (stored as string)
365+
std::string valEncoded = std::string(reinterpret_cast<char*>(val.data()), val.size());
366+
safe_cast<string, string>(valEncoded, ((string*)values[schemaId])[rowIndex]);
367+
}
368+
369+
void addValue(const string& schemaName, size_t rowIndex, bool isEOF, int64_t offset,
370+
const std::vector<uint8_t>& content) {
371+
if (schemaNameIndex.find(schemaName) == schemaNameIndex.end()) {
372+
throw SchemaNotFoundException(string("Schema ") + schemaName + " not found.");
373+
}
374+
size_t schemaId = schemaNameIndex[schemaName];
375+
addValue(schemaId, rowIndex, isEOF, offset, content);
376+
}
377+
325378
template <typename T>
326379
void addValue(const string& schemaName, size_t rowIndex, const T& value) {
327380
if (schemaNameIndex.find(schemaName) == schemaNameIndex.end()) {
@@ -331,7 +384,6 @@ class Tablet {
331384
addValue(schemaId, rowIndex, value);
332385
}
333386

334-
335387
void* getValue(size_t schemaId, size_t rowIndex, TSDataType::TSDataType dataType) {
336388
if (schemaId >= schemas.size()) {
337389
throw std::out_of_range("Tablet::getValue schemaId out of range: "
@@ -358,6 +410,7 @@ class Tablet {
358410
return &(reinterpret_cast<double*>(values[schemaId])[rowIndex]);
359411
case TSDataType::BLOB:
360412
case TSDataType::STRING:
413+
case TSDataType::OBJECT:
361414
case TSDataType::TEXT:
362415
return &(reinterpret_cast<std::string*>(values[schemaId])[rowIndex]);
363416
default:

iotdb-client/client-cpp/src/main/SessionDataSet.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ std::string RowRecord::toString() {
9898
break;
9999
case TSDataType::BLOB:
100100
case TSDataType::STRING:
101+
case TSDataType::OBJECT:
101102
case TSDataType::TEXT:
102103
if (!fields[i].stringV.is_initialized()) {
103104
ret.append("null");
@@ -268,6 +269,7 @@ shared_ptr<RowRecord> SessionDataSet::constructRowRecordFromValueArray() {
268269
case TSDataType::TEXT:
269270
case TSDataType::BLOB:
270271
case TSDataType::STRING:
272+
case TSDataType::OBJECT:
271273
field.stringV = iotdbRpcDataSet_->getBinary(columnName)->getStringValue();
272274
break;
273275
default:

iotdb-client/client-cpp/src/test/cpp/sessionRelationalIT.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ TEST_CASE("Test RelationalTabletTsblockRead", "[testRelationalTabletTsblockRead]
135135
"field7 TIMESTAMP field,"
136136
"field8 DATE field,"
137137
"field9 BLOB field,"
138-
"field10 STRING field)");
138+
"field10 STRING field,"
139+
"field11 OBJECT field)");
139140

140141
vector<pair<string, TSDataType::TSDataType>> schemaList;
141142
schemaList.push_back(make_pair("field1", TSDataType::BOOLEAN));
@@ -148,8 +149,9 @@ TEST_CASE("Test RelationalTabletTsblockRead", "[testRelationalTabletTsblockRead]
148149
schemaList.push_back(make_pair("field8", TSDataType::DATE));
149150
schemaList.push_back(make_pair("field9", TSDataType::BLOB));
150151
schemaList.push_back(make_pair("field10", TSDataType::STRING));
152+
schemaList.push_back(make_pair("field11", TSDataType::OBJECT));
151153

152-
vector<ColumnCategory> columnTypes(10, ColumnCategory::FIELD);
154+
vector<ColumnCategory> columnTypes(11, ColumnCategory::FIELD);
153155

154156
int64_t timestamp = 0;
155157
int maxRowNumber = 50000;
@@ -168,6 +170,9 @@ TEST_CASE("Test RelationalTabletTsblockRead", "[testRelationalTabletTsblockRead]
168170
tablet.addValue(7, rowIndex, boost::gregorian::date(2025, 5, 15));
169171
tablet.addValue(8, rowIndex, "blob_" + to_string(row));
170172
tablet.addValue(9, rowIndex, "string_" + to_string(row));
173+
vector<uint8_t> rawData = {0x01, 0x02, 0x03, 0x04};
174+
// always non-null
175+
tablet.addValue(10, rowIndex, true, 0, rawData);
171176

172177
if (row % 2 == 0) {
173178
for (int col = 0; col <= 9; col++) {
@@ -203,6 +208,7 @@ TEST_CASE("Test RelationalTabletTsblockRead", "[testRelationalTabletTsblockRead]
203208
REQUIRE_FALSE(dataIter.getDateByIndex(9).is_initialized());
204209
REQUIRE_FALSE(dataIter.getStringByIndex(10).is_initialized());
205210
REQUIRE_FALSE(dataIter.getStringByIndex(11).is_initialized());
211+
REQUIRE_FALSE(!dataIter.getStringByIndex(12).is_initialized());
206212
} else {
207213
REQUIRE(dataIter.getLongByIndex(1).value() == timestamp + rowNum);
208214
REQUIRE(dataIter.getBooleanByIndex(2).value() == (rowNum % 2 == 0));
@@ -215,6 +221,8 @@ TEST_CASE("Test RelationalTabletTsblockRead", "[testRelationalTabletTsblockRead]
215221
REQUIRE(dataIter.getDateByIndex(9).value() == boost::gregorian::date(2025, 5, 15));
216222
REQUIRE(dataIter.getStringByIndex(10).value() == "blob_" + to_string(rowNum));
217223
REQUIRE(dataIter.getStringByIndex(11).value() == "string_" + to_string(rowNum));
224+
// [isEOF (1 byte)] + [offset (8 bytes)] + [content (4 bytes)]
225+
REQUIRE(dataIter.getStringByIndex(12).value() != "");
218226
}
219227
rowNum++;
220228
}

0 commit comments

Comments
 (0)