Skip to content

Fix CAST/CONVERT of NULL returning 0, false or "undefined" to close #1208 - #2576

Open
joshuablac wants to merge 1 commit into
AlaSQL:developfrom
joshuablac:fix/cast-null-1208
Open

joshuablac wants to merge 1 commit into
AlaSQL:developfrom
joshuablac:fix/cast-null-1208

Conversation

@joshuablac

Copy link
Copy Markdown

Closes #1208

Problem

CAST/CONVERT coerce NULL instead of passing it through, so AVG(CAST(col AS NUMBER)) over NULL values returns 0 instead of undefined (the example in #1208). The same root cause shows up for every target type:

Expression develop With this PR
CAST(NULL AS INT) / SMALLINT / BIGINT 0 undefined
CAST(a AS NUMBER) where a is null 0 undefined
CAST(NULL AS VARCHAR) "undefined" ("null" for a null column) undefined
CAST(NULL AS BOOLEAN) false undefined
CAST(NULL AS DATE) "aN.aN.aN" ("70.01.01" for a null column) undefined
CAST(NULL AS JSON) throws Cannot convert string to JSON undefined
AVG / SUM / COUNT(CAST(a AS NUMBER)) over [null, 4, missing] 1.33 / 4 / 3 4 / 4 / 1

Cause

alasql.stdfn.CONVERT (used by both CAST and CONVERT) never checks for NULL, so null goes through val | 0, +val, String(val), !!val or the date formatting.

Fix

Return undefined at the top of CONVERT when the value is null or undefined. That matches standard SQL (casting NULL to any type gives NULL) and AlaSQL's convention of returning undefined for NULL. Non-null values are converted as before.

Behavior change to note: anything that relied on CAST(NULL AS INT) being 0 (or BOOLEAN being false, etc.) now gets undefined. The same applies to DECLARE/SET on a typed variable assigned NULL, since they also go through CONVERT. No existing test depended on the old behavior.

Tests

  • Added test/test1208.js: both queries from the issue, CAST(NULL AS ...) for 17 types, null and missing columns, CONVERT with a style, aggregates over cast NULLs, and a guard that non-null values still convert. 6 of the 7 cases fail on develop and all 7 pass with this change.
  • Full suite (bun test, same command as yarn test-only): 2256 pass, 213 skip. The only 2 failures are in test2149.js (CLI). They fail identically on unmodified develop in my local setup: one because my checkout path contains spaces, and one because the version-injection step of build.sh didn't run.

Note: while testing I noticed that plain AVG(col) (without CAST) returns null for a single-row group whose value is null, but undefined for a multi-row all-null group. This PR doesn't touch that.

This fix was written with AI assistance (Claude Code) and verified locally as described above.

🤖 Generated with Claude Code

…laSQL#1208

CAST(NULL AS <type>) and CONVERT(<type>, NULL) now return undefined
(AlaSQL's NULL) for every target type, as in standard SQL. Previously the
value was coerced: INT gave 0, NUMBER gave 0 for a null column, STRING gave
"undefined"/"null", BOOLEAN gave false, DATE gave "aN.aN.aN" and JSON threw.
The coerced 0 was then counted by AVG/SUM/COUNT, which is the wrong AVG
reported in AlaSQL#1208.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 12, 2026 15:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

avg with cast as number not working as expected in group by

2 participants