Skip to content

Support OBJECT data type in tablet write - #175

Merged
JackieTien97 merged 3 commits into
mainfrom
support-object-tablet
Aug 21, 2026
Merged

Support OBJECT data type in tablet write#175
JackieTien97 merged 3 commits into
mainfrom
support-object-tablet

Conversation

@shuwenwei

Copy link
Copy Markdown
Member

Description

Adds support for the OBJECT data type (TSDataType 12) in the table-model tablet write path of the Go client, following the Java TableSession / tsfile implementation.

Write path

  • Add OBJECT to the TSDataType enum and the string/byte type maps (client/protocol.go)
  • Treat OBJECT as a binary column (same as BLOB) in Tablet (client/tablet.go): value storage, SetValueAt/GetValueAt, Swap, getValuesBytes, NewTablet
  • Add Tablet.SetObjectValueAt(isEOF, offset, content, columnIndex, rowIndex) for segmented OBJECT writes: each segment is wrapped with a 1-byte isEOF flag + 8-byte big-endian offset, matching Java Tablet.addValue(rowIndex, columnIndex, isEOF, offset, content)

Read path

  • Decode OBJECT (and BLOB/STRING) binary columns in BinaryArrayColumnDecoder, and handle OBJECT like BLOB in IoTDBRpcDataSet getters, so written objects can be read back (e.g. select READ_OBJECT(file) + GetBlob)

Tests

  • Unit tests: TestTablet_OBJECT (whole-object write), TestTablet_SetObjectValueAt (segmented write) in client/tablet_test.go
  • E2E table test: Test_InsertObjectTablet in test/e2e/e2e_table_test.go, covering whole-object, segmented (512B), and null-object rows, verified via READ_OBJECT/GetBlob, count(*), null check, and tag/field round-trip

Also includes the regenerated thrift common code (new aggregation types, pipeRecentFailureList field) produced by make all.

Verification

  • go build ./... / go test ./client/... pass
  • E2E suite requires Docker (make e2e_test)

Add support for the OBJECT data type (TSDataType 12) in the table model
tablet write path, following the Java TableSession/tsfile implementation:

- Add OBJECT to the TSDataType enum and the string/byte type maps
- Treat OBJECT as a binary column (like BLOB) in Tablet: value storage,
  SetValueAt/GetValueAt, Swap, getValuesBytes and NewTablet
- Add Tablet.SetObjectValueAt for segmented OBJECT writes, wrapping each
  segment with a 1-byte isEOF flag and an 8-byte big-endian offset,
  matching Java Tablet.addValue(rowIndex, columnIndex, isEOF, offset, content)
- Decode OBJECT (and BLOB/STRING) binary columns in the read path so
  written objects can be read back (e.g. via READ_OBJECT)
- Add unit tests for whole-object and segmented OBJECT tablet writes
- Add an e2e table test writing OBJECT via tablet, covering whole-object,
  segmented and null-object rows

Also include the regenerated thrift common code (new aggregation types,
pipeRecentFailureList field) from `make all`.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds OBJECT tablet write/read support, including segmented object uploads and protocol decoding.

Changes:

  • Adds OBJECT type handling across tablet serialization and query decoding.
  • Introduces segmented OBJECT writes with tests.
  • Regenerates thrift common types and fields.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
client/protocol.go Defines OBJECT type mappings.
client/tablet.go Adds OBJECT storage, serialization, and segmented writes.
client/tablet_test.go Tests OBJECT tablet behavior.
client/column_decoder.go Decodes binary OBJECT columns.
client/rpcdataset.go Supports OBJECT result getters.
test/e2e/e2e_table_test.go Adds OBJECT write/read integration coverage.
common/common.go Updates generated thrift definitions.
Files not reviewed (1)
  • common/common.go: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread common/common.go
Comment on lines +6854 to +6855
_src38 := _src37[k]
if _tgt != _src38 { return false }
@shuwenwei
shuwenwei force-pushed the support-object-tablet branch from f08f709 to c3bf6b4 Compare August 20, 2026 10:31

@JackieTien97 JackieTien97 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The segmented OBJECT write envelope matches the Java implementation and passed live round-trip testing against TimechoDB. However, the public OBJECT read/write semantics and null-bitmap handling still have reproducible correctness issues, and the unrelated generated Thrift changes should be removed from this PR. Please address the inline comments before merging.

Comment thread client/rpcdataset.go Outdated
return binary.GetStringValue(), nil
}
case BLOB:
case BLOB, OBJECT:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Decode OBJECT results with OBJECT semantics

Grouping OBJECT with BLOB exposes server-side OBJECT metadata instead of the public object representation. In a live TimechoDB test, SELECT file returned an OBJECT payload whose first eight bytes are the object size and whose remaining bytes contain the internal object path; this branch makes GetObject return those raw bytes, while the matching GetString branch hex-encodes them. The Java client uses BytesUtils.parseObjectByteArrayToString(...) for both getters (for example, (Object) 1.00 KB) and rejects getBlob for OBJECT. Please split OBJECT from BLOB, implement the same formatter/getter contract, add direct SELECT file tests, and add the corresponding database/sql column mapping so a non-null OBJECT is not silently returned as nil.

Comment thread client/tablet.go Outdated
return fmt.Errorf("illegal argument value %v %v", value, reflect.TypeOf(value))
}
case TEXT, STRING:
case TEXT, STRING, OBJECT:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Do not accept unframed OBJECT payloads here

For TableSession OBJECT writes, the server interprets every value as a segment envelope: one EOF byte, an eight-byte big-endian offset, then content. This branch accepts an arbitrary string or []byte and serializes it without that envelope; a live insertion of a string accepted here failed with status 741 because the server interpreted the string bytes as the offset. Please remove OBJECT from this generic branch and have SetObjectValueAt assign through an internal framed-value helper, or expose a separate, clearly documented API if another valid pre-encoded/object-path representation is required. The unit test should not assert that raw "hello" is a valid TableSession OBJECT value.

Comment thread client/tablet.go Outdated
}
binary.BigEndian.PutUint64(value[1:9], uint64(offset))
copy(value[9:], content)
return t.SetValueAt(value, columnIndex, rowIndex)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Clear a previously marked NULL bit before storing the segment

SetValueAt(nil, ...) marks this cell in the bitmap, but the non-nil path never unmarks it. Consequently, calling SetValueAt(nil, ...) and then SetObjectValueAt(...) for the same cell still writes a NULL row; this was reproducible against TimechoDB. The equivalent Java overload calls updateBitMap(rowIndex, columnIndex, false). Please clear the bit for non-nil assignments (ideally in the shared SetValueAt path) and add a regression test for overwriting NULL with an OBJECT value.

Comment thread common/common.go
TAggregationType_SKEWNESS TAggregationType = 38
TAggregationType_KURTOSIS TAggregationType = 39
TAggregationType_PERCENTILE TAggregationType = 40
TAggregationType_RATE TAggregationType = 41

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Keep unrelated generated protocol updates out of this OBJECT PR

These aggregation constants and the pipeRecentFailureList additions are generated from a newer IoTDB protocol and are unrelated to OBJECT tablet support. Bundling them expands the public Thrift/protocol surface, creates version drift, and also brings in the correctness issue already reported in the Equals implementation below. Please revert common/common.go from this PR and submit any pinned, reviewed IDL regeneration as a separate change.

@JackieTien97
JackieTien97 merged commit 013e3d3 into main Aug 21, 2026
7 checks passed
@JackieTien97
JackieTien97 deleted the support-object-tablet branch August 21, 2026 00:54
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.

3 participants