Skip to content

in operator in policy expressions fails with PostgreSQL native enums — operator does not exist #2718

@ludovicmotte

Description

@ludovicmotte

Description and expected behavior
When using the in operator in @@deny/@@Allow policy rules to compare a PostgreSQL enum field against a list of enum values, the generated SQL uses = any(cast(ARRAY[$x,$y] as text[])). PostgreSQL rejects this because the column is a native enum type and there's no implicit cast from enum to text for the = operator.

Error: 42883 — operator does not exist: "StateType" = text

Reproduction:

enum State {
    IN_PROGRESS
    DONE
    REVIEWED
}
model Post {
    state: State
    // This fails:
    @@deny("delete", !(state in [DONE, REVIEWED]))
}

Generated SQL (problematic part):

not (select "state" as "_" from "public"."Post"
where ...) = any(cast(ARRAY[$83,$84] as text[]))

Expected: The enum column should be cast to text before comparison, or the array should be cast to the enum type.

Workaround: Replace in [DONE, REVIEWED] with (state == DONE || state == REVIEWED).
The == operator generates correct SQL with implicit enum-to-text cast.

Environment (please complete the following information):

  • ZenStack version: 3.7.2
  • Database type: Postgresql
  • Node.js version: 24.15.0
  • Package manager: npm

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    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