Skip to content

CLUSTER silently corrupts cluster ids when a user column/alias is named __giql_is_new_cluster #195

Description

@conradbzura

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions