Repository navigation
[Feature] Support TAG value filtering for table subscriptions - #18639
Merged
Merged
Conversation
jt2594838
reviewed
Oct 14, 2026
Preserve subscription configuration tests and bilingual message additions. Reuse the existing table-cache version API and adapt subscription tests to topic metadata and model-specific lookups.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Table subscriptions can select databases, tables, and output columns, but they cannot filter individual rows by TAG value. This PR adds the
tag-filtertopic attribute for table-model subscriptions. Its default value istrue, so existing topics keep their current behavior.Filter semantics
AND,OR,NOT,=,!=,IN,LIKE,REGEXP, andIS NULL, evaluated with SQL three-valued logic.column-filterprojection."as""and each outer SQL'as''. The Subscription Session API accepts the raw expression.Delivery paths and configuration changes
TagFilterStatusandTagFilterMessageto table-modelSHOW TOPICS. The status reportsMATCH_ALL,MATCH_NONE,ACTIVE, orERRORfor the DataNode executing the statement; the message contains the local matcher failure when the status isERROR. Tree-model output remains unchanged.Validation
TagFilterParserTest,TopicStatementTest, andColumnFilterParserTest), covering single/consecutive/mixed quotes, CREATE/ALTER formatting, and SHOW CREATE round trips.ShowTopicsTaskTest,TabletTagFilterTest, andSubscriptionTopicAgentTest).TopicConfigTest: 10 tests passed.mvn test-compile -pl iotdb-core/datanode -P with-zh-locale -DskipTests).git diff --check: passed.Performance comparison
Benchmarked commit
5e9f4c07cd7with the subscription feature gate enabled in the test build; the TAG filtering implementation was unchanged.iot-benchmarkgenerated a fixed table with 1,000,000 rows, 200 devices, 10 random DOUBLE fields, and one uniformly distributed TAG (tag_0, 10 values). All columns were retained.Snapshot subscriptions; one warm-up and three measured runs per case, with shuffled order. The table reports medians. Consumption time runs from the start of
subscribe()until all expected field cells are delivered and the last data batch is acknowledged. Topic creation, the later automatic snapshot-termination notification, and subsequent TsFile content verification are excluded. Input throughput uses all 1,000,000 source rows for every case.true)tag_0 IS NOT NULL(100%)tag_0 IN ("value_0", "value_1", "value_2", "value_3", "value_4")(50%)tag_0 = "value_0"(10%)true)tag_0 IS NOT NULL(100%)tag_0 IN ("value_0", "value_1", "value_2", "value_3", "value_4")(50%)tag_0 = "value_0"(10%)true)tag_0 IS NOT NULL(100%)tag_0 IN ("value_0", "value_1", "value_2", "value_3", "value_4")(50%)tag_0 = "value_0"(10%)All 32 runs (including warm-ups) passed TAG-value, per-field row completeness, and duplicate-cell verification. Expected outputs were 1,000,000, 1,000,000, 500,000, and 100,000 logical rows with all 10 fields. Column-split Tablet/TsFile payloads were verified by device, timestamp, and field. TsFile contents were read after the measured delivery interval.
Single-device matching (2026-10-20)
Added
device_id = "d_0", selecting exactly one of the 200 devices: 5,000 logical rows and 50,000 non-null field cells (0.5% of the source rows), with all 10 fields retained.This additional experiment uses the same test build at commit
5e9f4c07cd7, with the subscription feature gate enabled, and a copy of the original flushed data verified by SHA-256. It does not measure the current PR HEAD. All five selections were rerun for both formats, with one warm-up and three measured runs per case. Timing and input-throughput definitions are the same as above; the no-filter values below come from this rerun, independently of the earlier table.Environment: Intel Core i7-11700 (8 cores / 16 threads), 31 GiB RAM, Java 17.0.9; one ConfigNode and one DataNode with 1 GiB and 6 GiB heaps, respectively; consumer heap 512 MiB–2 GiB.
device_id = "d_0"device_id = "d_0"Tablet/Record consumption time decreased by 84.0% relative to its no-filter median in this rerun. TsFile took 2.58× its no-filter median and delivered 5 files (0.013 MiB), compared with one forwarded source file without filtering. Even this small selection still incurs TsFile parsing, filtering, rewriting, and delivery overhead.
All 40/40 runs passed exact device/timestamp/field coverage and duplicate-cell verification, including all 8/8 single-device runs (both formats, warm-ups and measured runs). Each single-device run delivered only
d_0, all 5,000 timestamps, and all 10 fields. TsFile content verification remained outside the measured interval.This PR has:
Key changed/added classes (or packages if there are too many classes) in this PR
org.apache.iotdb.db.subscription.tagfilterSubscriptionFilterSnapshotSubscriptionTreeViewProjectorSubscriptionBrokerAgentConsensusLogToTabletConverterPipeTabletEventTsFileBatchShowTopicsTaskTopicConfigandTopicMeta