2 Ways to Check if a Table has a Generated Column in PostgreSQL

PostgreSQL has supported generated columns since version 12. Generated columns can be created easily with the CREATE TABLE and ALTER TABLE statements.

We can check whether a table contains a generated column or not with the following methods.

The \d Command

In psql, the \d command shows information about tables, views, materialised views, index, sequences, or foreign tables.

We can therefore use this command to check whether a given table has any generated columns:

\d students

Result:

                                                            Table "public.students"
  Column   |          Type          | Collation | Nullable |                                      Default                                      
-----------+------------------------+-----------+----------+-----------------------------------------------------------------------------------
 id        | integer                |           | not null | 
 firstname | character varying(50)  |           |          | 
 lastname  | character varying(50)  |           |          | 
 fullname  | character varying(101) |           |          | generated always as ((((firstname::text || ' '::text) || lastname::text))) stored
Indexes:
    "students_pkey" PRIMARY KEY, btree (id)

We can see that the fullname column is a generated column. We can see this, because the Default column contains its expression.

In this case, the expression looks like this:

generated always as ((((firstname::text || ' '::text) || lastname::text))) stored

That expression reflects the code that was used to create the generated column. We can see that it’s a stored column (as opposed to virtual).

  • A stored generated column stores its value in the table (and therefore uses up space in the table).
  • A virtual generated column generates its value dynamically when the table is read.

As of PostgreSQL 14, PostgreSQL only supports stored generated columns. This could change in a future release.

The information_schema.columns View

The information_schema.columns view contains information about columns:

SELECT 
  column_name, 
  is_generated,
  generation_expression
FROM information_schema.columns
WHERE table_name = 'students';

Result:

 column_name | is_generated |                 generation_expression                  
-------------+--------------+--------------------------------------------------------
 id          | NEVER        | 
 firstname   | NEVER        | 
 lastname    | NEVER        | 
 fullname    | ALWAYS       | (((firstname)::text || ' '::text) || (lastname)::text)

Here, I returned two columns of interest:

  • The is_generated column tells us whether or not the column is generated. ALWAYS means that it is.
  • The generation_expression shows us the expression that the generated column consists of.