Skip to content

typelayer: a role denied a generator-DEFAULT column has every record declined (chtypes v2) #816

Open

Description

@EricAndrechek

Found on the chtypes v2 work for #712. It affects unreleased code only: the role-restricted ingest path in #712.

Problem. When a role may not write a column whose DEFAULT draws a random or generated value, every record that role ingests is declined.

Measured on the chtypes v2 dev SDK, library build 20261009.145808, with an overlay test through Table.IngestWith:

  • Table: id UUID DEFAULT generateUUIDv4(), tenant String, v UInt32.
  • Role: may write tenant, v only.
  • Body: {"tenant":"a","v":1} {"tenant":"a","v":2}.
  • Result: the batch is declined as a whole: batch outcome is 'unsupported': only a fully accepted batch exports bytes. On the API that is a 422 validation engine declined for every record.

Controls (same build):

  • Same table with id writable by the role: accepted.
  • Same table, no column restrictions: accepted, with generated ids.
  • A denied ts DateTime64(3) DEFAULT now64(3) (a clock value, not a generator): accepted, ts omitted from the export.

Why. internal/typelayer/roletable.go builds a role's schema by re-declaring each column the role may not write as MATERIALIZED <its stored default> (storedDefault). That keeps every expression over it compiling, and stops a record from naming it. For id UUID DEFAULT generateUUIDv4() that gives id MATERIALIZED generateUUIDv4(). chtypes refuses a MATERIALIZED column that draws a random or generated value, because the server would draw its own at INSERT. So the role's whole batch comes back unsupported.

Who meets it. Any deployment where a role's insert permissions exclude a column with a generator DEFAULT (generateUUIDv4(), generateUUIDv7(), rand*(), generateSnowflakeID(), and similar). A server-assigned id UUID DEFAULT generateUUIDv4() is a common table shape.

Related: #712.

Activity

  1. EricAndrechek commented on Oct 13, 2026

    @EricAndrechek
    MemberAuthor

    Planned fix. chtypes v2 is adding a column-level insert restriction to its parse and preview calls, modelled on ClickHouse's column-level INSERT grant:

    • a record naming a non-insertable column is refused the way the server refuses it;
    • an omitted column keeps its own kind, so a generator DEFAULT still draws;
    • the export carries the drawn value.

    When it ships in a chtypes v2 build, WaveHouse should:

    • pass each role's writable columns through it;
    • drop the MATERIALIZED re-declaration in roletable.go;
    • add a regression test for the case measured above: a role denied id UUID DEFAULT generateUUIDv4() gets its records accepted, with generated ids.

    Role-injected defaults would need a follow-up chtypes option, which is reserved and isn't in 2.0.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions