Search code examples
postgresqlconcatenationstring-concatenation

Error when creating a generated column in Postgresql


CREATE TABLE Person (
   id  serial primary key,
   accNum  text UNIQUE GENERATED ALWAYS AS (
 concat(right(cast(extract year from current_date) as text), 2), cast(id as text)) STORED
);

Error: generation expression is not immutable

The goal is to populate the accNum field with YYid where YY is the last two letters of the year when the person was added.

I also tried the '||' operator but it was unsuccessful.


Solution

  • As you don't expect the column to be updated, when the row is changed, you can define your own function that generates the number:

    create function generate_acc_num(id int)
    returns text
    as
    $$
      select to_char(current_date, 'YY')||id::text;
    $$
    language sql
    immutable; --<< this is lying to Postgres!
    

    Note that you should never use this function for any other purpose. Especially not as an index expression.

    Then you can use that in a generated column:

    CREATE TABLE Person 
    (
      id  integer generated always as identity primary key,
      acc_num  text UNIQUE GENERATED ALWAYS AS (generate_acc_num(id)) STORED
    );