regexpostgresqlsubstring

substring(enumColumn::TEXT from 'pattern') not IMMUTABLE in PostgreSQL


As I understand it, the substring function should be immutable. However, when I try to generate a column from the expression substring(enumColumn::TEXT from '-(.+)') I get a generation expression is not immutable error.

enumColumn is constrained to not be NULL, and it is not a generated column. Its type is an enum whose values are strings that all match the pattern '-(.+)'.

Is the issue related to the possibility that the pattern won't match and return NULL? Or is PostgreSQL complaining about something else?


UPDATE: this works fine when the column type from which the substring is computed is already TEXT. I think the issue is that enumType::TEXT is only STABLE, not IMMUTABLE?


Solution

  • Yes, it is the type cast that is your problem. The only solution would be to define a function (or a type cast using a function) and explicitly declare the function to be IMMUTABLE. You can safely do that if you promise never to change an enum label with ALTER TYPE ... RENAME.

    A different approach would be not to use a generated column, but to define a BEFORE INSERT OR UPDATE trigger that sets the column to the desired value before the row is inserted into the table.