Add support for ENUM types in shape's WHERE clause
-
[ ] 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'orstatus::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')orstatus > 'draft'.Note that
status::text > 'draft'is different fromstatus > '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.
Issue we've run into working on this with @icehaunter is that row filters on the replication publication don't allow for user-defined types, see docs:
A row filter expression (i.e., the WHERE clause) must contain only columns that are covered by the REPLICA IDENTITY, in order for UPDATE and DELETE operations to be published. For publication of INSERT operations, any column may be used in the WHERE expression. The row filter allows simple expressions that don't have user-defined functions, user-defined operators, user-defined types, user-defined collations, non-immutable built-in functions, or references to system columns.