snippetsqlMinor
Immutably convert enum to string
Viewed 0 times
convertimmutablyenumstring
Problem
The normal way to convert an enum value to a string in PostgreSQL is to cast it (with
However, there's a catch: such conversions seem not to be considered immutable by Postgres. As a consequence, you get an error if you try to use them in a place where an immutable expression is expected, such as in the definition of a
This seems unintuitive, and is inconvenient, since I'd like to be able to concatenate enum values onto strings in a computed column.
Thus, I have two questions:
::text) or to simply rely on implicit conversion when, say, concatenating it to another string:testdb=# CREATE TYPE color AS ENUM ('red', 'green', 'blue');
CREATE TYPE
testdb=# CREATE TABLE object (id serial, name text, color color);
CREATE TABLE
testdb=# INSERT INTO object (name, color) VALUES ('table', 'red'), ('chair', 'green');
INSERT 0 2
testdb=# SELECT name || color FROM object;
?column?
------------
tablered
chairgreen
(2 rows)However, there's a catch: such conversions seem not to be considered immutable by Postgres. As a consequence, you get an error if you try to use them in a place where an immutable expression is expected, such as in the definition of a
GENERATED column:testdb=# ALTER TABLE object ADD COLUMN namecolor text GENERATED ALWAYS AS (name || color) STORED;
ERROR: generation expression is not immutable
testdb=# ALTER TABLE object ADD COLUMN colorastext text GENERATED ALWAYS AS (color::text) STORED;
ERROR: generation expression is not immutableThis seems unintuitive, and is inconvenient, since I'd like to be able to concatenate enum values onto strings in a computed column.
Thus, I have two questions:
- Why does Postgres consider converting an enum to a string to not be immutable? Is this behaviour a bug?
- Is there a workaround that will let me persuade Postgres such a conversion is immutable (and are there any risks I should be wary of)?
Solution
-
It is possible to rename an enum entry, so the cast is not
-
If you are sure that you will never rename enum values, write your own conversion function that uses a cast internally and label the function
It is possible to rename an enum entry, so the cast is not
IMMUTABLE.-
If you are sure that you will never rename enum values, write your own conversion function that uses a cast internally and label the function
IMMUTABLE. Then PostgreSQL will trust that label, and it is up to you to fulfill the promise.Context
StackExchange Database Administrators Q#276477, answer score: 6
Revisions (0)
No revisions yet.