Get the default values of table columns in Postgres?

前端 未结 6 2001
温柔的废话
温柔的废话 2020-11-29 11:21

I\'m looking for a way to run a query to find the default values of the columns of a table in Postgres. For example, if I made a table with the following query:

6条回答
  •  -上瘾入骨i
    2020-11-29 11:45

    System catalogs are the source of truth in Postgres:

    SELECT pg_get_expr(d.adbin, d.adrelid) AS default_value
    FROM   pg_catalog.pg_attribute    a
    LEFT   JOIN pg_catalog.pg_attrdef d ON (a.attrelid, a.attnum) = (d.adrelid,  d.adnum)
    WHERE  NOT a.attisdropped           -- no dropped (dead) columns
    AND    a.attnum   > 0               -- no system columns
    AND    a.attrelid = 'myschema.mytable'::regclass
    AND    a.attname  = 'mycolumn';
    
    • Related answer on dba.SE discussing information schema vs. system catalogs

    LEFT JOIN guarantees a result as long as the column exists. If there is no default you get NULL - which happens to be the default default. And almost always correct. But see:

    • How to use default value of data type as column default?

    To exclude columns without default, use JOIN instead and be prepared to get no row occasionally.

    The special cast ::regclass considers the current setting for search_path. With names that aren't schema-qualified (which you should, to be sure!), you may or may not get the expected result. See rebuttal below. More in the manual. Related:

    • How does the search_path influence identifier resolution and the "current schema"

    No need to include pg_class once we have the OID of the table. Faster without.

    Why the first answer wouldn't do

    @Zohaib's query is almost but not quite right. There are a couple of issues. I copied it here for future reference. Do not use this:

    SELECT adsrc as default_value
     FROM pg_attrdef pad, pg_atttribute pat, pg_class pc
     WHERE pc.relname='your_table_name'
         AND pc.oid=pat.attrelid AND pat.attname='your_column_name'
         AND pat.attrelid=pad.adrelid AND pat.attnum=pad.adnum
    
    • Copied from some blog. Good that it's mentioned, but the source should be added. People reading that blog need to be warned.

    • Typo in pg_atttribute - fixed easily.

    • Doesn't return any rows, if there is no default specified for the requested column. Better make that a LEFT JOIN pg_attrdef ON .., so you always get a resulting row if the column exists. It will be NULL, if there is no default, which is actually the correct result because NULL is the default then.

    • If you remove attname from the WHERE clause, you only get values for columns that actually have a default value. Not for others. And you need to add attname to the SELECT list or you will not know for which column.

    • The query would also return the default of a column that is already dropped, which is wrong. Read about the details in the manual.

    • Most importantly: the query can give completely wrong results, as it does not take the schema name into account. There can be any number of table1.col1 in a postgres database: in various schemas. If more than one have a default, you get multiple values. If the column you have in mind does not have a default, but another one in another schema does, you will be fooled and never know it.

    • Last not least: in recent PostgreSQL releases, the adsrc column has been removed from pg_attrdef by commit fe5038236c, as it was redundant, deprecated and unused in PostgreSQL.

    To sum it up: C/P from some blog without insight went dangerously wrong.

提交回复
热议问题