Skip to content

test: capture datetime audit findings as ignored SQL tests; update audit skill#4453

Closed
andygrove wants to merge 4 commits into
apache:mainfrom
andygrove:audit-datetime-tests
Closed

test: capture datetime audit findings as ignored SQL tests; update audit skill#4453
andygrove wants to merge 4 commits into
apache:mainfrom
andygrove:audit-datetime-tests

Conversation

@andygrove
Copy link
Copy Markdown
Member

Which issue does this PR close?

Closes #.

Rationale for this change

While reviewing #4448 it became clear that the audit skill should produce captured tests for any correctness divergence it identifies, not just prose findings. Tests in query ignore(...) mode are the most useful long-lived artefact: they reproduce the bug for whoever picks up the fix, and they auto-activate when the ignore(...) is removed.

This PR updates the audit-comet-expression skill to require that workflow, and applies it retroactively to three correctness findings from the #4448 audit.

Stacked on #4448. The diff currently shows that PR's docs commits too; they will drop out when #4448 merges and this branch is rebased.

What changes are included in this PR?

Skill update (audit-comet-expression):

  • Step 6 reorganises the priorities into three named buckets: correctness divergences, missing coverage, and consistency issues.
  • Step 7 now requires correctness findings to be captured as SQL file tests in the same PR as the audit, walks through the "search for existing issue, file if missing" workflow, and gives the trivial-fix-vs-ignore decision rule with a concrete query ignore(<url>) example.

Captured tests for #4448 findings:

Test Bug Issue
next_day.sql (appended) Comet trims ' MO ' to match Monday; Spark does not trim and returns NULL #4450
next_day_ansi.sql (new) next_day returns NULL where Spark throws under spark.sql.ansi.enabled=true #4449
make_date_ansi.sql (new) make_date returns NULL where Spark throws under spark.sql.ansi.enabled=true #4451

All three are in query ignore(<issue>) mode. When the upstream fix lands, removing ignore(...) will activate the assertions.

Audit finding withdrawn:

The make_date "year 0 / negative years" finding was checked against Spark's own MakeDate.nullSafeEval, which uses LocalDate.of(year, month, day) and accepts any year in the full Java LocalDate range. Spark and chrono agree on this case, and the existing make_date.sql tests at lines 133/136 already exercise it. Issue #4452 was closed as not-a-bug.

Why not fix instead of ignore?

Both SparkNextDay and SparkMakeDate live in the upstream datafusion-spark crate (pinned at 53.1.0 in Cargo.lock). Fixing the ANSI throw and the trim behaviour requires changes there, which is outside the scope of this PR.

How are these changes tested?

The new SQL test files parse against SqlFileTestParser (the IgnorePattern, ConfigPattern, and MinSparkVersionPattern regexes all match the directives used). The query ignore(...) queries are skipped at runtime per the documented ignore mode contract in sql-file-tests.md, so they do not affect suite outcomes today.

andygrove added 4 commits May 27, 2026 07:44
…ression skill

Expand the audit skill so it produces consistent, accurate findings about
`getSupportLevel`, `getIncompatibleReasons`, `getUnsupportedReasons`, and
`convert`.

Step 3 gains a dedicated subsection covering:

- A decision rule for `Unsupported` vs `Incompatible` (wrong answer vs
  fallback/error).
- The runtime-vs-docs split: support-level `notes` flow into EXPLAIN via
  the dispatcher, while `get*Reasons()` is read only by `GenerateDocs`.
- Six consistency rules covering every branch, dead-reason detection,
  shared `private val` for reason strings, `Incompatible(Some(reason))`
  preference, and gating decisions in `getSupportLevel` rather than
  `convert`.
- Wording guidelines for reason strings (user-observable effect first,
  sentence case, backtick configs/types, tracking issue links).
- Real antipattern callouts naming specific serdes (`CometHour`,
  `CometMinute`, `CometSecond`, `CometInitCap`).

Step 5 gains a structured 9-item support-level consistency audit
checklist that produces findings against the four methods.

Step 7 splits into two asks: one for missing tests, one for consistency
fixes, so the user can opt in to either independently.
Add per-version audit sub-bullets to every implemented date/time
expression in spark_expressions_support.md using the
audit-comet-expression skill. Covers 38 SQL function names across the
33 backing Comet serde objects (some serdes back multiple SQL names,
e.g. `day`/`dayofmonth`, `date_add`/`dateadd`, `date_diff`/`datediff`).

For each function, the sub-bullets record:
- Whether the Spark class is identical across 3.4.3, 3.5.8, 4.0.1
- Spark 4.0 changes (universally the `NullIntolerant` trait /
  `nullIntolerant: Boolean` refactor, plus `StringTypeWithCollation`
  widening on string inputs and some error-helper renames)
- Known divergences between Comet and Spark, with tracking-issue links

The audit was driven by 8 parallel agents, each handling a related
group of expressions (codegen-dispatched, date field extractors,
Hour/Minute/Second, scalar function wrappers, timezone/unix,
truncation, format, Iceberg transforms).

Out of scope: `current_timezone`, `date_part`, `datepart`, `extract`,
`localtimestamp` route through Spark optimizer rewrites or evaluate to
constants and do not have dedicated Comet serdes; `days` and `hours`
are V2 partition transforms with no SQL function name and so do not
appear in this section.

No code changes in this PR; consistency findings flagged during the
audit will be addressed in follow-up PRs.
… audit skill

Skill update (audit-comet-expression):

- Step 6 reorganises priorities: correctness divergences, missing
  coverage, and consistency issues are now three distinct buckets.
- Step 7 now requires correctness findings to land as captured tests
  in the same PR as the audit. Walks through the search-or-file issue
  workflow and the trivial-fix-vs-ignore decision, with a `query
  ignore(<url>)` example.

Captured tests (linked to follow-up issues filed against this PR):

- next_day.sql gains a divergence test for whitespace trimming
  (Comet trims `' MO '`; Spark does not). ignore(apache#4450).
- next_day_ansi.sql is new and asserts that `next_day` throws under
  `spark.sql.ansi.enabled=true` for malformed dayOfWeek. Comet
  currently returns NULL. ignore(apache#4449).
- make_date_ansi.sql is new and asserts that `make_date` throws under
  `spark.sql.ansi.enabled=true` for invalid `(year, month, day)`.
  Comet currently returns NULL. ignore(apache#4451).

The fourth audit finding (`make_date` year 0 / negative years) was
verified against Spark's own implementation and turned out to be a
non-divergence; the issue was closed and no test added.

None of the three remaining bugs are trivial to fix here: both
`SparkNextDay` and `SparkMakeDate` live upstream in the
`datafusion-spark` crate, so the fixes need to flow through that
project. The captured tests will switch from `ignore(...)` to their
intended assertion mode when the upstream changes land.
@andygrove
Copy link
Copy Markdown
Member Author

Folded into #4448 per author request — the skill update and ignored tests belong in the same PR as the audit they came from.

@andygrove andygrove closed this May 27, 2026
@andygrove andygrove deleted the audit-datetime-tests branch May 27, 2026 14:22
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