Skip to content

[core] Validate STRING ts field for merge_map_with_keytime at DDL - #10221

Open
LuciferYang wants to merge 2 commits into
apache:masterfrom
LuciferYang:m/core-046-map-key-time-agg
Open

LuciferYang wants to merge 2 commits into
apache:masterfrom
LuciferYang:m/core-046-map-key-time-agg

Conversation

@LuciferYang

@LuciferYang LuciferYang commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Purpose

The merge_map_with_keytime aggregator reads the per-key timestamp field with getString and compares values lexicographically, so a STRING ts field is the documented contract. The type was never validated, so a ROW whose ts field is TIMESTAMP, INT, or any non-string type was accepted, and at merge time getString reinterprets the raw bytes, silently retaining the wrong map entry on a key collision.

This validates the ts field type at DDL only. SchemaValidation now resolves the ts field the same way the aggregator does (the explicitly configured fields.<f>.ts-field, else the default last field of the map value ROW) and requires it to be VARCHAR or CHAR, throwing IllegalArgumentException naming the field. The check runs at CREATE/ALTER validation, not when the merge function is built, so a bad new schema is rejected up front while an already-created table is still readable (its rows can be read for migration rather than the table failing to open). The factory no longer performs a build-time type check.

Tests

SchemaValidationTest.testMergeMapWithKeyTimeRejectsNonStringTsFieldAtDdl pins that DDL validation rejects a merge_map_with_keytime schema whose ts field is TIMESTAMP, and whose explicitly configured ts-field points at an INT column, while a STRING ts field is accepted.

FieldAggregatorTest.testFieldMergeMapWithKeyTimeAggBuildIgnoresTsFieldType pins that building the aggregator no longer throws for a non-string ts field, so opening an existing table does not fail.

API and Format

No.

Documentation

No.

The aggregate reads the ts field with getString and compares values
lexicographically, but nothing checked the field type: a ROW whose ts
field is TIMESTAMP (or INT, or anything non-string) is accepted and the
raw bits are interpreted as a string — BinaryRow reads an unrelated
offset/length as the value — so the wrong map entry is retained with
no error. The documented contract says each key carries a string
timestamp and the implementation reads this field as a string.

Reject the schema in the factory when the resolved ts field (explicit
or the default last field) is not STRING.

Assisted-by: GLM-5.3
@LuciferYang
LuciferYang marked this pull request as draft September 27, 2026 03:04
@LuciferYang
LuciferYang marked this pull request as ready for review September 27, 2026 04:24
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.

1 participant