Skip to content

fix: type the NULL that a date shifted by NULL compiles to - #444

Draft
jat255 wants to merge 1 commit into
jat255/438-quote-lowercase-tablesfrom
jat255/441-typed-null-date-shift
Draft

jat255 wants to merge 1 commit into
jat255/438-quote-lowercase-tablesfrom
jat255/441-typed-null-date-shift

Conversation

@jat255

@jat255 jat255 commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #441

This PR makes a definition such as created + NULL compile to a typed NULL timestamp on Snowflake and Databricks. Snowflake refuses to add a bare NULL to a DATE.

Details (agent-written)

The type checker reads created + NULL as a temporal shift with a datetime result, but the emitters rewrote a shift only when an operand had the interval type. Both the Python emitter and the R emitter now write CAST(NULL AS TIMESTAMP_TZ) on Snowflake and CAST(NULL AS TIMESTAMP) on Databricks. These are the types the live fixture uses for timestamp columns. The shared warehouse fixture pins both.

Known gap: a sibling definition whose value is NULL, used as the shift, still compiles to DATE + (NULL) after composition. The emitter sees only a reference with the type any, and an any operand can also be an untyped column with real values, so it cannot be typed NULL the way a literal can. This is tracked as kata y8nf.

Testing: the full Python and R suites pass. On live Snowflake, with this whole stack, all 40 corpus definitions return the same values as DuckDB, and every Snowflake live test passes in both packages. Databricks is not verified.

Kata: whhh, y8nf.

R changes

The R SQL emitter now compiles a date or datetime shifted by a literal NULL to a NULL cast to the dialect's timestamp type (definition-emit-sql.R). Snowflake used to reject the compiled SQL for such a definition, and now runs it and returns NULL. Every other temporal shift compiles as before. NEWS has a bullet.

@jat255 jat255 added bug Something isn't working needs-manual-review Agent-created work that needs a human review labels Oct 21, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Preview root: https://posit-dev.github.io/commons/pr-444/

Python site preview: https://posit-dev.github.io/commons/pr-444/py/

Built from the latest commit on this branch. The R links in it point at the published R site, which no pull request rebuilds.

The checker accepts an untyped NULL as a temporal shift's interval and types the result as a datetime, but the emitters rewrote a shift only when an operand had the interval type. created + NULL therefore fell through to a plain +, and Snowflake refuses to add a bare NULL to a DATE. Both emitters now write a NULL cast to the dialect's timestamp type.

The shared warehouse fixture pins the corpus's nullable date shift for both targets.

Closes #441
@jat255
jat255 force-pushed the jat255/438-quote-lowercase-tables branch from d41e26b to af62e71 Compare October 22, 2026 02:46
@jat255
jat255 force-pushed the jat255/441-typed-null-date-shift branch from 521853f to 4e4c282 Compare October 22, 2026 02:46

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working needs-manual-review Agent-created work that needs a human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant