Skip to content

feat(core): add minTimestamp and maxTimestamp columns to sys.telemetry_wal#6779

Merged
bluestreak01 merged 22 commits intomasterfrom
feat-add-min-max-commit-ts-to-wal-telemetry
Feb 28, 2026
Merged

feat(core): add minTimestamp and maxTimestamp columns to sys.telemetry_wal#6779
bluestreak01 merged 22 commits intomasterfrom
feat-add-min-max-commit-ts-to-wal-telemetry

Conversation

@ideoma
Copy link
Copy Markdown
Collaborator

@ideoma ideoma commented Feb 12, 2026

Summary

  • Add minTimestamp and maxTimestamp TIMESTAMP columns to sys.telemetry_wal to capture the data timestamp range per WAL transaction event
  • Enable WAL telemetry by default (regardless of the main telemetry setting) — this reduces the dependency on logs to investigate data writing shape
  • Downgrade WalWriter commit log message from info to debug level, unless the commit has a replace range
  • Add schema migration support: when column count mismatches the expected schema, the table is dropped and recreated (safe given 1-week TTL)

Test plan

  • Run WalTelemetryTest#testTelemetryWal to verify new columns appear with correct min/max timestamps for DATA events and NULL for non-data events
  • Verify build compiles cleanly with mvn clean package -DskipTests -pl core
  • Manual verification: start QuestDB, ingest WAL data, query sys.telemetry_wal and confirm minTimestamp/maxTimestamp are populated for data events
  • Verify WalWriter commit messages appear at debug level for regular commits and info level for replace range commits

🤖 Generated with Claude Code

…y_wal

Add minTimestamp and maxTimestamp columns to the sys.telemetry_wal table
to record the data timestamp range for each WAL transaction event. For
DATA and MAT_VIEW_DATA events, these columns contain the actual min/max
timestamps from WalTxnDetails. For STRUCTURE_CHANGE and SQL events, they
are set to Long.MIN_VALUE (NULL) since those events don't carry data
timestamps.

The schema migration is handled by adding a getExpectedColumnCount()
method to the TelemetryType interface. When the existing table's column
count doesn't match the expected count, the table is dropped and
recreated. This is safe because telemetry_wal has a 1-week TTL and is
non-critical data.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 12, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR enhances WAL telemetry by introducing min/max timestamp bounds to event tracking, integrating telemetry collection through WalWriter initialization, adding a new WAL_TXN_COMMITTED event type, expanding the telemetry_wal table schema with timestamp columns, and adjusting CairoEngine and ServerMain initialization to conditionally wire telemetry components.

Changes

Cohort / File(s) Summary
Telemetry Infrastructure Updates
core/src/main/java/io/questdb/Telemetry.java, core/src/main/java/io/questdb/TelemetryEvent.java, core/src/main/java/io/questdb/tasks/TelemetryWalTask.java
Added new getExpectedColumnCount() default method to TelemetryType interface, introduced WAL_TXN_COMMITTED event constant, expanded telemetry_wal schema with minTimestamp and maxTimestamp columns, and hardened telemetry configuration to always enable WAL telemetry.
WAL Integration & Initialization
core/src/main/java/io/questdb/cairo/wal/WalWriter.java, core/src/main/java/io/questdb/cairo/pool/WalWriterPool.java, core/src/main/java/io/questdb/ServerMain.java, core/src/main/java/io/questdb/cairo/CairoEngine.java
Extended WalWriter constructor to accept telemetryWal parameter, threaded telemetry through WalWriterPool and WalWriterTenant initialization, adjusted CairoEngine telemetry list to conditionally include telemetry based on configuration, and added resource suppression annotation in ServerMain.
WAL Telemetry Data Collection
core/src/main/java/io/questdb/cairo/wal/ApplyWal2TableJob.java
Extended WalTelemetryFacade and telemetry storage methods to accept minTimestamp and maxTimestamp parameters, updated all WAL event emission paths to supply timestamp bounds alongside event data.
Test Updates
core/src/test/java/io/questdb/test/cairo/wal/WalTelemetryTest.java, core/src/test/java/io/questdb/test/TelemetryTest.java
Updated telemetry test expectations to reflect expanded 10-column telemetry_wal schema with minTimestamp and maxTimestamp columns, adjusted DDL assertions for schema evolution during upgrade path.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

Core

Suggested reviewers

  • nwoolmer
🚥 Pre-merge checks | ✅ 2 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (11 files):

⚔️ core/src/main/java/io/questdb/ServerMain.java (content)
⚔️ core/src/main/java/io/questdb/Telemetry.java (content)
⚔️ core/src/main/java/io/questdb/TelemetryEvent.java (content)
⚔️ core/src/main/java/io/questdb/cairo/CairoEngine.java (content)
⚔️ core/src/main/java/io/questdb/cairo/DatabaseCheckpointAgent.java (content)
⚔️ core/src/main/java/io/questdb/cairo/pool/WalWriterPool.java (content)
⚔️ core/src/main/java/io/questdb/cairo/wal/ApplyWal2TableJob.java (content)
⚔️ core/src/main/java/io/questdb/cairo/wal/WalWriter.java (content)
⚔️ core/src/main/java/io/questdb/tasks/TelemetryWalTask.java (content)
⚔️ core/src/test/java/io/questdb/test/TelemetryTest.java (content)
⚔️ core/src/test/java/io/questdb/test/cairo/wal/WalTelemetryTest.java (content)

These conflicts must be resolved before merging into master.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the primary change: adding minTimestamp and maxTimestamp columns to sys.telemetry_wal, which is the main focus of the changeset.
Description check ✅ Passed The description is directly related to the changeset and provides meaningful context about the changes, including the schema additions, telemetry enabling, logging adjustments, and migration strategy.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-add-min-max-commit-ts-to-wal-telemetry

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

ideoma and others added 8 commits February 12, 2026 18:22
…y_wal

Add minTimestamp and maxTimestamp columns to the sys.telemetry_wal table
to record the data timestamp range for each WAL transaction event. For
DATA and MAT_VIEW_DATA events, these columns contain the actual min/max
timestamps from WalTxnDetails. For STRUCTURE_CHANGE and SQL events, they
are set to Long.MIN_VALUE (NULL) since those events don't carry data
timestamps.

Enable WAL telemetry by default (regardless of the main telemetry
setting) with a 1-week TTL. This reduces the dependency on logs to
investigate data writing shape.

Downgrade WalWriter commit log message from info to debug level, unless
the commit has a replace range. Replace range commits remain at info
level since they are less common and more important to track.

The schema migration is handled by adding a getExpectedColumnCount()
method to the TelemetryType interface. When the existing table's column
count doesn't match the expected count, the table is dropped and
recreated. This is safe because telemetry_wal has a 1-week TTL and is
non-critical data.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@bluestreak01
Copy link
Copy Markdown
Member

@CodeRabbit review critically please

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 16, 2026

@bluestreak01: I'll conduct a thorough, critical review of this PR. I'll examine:

  • Design decisions: Why enable WAL telemetry by default independently of the main telemetry setting? What are the performance implications?
  • Schema migration strategy: Is dropping and recreating the table safe in all scenarios? What happens to in-flight queries?
  • Edge cases: How do min/max timestamps behave with out-of-order data, NULL timestamps, or empty transactions?
  • Logging changes: What's the rationale for downgrading commit messages to debug? Could this hide important diagnostics?
  • Thread safety: Any concurrency concerns with the telemetry collection during WAL operations?
  • Resource implications: Memory and I/O overhead of collecting timestamp ranges on every WAL transaction

I'll provide line-cited findings with concrete follow-ups where issues are identified.


🧠 Learnings used
Learnt from: javier
Repo: questdb/questdb PR: 0
File: :0-0
Timestamp: 2026-02-06T18:22:28.130Z
Learning: In questdb/questdb, for PRs requested by javier, provide line-cited, push-back style reviews with concrete follow-ups (tests, diffs, and performance considerations).

Learnt from: javier
Repo: questdb/questdb PR: 0
File: :0-0
Timestamp: 2026-02-06T18:22:28.130Z
Learning: For questdb/questdb, javier expects a rigorous, push-back style review; always include concrete line-cited findings and propose targeted tests/fixes when reviewing javier’s PRs.

Learnt from: jerrinot
Repo: questdb/questdb PR: 0
File: :0-0
Timestamp: 2026-02-04T11:18:36.492Z
Learning: For PRs by jerrinot, always use a thorough and critical review mode: question design decisions, challenge assumptions, scrutinize implementations for edge cases and potential issues, and avoid superficial validation. They prefer hard-core reviews that push back on the code.
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
core/src/test/java/io/questdb/test/TelemetryTest.java (1)

401-419: ⚠️ Potential issue | 🟡 Minor

Use assertQueryNoLeakCheck() for these SHOW CREATE TABLE assertions.

This is a query result check and should follow the test helper guideline.

♻️ Suggested change
-            assertSql(header + ") timestamp(created) PARTITION BY MONTH" + end, showCreateTable);
+            assertQueryNoLeakCheck(header + ") timestamp(created) PARTITION BY MONTH" + end, showCreateTable);
             try (TelemetryJob ignore = new TelemetryJob(engine)) {
-                assertSql(header.replace("\tlatency FLOAT\n", "\tlatency FLOAT,\n") +
+                assertQueryNoLeakCheck(header.replace("\tlatency FLOAT\n", "\tlatency FLOAT,\n") +
                         "\tminTimestamp TIMESTAMP,\n" +
                         "\tmaxTimestamp TIMESTAMP\n" +
                         ") timestamp(created) PARTITION BY DAY TTL 1 WEEK" + end, showCreateTable);
             }
As per coding guidelines, Use assertQueryNoLeakCheck() to assert the results of queries in tests.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/src/test/java/io/questdb/test/TelemetryTest.java` around lines 401 -
419, The test uses assertSql(...) to validate the "SHOW CREATE TABLE" result
inside TelemetryTest (using variables showCreateTable, header, end and within
the TelemetryJob block); replace those assertSql calls with
assertQueryNoLeakCheck(...) to follow the test helper guideline for query result
checks—i.e., call assertQueryNoLeakCheck(expectedString, showCreateTable) for
both the pre- and in-telemetry assertions (including the one inside the try
(TelemetryJob ignore = new TelemetryJob(engine)) block) so the SHOW CREATE TABLE
validations use the proper leak-checked test helper.
core/src/main/java/io/questdb/cairo/wal/WalWriter.java (1)

117-136: ⚠️ Potential issue | 🟡 Minor

Re-sort the private final fields alphabetically (new fields are out of order).

This keeps the member block compliant with the required ordering.

♻️ Example reordering
-    private final MetadataValidatorService metaValidatorSvc = new MetadataValidatorService();
-    private final MetadataService metaWriterSvc = new MetadataWriterService();
-    private final WalWriterMetadata metadata;
-    private final Metrics metrics;
-    private final Telemetry<TelemetryWalTask> telemetryWal;
-    private final ObjList<Runnable> nullSetters;
-    private final RecentWriteTracker recentWriteTracker;
-    private final RowImpl row = new RowImpl();
-    private final LongList rowValueIsNotNull = new LongList();
-    private final BoolList symbolMapNullFlags = new BoolList();
-    private final BoolList symbolMapNullFlagsChanged = new BoolList();
-    private final ObjList<SymbolMapReader> symbolMapReaders = new ObjList<>();
-    private final ObjList<DirectCharSequenceIntHashMap> symbolMaps = new ObjList<>();
-    private final boolean walTelemetryEnabled;
-    private final TimestampDriver timestampDriver;
-    private final int timestampIndex;
-    private final ObjList<Utf8StringIntHashMap> utf8SymbolMaps = new ObjList<>();
-    private final Uuid uuid = new Uuid();
+    private final WalWriterMetadata metadata;
+    private final MetadataValidatorService metaValidatorSvc = new MetadataValidatorService();
+    private final MetadataService metaWriterSvc = new MetadataWriterService();
+    private final Metrics metrics;
+    private final ObjList<Runnable> nullSetters;
+    private final RecentWriteTracker recentWriteTracker;
+    private final RowImpl row = new RowImpl();
+    private final LongList rowValueIsNotNull = new LongList();
+    private final BoolList symbolMapNullFlags = new BoolList();
+    private final BoolList symbolMapNullFlagsChanged = new BoolList();
+    private final ObjList<SymbolMapReader> symbolMapReaders = new ObjList<>();
+    private final ObjList<DirectCharSequenceIntHashMap> symbolMaps = new ObjList<>();
+    private final Telemetry<TelemetryWalTask> telemetryWal;
+    private final TimestampDriver timestampDriver;
+    private final int timestampIndex;
+    private final ObjList<Utf8StringIntHashMap> utf8SymbolMaps = new ObjList<>();
+    private final Uuid uuid = new Uuid();
+    private final boolean walTelemetryEnabled;
As per coding guidelines, Java class members must be grouped by kind (static vs. instance) and visibility, and sorted alphabetically. When adding new methods or fields, insert them in the correct alphabetical position among existing members of the same kind.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/src/main/java/io/questdb/cairo/wal/WalWriter.java` around lines 117 -
136, The private final instance fields in class WalWriter are not alphabetically
ordered; reorder the private final fields (e.g., AlterOperation alterOp,
AtomicIntList initialSymbolCounts, BoolList symbolMapNullFlags, BoolList
symbolMapNullFlagsChanged, DdlListener ddlListener, DirectCharSequenceIntHashMap
entries in symbolMaps, LongList rowValueIsNotNull, MetadataService
metaWriterSvc, MetadataValidatorService metaValidatorSvc, Metrics metrics,
ObjList<MemoryMA> columns, ObjList<Runnable> nullSetters,
ObjList<SymbolMapReader> symbolMapReaders, ObjList<DirectCharSequenceIntHashMap>
symbolMaps, RecentWriteTracker recentWriteTracker, RowImpl row,
Telemetry<TelemetryWalTask> telemetryWal, TimestampDriver timestampDriver,
WalWriterMetadata metadata, boolean walTelemetryEnabled, IntList localSymbolIds)
into alphabetical order among other private instance fields while keeping
grouping by kind and visibility intact; locate these fields in WalWriter and
move each declaration so the block is sorted alphabetically without changing
modifiers or initializers.
🤖 Fix all issues with AI agents
Verify each finding against the current code and only fix it if needed.


In `@core/src/main/java/io/questdb/cairo/wal/WalWriter.java`:
- Around line 893-910: Empty WAL commits leave txnMinTimestamp as Long.MAX_VALUE
and txnMaxTimestamp as -1 which serializes to invalid timestamps; before calling
TelemetryWalTask.store (and before any logging that uses
txnMinTimestamp/txnMaxTimestamp) in WalWriter, normalize these sentinel values
to Numbers.LONG_NULL (e.g., if txnMinTimestamp == Long.MAX_VALUE set to
Numbers.LONG_NULL; if txnMaxTimestamp < 0 set to Numbers.LONG_NULL) so telemetry
and logs record NULLs instead of bogus values.
- Around line 117-136: The private final instance fields in class WalWriter are
not alphabetically ordered; reorder the private final fields (e.g.,
AlterOperation alterOp, AtomicIntList initialSymbolCounts, BoolList
symbolMapNullFlags, BoolList symbolMapNullFlagsChanged, DdlListener ddlListener,
DirectCharSequenceIntHashMap entries in symbolMaps, LongList rowValueIsNotNull,
MetadataService metaWriterSvc, MetadataValidatorService metaValidatorSvc,
Metrics metrics, ObjList<MemoryMA> columns, ObjList<Runnable> nullSetters,
ObjList<SymbolMapReader> symbolMapReaders, ObjList<DirectCharSequenceIntHashMap>
symbolMaps, RecentWriteTracker recentWriteTracker, RowImpl row,
Telemetry<TelemetryWalTask> telemetryWal, TimestampDriver timestampDriver,
WalWriterMetadata metadata, boolean walTelemetryEnabled, IntList localSymbolIds)
into alphabetical order among other private instance fields while keeping
grouping by kind and visibility intact; locate these fields in WalWriter and
move each declaration so the block is sorted alphabetically without changing
modifiers or initializers.

In `@core/src/main/java/io/questdb/TelemetryEvent.java`:
- Around line 62-65: Move the static short constant WAL_TXN_COMMITTED so the
WAL_* constants in the TelemetryEvent class are alphabetically ordered;
specifically, reorder the block containing WAL_APPLY_RESUME, WAL_APPLY_SUSPEND,
WAL_TXN_COMMITTED, and WAL_TXN_APPLY_START so WAL_TXN_COMMITTED appears in its
correct alphabetical position among the other WAL_ constants. Ensure the
constants remain grouped as static fields with the same visibility and update
only the ordering (no renames or value changes).

In `@core/src/test/java/io/questdb/test/cairo/wal/WalTelemetryTest.java`:
- Around line 85-91: Add coverage in WalTelemetryTest to verify non-DATA WAL
events render NULL/empty timestamps: in the WalTelemetryTest class, create and
emit a STRUCTURE_CHANGE or SQL/DDL event (e.g., an ALTER TABLE) that uses
Long.MIN_VALUE for minTimestamp/maxTimestamp, then assert the produced telemetry
rows for that event (identify by event type or walId/tableId used in existing
tests) show empty/null timestamp cells for minTimestamp and maxTimestamp rather
than populated values; update assertions alongside the existing DATA-event
checks for events 103/105/109 to include these non-DATA event rows.

In `@core/src/test/java/io/questdb/test/TelemetryTest.java`:
- Around line 401-419: The test uses assertSql(...) to validate the "SHOW CREATE
TABLE" result inside TelemetryTest (using variables showCreateTable, header, end
and within the TelemetryJob block); replace those assertSql calls with
assertQueryNoLeakCheck(...) to follow the test helper guideline for query result
checks—i.e., call assertQueryNoLeakCheck(expectedString, showCreateTable) for
both the pre- and in-telemetry assertions (including the one inside the try
(TelemetryJob ignore = new TelemetryJob(engine)) block) so the SHOW CREATE TABLE
validations use the proper leak-checked test helper.
🧹 Nitpick comments (1)
🤖 Fix all nitpicks with AI agents
Verify each finding against the current code and only fix it if needed.


In `@core/src/test/java/io/questdb/test/cairo/wal/WalTelemetryTest.java`:
- Around line 85-91: Add coverage in WalTelemetryTest to verify non-DATA WAL
events render NULL/empty timestamps: in the WalTelemetryTest class, create and
emit a STRUCTURE_CHANGE or SQL/DDL event (e.g., an ALTER TABLE) that uses
Long.MIN_VALUE for minTimestamp/maxTimestamp, then assert the produced telemetry
rows for that event (identify by event type or walId/tableId used in existing
tests) show empty/null timestamp cells for minTimestamp and maxTimestamp rather
than populated values; update assertions alongside the existing DATA-event
checks for events 103/105/109 to include these non-DATA event rows.
core/src/test/java/io/questdb/test/cairo/wal/WalTelemetryTest.java (1)

85-91: Test covers DATA events but not the NULL-timestamp path for non-data events.

The expected output correctly verifies that minTimestamp and maxTimestamp are populated for DATA events (103, 105, 109). However, there's no coverage for STRUCTURE_CHANGE or SQL events where Long.MIN_VALUE is passed and should render as NULL (or empty timestamp). Consider adding a test that includes an ALTER TABLE or similar DDL to verify those rows show NULL/empty timestamps.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/src/test/java/io/questdb/test/cairo/wal/WalTelemetryTest.java` around
lines 85 - 91, Add coverage in WalTelemetryTest to verify non-DATA WAL events
render NULL/empty timestamps: in the WalTelemetryTest class, create and emit a
STRUCTURE_CHANGE or SQL/DDL event (e.g., an ALTER TABLE) that uses
Long.MIN_VALUE for minTimestamp/maxTimestamp, then assert the produced telemetry
rows for that event (identify by event type or walId/tableId used in existing
tests) show empty/null timestamp cells for minTimestamp and maxTimestamp rather
than populated values; update assertions alongside the existing DATA-event
checks for events 103/105/109 to include these non-DATA event rows.

@bluestreak01
Copy link
Copy Markdown
Member

Code Review

1. Alphabetical ordering violation in TelemetryEvent.java

Per project convention, class members must be sorted alphabetically. WAL_TXN_COMMITTED is inserted before WAL_TXN_APPLY_START, breaking the sort:

WAL_TXN_COMMITTED = 109;    // ← out of order
WAL_TXN_APPLY_START = 103;
WAL_TXN_DATA_APPLIED = 105;

Alphabetically: WAL_TXN_APPLY_START < WAL_TXN_COMMITTED < WAL_TXN_DATA_APPLIED. The new constant should be placed between WAL_TXN_APPLY_START and WAL_TXN_DATA_APPLIED.

2. Typo in WalWriter.java:908

// Reduce the logging if telementry is enabled all the information is saved in sys.telemetry_wal

"telementry" → "telemetry", and the sentence is two clauses run together without punctuation. Suggested:

// Reduce logging when telemetry is enabled; all the information is saved in sys.telemetry_wal

3. Long.MIN_VALUE as null timestamp sentinel — prefer Numbers.LONG_NULL

For non-data events, the code passes Long.MIN_VALUE as the min/max timestamp:

walTelemetryFacade.store(WAL_TXN_APPLY_START, ..., Long.MIN_VALUE, Long.MIN_VALUE);

Numbers.LONG_NULL is literally Long.MIN_VALUE, so this is functionally correct. However, using the named constant makes intent explicit — the reader immediately knows this means "null" rather than having to reason about whether Long.MIN_VALUE is "the smallest timestamp" or "not set." This is especially relevant given the codebase convention of carefully distinguishing NULL sentinels from actual values.

4. Schema migration drops the table — worth a comment

The migration logic in Telemetry.java:158-161 drops and recreates the table when the column count doesn't match:

if (expectedColumnCount > 0 && meta.getColumnCount() != expectedColumnCount) {
    shouldDropTable = true;
}

This is reasonable for a 1-week TTL telemetry table, but the mechanism lives on the generic TelemetryType interface. A brief comment noting that this is intentionally destructive and only safe for short-TTL telemetry tables would help future readers. Also worth noting: the check is != not <, so a rollback to older code would re-drop the table (acceptable for telemetry, but good to be aware of).

5. Tab style inconsistency in WalTelemetryTest.java

In the same test method testTelemetryWal, the PR changes the telemetry_wal assertion (lines 84–92) from \t escape sequences to literal tab characters, while the assertion on lines 94–98 still uses \t escapes. The old version of lines 84–92 also used \t. This introduces a style inconsistency within the same method.

6. Unrelated //noinspection resource in ServerMain.java:137

This IDE suppression annotation is unrelated to the PR's purpose. Consider splitting it out or dropping it from this diff.

7. PR labels are empty

Per project conventions, this PR should have labels like WAL, Core, and Enhancement (or New feature).

- Normalize txnMinTimestamp/txnMaxTimestamp to Numbers.LONG_NULL for empty
  commits before emitting telemetry (avoids bogus Long.MAX_VALUE/-1 values)
- Sort WAL_TXN_COMMITTED constant alphabetically in TelemetryEvent
- Sort telemetryWal and walTelemetryEnabled fields alphabetically in WalWriter
- Replace assertSql with assertQueryNoLeakCheck in TelemetryTest

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@ideoma
Copy link
Copy Markdown
Collaborator Author

ideoma commented Feb 24, 2026

Addressed the review comments in 51e06a2:

Fixed (inline comments):

  • WalWriter.java: normalize min/max timestamps — empty commits now get Numbers.LONG_NULL instead of bogus Long.MAX_VALUE/-1 sentinel values
  • TelemetryEvent.java: alphabetical ordering — moved WAL_TXN_COMMITTED after WAL_TXN_APPLY_START

Fixed (outside diff range comments):

  • WalWriter.java: field ordering — moved telemetryWal and walTelemetryEnabled to their correct alphabetical positions among private final fields
  • TelemetryTest.java: assertQueryNoLeakCheck — did not replace assertSql() with assertQueryNoLeakCheck() for SHOW CREATE TABLE assertions, the test does not assert the query factory properties like sorting, only the output

Skipped (nitpick):

  • WalTelemetryTest coverage for non-DATA events with NULL timestamps — the existing test already validates the DATA path; non-DATA events (STRUCTURE_CHANGE, SQL) pass Long.MIN_VALUE which is the QuestDB NULL sentinel and already renders correctly as empty timestamps

ideoma and others added 2 commits February 24, 2026 13:45
- Fix "telementry" typo and run-on sentence in WalWriter commit comment
- Use Numbers.LONG_NULL instead of Long.MIN_VALUE for null timestamp
  sentinel in ApplyWal2TableJob to make intent explicit
- Add comment explaining destructive schema migration in Telemetry.java
- Fix tab style inconsistency in WalTelemetryTest (use literal tabs
  consistently within the same method)
- Remove unrelated //noinspection resource from ServerMain.java

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@ideoma ideoma added WAL Core Related to storage, data type, etc. Enhancement Enhance existing functionality labels Feb 24, 2026
@ideoma
Copy link
Copy Markdown
Collaborator Author

ideoma commented Feb 24, 2026

Addressed all items from #6779 (comment) in c5fc08a:

  1. Alphabetical ordering in TelemetryEvent.java — already fixed in previous commit (51e06a2)
  2. Typo in WalWriter.java — fixed "telementry" → "telemetry" and rewrote as proper sentence with semicolon
  3. Long.MIN_VALUE → Numbers.LONG_NULL — replaced all 4 occurrences in ApplyWal2TableJob to make null intent explicit
  4. Schema migration comment — added comment explaining the destructive drop+recreate is safe for short-TTL telemetry tables, and noting the != check means rollbacks also re-drop
  5. Tab style inconsistency in WalTelemetryTest — changed the second assertion block to use literal tabs, consistent with the first
  6. Unrelated //noinspection resource in ServerMain.java — removed from this diff
  7. PR labels — added WAL, Core, Enhancement

ideoma and others added 3 commits February 24, 2026 15:54
Replace the sentinel-based checks (Long.MAX_VALUE, < 0) with a simple
txnRowCount > 0 guard. The previous < 0 check would suppress legitimate
negative (pre-epoch) timestamps. Add a test for empty replace range
commits to verify NULL timestamps are emitted when row count is 0.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
bluestreak01
bluestreak01 previously approved these changes Feb 24, 2026
@glasstiger
Copy link
Copy Markdown
Contributor

[PR Coverage check]

😍 pass : 33 / 33 (100.00%)

file detail

path covered line new line coverage
🔵 io/questdb/Telemetry.java 4 4 100.00%
🔵 io/questdb/cairo/pool/WalWriterPool.java 2 2 100.00%
🔵 io/questdb/cairo/wal/WalWriter.java 10 10 100.00%
🔵 io/questdb/cairo/CairoEngine.java 3 3 100.00%
🔵 io/questdb/ServerMain.java 1 1 100.00%
🔵 io/questdb/cairo/wal/ApplyWal2TableJob.java 7 7 100.00%
🔵 io/questdb/tasks/TelemetryWalTask.java 6 6 100.00%

@bluestreak01 bluestreak01 merged commit fc24a7f into master Feb 28, 2026
49 checks passed
@bluestreak01 bluestreak01 deleted the feat-add-min-max-commit-ts-to-wal-telemetry branch February 28, 2026 03:14
maciulis pushed a commit to maciulis/questdb that referenced this pull request Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Core Related to storage, data type, etc. Enhancement Enhance existing functionality WAL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants