Skip to content

Add support for ENUM types in shape's WHERE clause #1709

@alco

Description

@alco
  • Allow casting any enum type to a character type: text, char(N), varchar(N).
    This will allow WHERE clauses to have equality, non-equality, list inclusion, nullability checks via an explicit cast. For example, status::text = 'draft' or status::text IN ('draft', 'in_review').

  • Implicitly cast character literals to the appropriate enum type.
    This will allow shapes to have WHERE clauses such as status IN ('draft', 'published') or status > 'draft'.

    Note that status::text > 'draft' is different from status > 'draft'::status. The result depends on the order of enum values in the type definition:

    =# create type status as enum ('published', 'draft');
    CREATE TYPE
    
    =# create table example(id bigserial primary key, status status);
    CREATE TABLE
    
    =# insert into example(id, status) VALUES (1, 'draft'), (2, 'published');
    INSERT 0 2
    
    =# select * from example where status::text > 'draft';
     id │  status   
    ────┼───────────
      2 │ published
    (1 row)
    
    =# select * from example where status > 'draft'::status;
     id │ status 
    ────┼────────
    (0 rows)
    
    =# select * from example where status < 'draft'::status;
     id │  status   
    ────┼───────────
      2 │ published
    (1 row)
  • Altering an enum type must invalidate the shapes that reference columns or values of that type. The difficult part is that we don't have a reliable way to detect that without using Event Triggers.

    As an example, a shape with the WHERE clause status > 'draft' cannot be used anymore after the referenced enum value is renamed. Given the following type definition:

    CREATE TYPE status AS ENUM ('draft', 'published');

    Renaming the referenced value will invalidate the shape's WHERE clause:

    ALTER TYPE status RENAME VALUE 'draft' TO 'unpublished';

    A series of renamings may effectively reverse the order of enum values, so that while the shape's WHERE clause remains valid, the set of synced rows no longer matches it:

    ALTER TYPE status RENAME VALUE 'draft' TO 'tmp';
    ALTER TYPE status RENAME VALUE 'published' TO 'draft';
    ALTER TYPE status RENAME VALUE 'tmp' TO 'published';

    Now the shape's WHERE clause status > 'draft' matches 0 rows, even though some have already been synced.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions