Skip to content

Fix C++ client time column access returning NULL for non-long types (#17397)#17400

Open
PDGGK wants to merge 1 commit intoapache:masterfrom
PDGGK:fix/cpp-client-boolean-first-column
Open

Fix C++ client time column access returning NULL for non-long types (#17397)#17400
PDGGK wants to merge 1 commit intoapache:masterfrom
PDGGK:fix/cpp-client-boolean-first-column

Conversation

@PDGGK
Copy link
Copy Markdown
Contributor

@PDGGK PDGGK commented Mar 30, 2026

Description

Fixes #17397

Several ByTsBlockColumnIndex getter methods in IoTDBRpcDataSet.cpp did not handle the tsBlockColumnIndex < 0 case (time pseudo-column in tree model), causing undefined behavior when the time column was accessed through typed getters other than getLong or getString.

In tree model, column index 1 maps to tsBlockColumnIndex = -1 (the time column). When a user calls getBooleanByIndex(1), this flows to getBooleanByTsBlockColumnIndex(-1), which calls curTsBlock_->getColumn(-1) — an out-of-bounds std::vector access (UB in C++).

Only getLongByTsBlockColumnIndex and getStringByTsBlockColumnIndex correctly handled the < 0 case. The following five methods were missing the guard:

Method Fix
getBooleanByTsBlockColumnIndex Throw IoTDBException (boolean from timestamp is nonsensical)
getDoubleByTsBlockColumnIndex Return timestamp cast to double
getFloatByTsBlockColumnIndex Return timestamp cast to float
getIntByTsBlockColumnIndex Return timestamp cast to int32_t
getBinaryByTsBlockColumnIndex Return timestamp as Binary string

Design Discussion

For the numeric types (int, float, double), I chose to return the timestamp value (cast to the target type) to stay consistent with getLongByTsBlockColumnIndex which already returns the timestamp. However, an alternative approach would be to throw IoTDBException for all non-long/non-string types, since:

  • static_cast<int32_t>(timestamp) silently truncates 64-bit timestamps
  • Accessing a time column as float or boolean is likely a user error

I'd appreciate the maintainers' preference on which approach is better. Happy to change if throwing is preferred.

Note

The Java client (IoTDBRpcDataSet.java) has the same asymmetry — only getLong and getString handle tsBlockColumnIndex < 0. The other typed getters (getBoolean, getInt, getFloat, getDouble, getBinary) will throw IndexOutOfBoundsException in Java. This could be addressed as a follow-up.

…pache#17397)

Several ByTsBlockColumnIndex methods in IoTDBRpcDataSet did not handle
the tsBlockColumnIndex < 0 case (time column), causing undefined
behavior when accessing the time column as boolean, double, float,
int, or binary. Only getLong and getString handled this correctly.

Add tsBlockColumnIndex < 0 checks to:
- getBooleanByTsBlockColumnIndex: throw IoTDBException (boolean from
  timestamp is nonsensical)
- getDoubleByTsBlockColumnIndex: return timestamp cast to double
- getFloatByTsBlockColumnIndex: return timestamp cast to float
- getIntByTsBlockColumnIndex: return timestamp cast to int32_t
- getBinaryByTsBlockColumnIndex: return timestamp as Binary string

Signed-off-by: Zihan Dai <1436286758@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] [version:2.0.7]使用C++ API时,如果SQL语句中第一个列类型是boolen类型则无法正确获取值,值为NULL

1 participant