Description
When a CLUSTER query projects a user column or alias whose name is literally the synthesized flag name __giql_is_new_cluster, the cluster ids are silently computed wrong. Examples:
-- table has a real column __giql_is_new_cluster
SELECT *, __giql_is_new_cluster AS leaked, CLUSTER(interval) AS cid FROM peaks
-- cids come out 7/14/23 instead of 1/1/2
SELECT *, score AS __giql_is_new_cluster, CLUSTER(interval) AS cid FROM peaks
-- cids come out 5/10/19 instead of 1/1/2
The user's column and the synthesized flag share the exact name; DuckDB renames the synthesized one to __giql_is_new_cluster_1, the outer * EXCLUDE ("__giql_is_new_cluster") strips the user's column, and the outer SUM(__giql_is_new_cluster) binds to the user's values instead of the 0/1 boundary flag — a silent cumulative-sum corruption of the cluster ids.
Root cause
giql.expanders.cluster._transform_for_cluster synthesizes __giql_is_new_cluster (giql.constants.CLUSTER_FLAG_COL) and both EXCLUDEs it from the outer star and sums it, but nothing rejects a user projection that references or aliases to a __giql_-prefixed name. The reserved __giql_ prefix is documented (#161, #178) to avoid collisions, but there is no validation pass enforcing it — so the collision fails silently rather than loudly.
Expected behavior
A user projection referencing or aliasing to a __giql_-prefixed reserved name should raise a clear error (converting a silent wrong-answer into a loud one), consistent with the reserved-namespace contract in #161/#178. Relatedly, the existing #161 test (test_transpile_should_disambiguate_cluster_when_source_has_is_new_cluster_column) only covers the unprefixed is_new_cluster column, giving false confidence that the prefixed collision is handled — that coverage gap should be closed. Surfaced during the #190 (PR #193) review; pre-existing and out of #190's scope.
https://claude.ai/code/session_01KAYsMtN7vYuECZHeeFFzCM
Description
When a
CLUSTERquery projects a user column or alias whose name is literally the synthesized flag name__giql_is_new_cluster, the cluster ids are silently computed wrong. Examples:The user's column and the synthesized flag share the exact name; DuckDB renames the synthesized one to
__giql_is_new_cluster_1, the outer* EXCLUDE ("__giql_is_new_cluster")strips the user's column, and the outerSUM(__giql_is_new_cluster)binds to the user's values instead of the 0/1 boundary flag — a silent cumulative-sum corruption of the cluster ids.Root cause
giql.expanders.cluster._transform_for_clustersynthesizes__giql_is_new_cluster(giql.constants.CLUSTER_FLAG_COL) and both EXCLUDEs it from the outer star and sums it, but nothing rejects a user projection that references or aliases to a__giql_-prefixed name. The reserved__giql_prefix is documented (#161, #178) to avoid collisions, but there is no validation pass enforcing it — so the collision fails silently rather than loudly.Expected behavior
A user projection referencing or aliasing to a
__giql_-prefixed reserved name should raise a clear error (converting a silent wrong-answer into a loud one), consistent with the reserved-namespace contract in #161/#178. Relatedly, the existing #161 test (test_transpile_should_disambiguate_cluster_when_source_has_is_new_cluster_column) only covers the unprefixedis_new_clustercolumn, giving false confidence that the prefixed collision is handled — that coverage gap should be closed. Surfaced during the #190 (PR #193) review; pre-existing and out of #190's scope.https://claude.ai/code/session_01KAYsMtN7vYuECZHeeFFzCM