Skip to content

fix(sql): fix parquet export bug when SQL contains now() function#6499

Merged
bluestreak01 merged 2 commits intomasterfrom
export_parquet_now_bug
Dec 5, 2025
Merged

fix(sql): fix parquet export bug when SQL contains now() function#6499
bluestreak01 merged 2 commits intomasterfrom
export_parquet_now_bug

Conversation

@kafka1991
Copy link
Copy Markdown
Collaborator

@kafka1991 kafka1991 commented Dec 4, 2025

When exporting a query that contains the now() function to Parquet, the now() value was not initialized before query execution, leading to incorrect export results.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 4, 2025

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.

Walkthrough

The change captures and propagates the current timestamp context (now and nowTimestampType) through the Parquet export pipeline, from initial query processing to downstream execution context setup. Two new fields are added to CopyExportRequestTask with corresponding accessors, and the values are threaded through ExportQueryProcessor, CopyExportRequestJob, and CopyExportFactory to SerialParquetExporter, where the SQL execution context is updated with the captured timestamp.

Changes

Cohort / File(s) Summary
Task model updates
core/src/main/java/io/questdb/cutlass/parquet/CopyExportRequestTask.java
Added two private fields (long now, int nowTimestampType), public accessors (getNow(), getNowTimestampType()), and expanded the of(...) method signature to accept and populate these new timestamp parameters.
Export pipeline threading
core/src/main/java/io/questdb/cutlass/http/processors/ExportQueryProcessor.java, core/src/main/java/io/questdb/cutlass/parquet/CopyExportRequestJob.java, core/src/main/java/io/questdb/griffin/engine/ops/CopyExportFactory.java
Updated call sites to CopyExportRequestTask.of(...) to pass computed nowTimestampType and now values extracted from execution context or task state.
Exporter context setup
core/src/main/java/io/questdb/cutlass/parquet/SerialParquetExporter.java
Added call to sqlExecutionContext.setNowAndFixClock(task.getNow(), task.getNowTimestampType()) in process() method to apply captured timestamp context to SQL execution.
Test coverage
core/src/test/java/io/questdb/test/cutlass/http/ExpParquetExportTest.java, core/src/test/java/io/questdb/test/griffin/CopyExportTest.java
Added test methods (testExportWithNowParameter, testCopyWithNowParameter) that verify Parquet export behavior with fixed timestamp context and time-based filtering predicates.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

  • Changes follow a consistent, homogeneous pattern across all production files (straightforward parameter threading with minimal logic)
  • No error handling modifications or control-flow alterations
  • Test additions are straightforward functional validation

Possibly related PRs

  • questdb#6420: Modifies SerialParquetExporter.process() to restructure empty-partition handling, affecting the same export flow where this PR introduces timestamp context setup.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.88% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(sql): fix parquet export bug when SQL contains now() function' clearly and concisely describes the main change: fixing a parquet export bug related to the now() function.
Description check ✅ Passed The description is directly related to the changeset, explaining that the now() function was not initialized during parquet export, which is the core issue addressed by all the code changes.

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.

@kafka1991 kafka1991 changed the title fix(sql): fix incorrect result when use now() function in parquet export fix(sql): fix parquet export bug when SQL contains now() function Dec 4, 2025
@bluestreak01
Copy link
Copy Markdown
Member

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 4, 2025

✅ 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: 0

🧹 Nitpick comments (1)
core/src/main/java/io/questdb/cutlass/parquet/CopyExportRequestTask.java (1)

43-45: Task-level now context wiring is consistent; consider clearing in clear()

The added now/nowTimestampType fields, their getters, and the extended of(...) signature cleanly carry timestamp context through the export pipeline and are used consistently by all shown call sites (ExportQueryProcessor, CopyExportFactory, CopyExportRequestJob, SerialParquetExporter).

One small robustness improvement would be to reset now and nowTimestampType in clear(), alongside the other fields, so that a reused instance can’t accidentally expose stale values if someone ever accesses these getters before calling of(...):

 public void clear() {
     this.entry = null;
     this.tableName = null;
     this.fileName = null;
     this.compressionCodec = -1;
     this.compressionLevel = -1;
     this.dataPageSize = -1;
     this.parquetVersion = -1;
     this.rowGroupSize = -1;
     this.statisticsEnabled = true;
+    this.now = 0;
+    this.nowTimestampType = 0;
     this.createOp = Misc.free(createOp);
     result = null;
 }

Also applies to: 99-106, 135-150, 163-165

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7896064 and 6926245.

📒 Files selected for processing (7)
  • core/src/main/java/io/questdb/cutlass/http/processors/ExportQueryProcessor.java (2 hunks)
  • core/src/main/java/io/questdb/cutlass/parquet/CopyExportRequestJob.java (1 hunks)
  • core/src/main/java/io/questdb/cutlass/parquet/CopyExportRequestTask.java (4 hunks)
  • core/src/main/java/io/questdb/cutlass/parquet/SerialParquetExporter.java (1 hunks)
  • core/src/main/java/io/questdb/griffin/engine/ops/CopyExportFactory.java (2 hunks)
  • core/src/test/java/io/questdb/test/cutlass/http/ExpParquetExportTest.java (2 hunks)
  • core/src/test/java/io/questdb/test/griffin/CopyExportTest.java (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
core/src/test/java/io/questdb/test/griffin/CopyExportTest.java (1)
core/src/main/java/io/questdb/cairo/MicrosTimestampDriver.java (1)
  • MicrosTimestampDriver (69-1609)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (35)
  • GitHub Check: New pull request (Coverage Report Coverage Report)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-other)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-pgwire)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-cairo-sub)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-cairo-root)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-fuzz2)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-fuzz1)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-griffin-sub)
  • GitHub Check: New pull request (SelfHosted Running tests with cover on linux-griffin-root)
  • GitHub Check: New pull request (Rust Test and Lint on linux-jdk17)
  • GitHub Check: New pull request (Hosted Running tests on windows-other-2)
  • GitHub Check: New pull request (Hosted Running tests on windows-other-1)
  • GitHub Check: New pull request (Hosted Running tests on windows-pgwire)
  • GitHub Check: New pull request (Hosted Running tests on windows-cairo-2)
  • GitHub Check: New pull request (Hosted Running tests on windows-cairo-1)
  • GitHub Check: New pull request (Hosted Running tests on windows-fuzz2)
  • GitHub Check: New pull request (Hosted Running tests on windows-fuzz1)
  • GitHub Check: New pull request (Hosted Running tests on windows-griffin-sub)
  • GitHub Check: New pull request (Hosted Running tests on windows-griffin-base)
  • GitHub Check: New pull request (Hosted Running tests on mac-other)
  • GitHub Check: New pull request (Hosted Running tests on mac-pgwire)
  • GitHub Check: New pull request (Hosted Running tests on mac-cairo-fuzz)
  • GitHub Check: New pull request (Hosted Running tests on mac-cairo)
  • GitHub Check: New pull request (SelfHosted Griffin tests on linux-x86-graal)
  • GitHub Check: New pull request (SelfHosted Griffin tests on linux-x64-zfs)
  • GitHub Check: New pull request (Hosted Running tests on mac-griffin)
  • GitHub Check: New pull request (Trigger Enterprise CI Trigger Enterprise Pipeline)
  • GitHub Check: New pull request (SelfHosted Other tests on linux-x64-zfs)
  • GitHub Check: New pull request (SelfHosted Cairo tests on linux-x64-zfs)
  • GitHub Check: New pull request (SelfHosted Griffin tests on linux-arm64)
  • GitHub Check: New pull request (SelfHosted Cairo tests on linux-x86-graal)
  • GitHub Check: New pull request (SelfHosted Other tests on linux-arm64)
  • GitHub Check: New pull request (SelfHosted Other tests on linux-x86-graal)
  • GitHub Check: New pull request (SelfHosted Cairo tests on linux-arm64)
  • GitHub Check: New pull request (Check Changes Check changes)
🔇 Additional comments (6)
core/src/main/java/io/questdb/cutlass/parquet/SerialParquetExporter.java (1)

103-110: Seeding exporter SqlExecutionContext with captured now looks correct

Calling sqlExecutionContext.setNowAndFixClock(task.getNow(), task.getNowTimestampType()) before any SQL work in process() correctly aligns now() evaluation in the exporter with the value captured upstream in the task. This directly addresses the bug around uninitialised or drifting now() during Parquet export.

core/src/test/java/io/questdb/test/cutlass/http/ExpParquetExportTest.java (1)

30-30: HTTP /exp now()-based Parquet export test is well integrated

The added testExportWithNowParameter plus the ColumnType import give good coverage that /exp Parquet exports respect a fixed now() (via microsecond clock + setNowAndFixClock) when filtering on ts < now(). The pattern matches existing tests and exercises the new timestamp plumbing end‑to‑end.

Also applies to: 468-479

core/src/test/java/io/questdb/test/griffin/CopyExportTest.java (1)

29-30: SQL COPY now()-based Parquet export scenario is well covered

testCopyWithNowParameter correctly fixes currentMicros with MicrosTimestampDriver.floor(...), runs a COPY (SELECT ... WHERE ts < now()) to Parquet, and verifies only the expected row is present in the exported file. This gives solid regression coverage for the bug this PR targets and aligns with existing copy-export test patterns.

Also applies to: 1311-1335

core/src/main/java/io/questdb/griffin/engine/ops/CopyExportFactory.java (1)

167-185: Propagating now from execution context into queued export task is appropriate

Capturing nowTimestampType and now from the SqlExecutionContext right before enqueuing the CopyExportRequestTask, and passing them into task.of(...), ensures the asynchronous COPY-to-Parquet worker sees the same fixed now() value as the original COPY statement. This matches the HTTP path and is a clean extension of the existing task payload.

core/src/main/java/io/questdb/cutlass/http/processors/ExportQueryProcessor.java (1)

595-618: HTTP export path correctly threads now into the Parquet export task

The added nowTimestampType/now capture in copyQueryToParquetFile() and their inclusion in task.of(...) align the /exp Parquet export with the SqlExecutionContext that compiled the query (already initialised via initNow()). Together with SerialParquetExporter.setNowAndFixClock(...), this should eliminate discrepancies in now() evaluation between query compilation and asynchronous export.

core/src/main/java/io/questdb/cutlass/parquet/CopyExportRequestJob.java (1)

80-99: Worker’s local task copy now preserves now context

Extending localTaskCopy.of(...) to include rawArrayEncoding, nowTimestampType, and now mirrors the queue task’s state and guarantees that SerialParquetExporter sees the same timestamp context that was captured when the request was enqueued.

@bluestreak01
Copy link
Copy Markdown
Member

@kafka1991 there is an actionable nit-pick from the robot!

@kafka1991
Copy link
Copy Markdown
Collaborator Author

@kafka1991 there is an actionable nit-pick from the robot!

Hi @bluestreak01 Thanks! the nit has been resolved.

@glasstiger
Copy link
Copy Markdown
Contributor

[PR Coverage check]

😍 pass : 15 / 15 (100.00%)

file detail

path covered line new line coverage
🔵 io/questdb/cutlass/parquet/CopyExportRequestJob.java 3 3 100.00%
🔵 io/questdb/cutlass/http/processors/ExportQueryProcessor.java 3 3 100.00%
🔵 io/questdb/cutlass/parquet/SerialParquetExporter.java 1 1 100.00%
🔵 io/questdb/cutlass/parquet/CopyExportRequestTask.java 6 6 100.00%
🔵 io/questdb/griffin/engine/ops/CopyExportFactory.java 2 2 100.00%

@bluestreak01 bluestreak01 merged commit b978464 into master Dec 5, 2025
43 checks passed
@bluestreak01 bluestreak01 deleted the export_parquet_now_bug branch December 5, 2025 17: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.

3 participants