CAST(pg_get_expr(ad.adbin, ad.adrelid) AS varchar) AS column_default
FROM
pg_class c
LEFT JOIN pg_attribute a ON a.attrelid = c.oid
LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum
LEFT JOIN pg_type t ON a.atttypid = t.oid
LEFT JOIN pg_namespace d ON d.oid = c.relnamespace
LEFT join pg_constraint ct on ct.conrelid=c.oid and ct.contype='p'
WHERE
a.attnum > 0 and t.typname != ''
and c.relname = 'st_tbl'
and d.nspname = 'public'
ORDER BY
a.attnum;
9.3: <1::smallint>
9.6: <'1'::smallint>
(defining the default as simply <1> in create table results in <1> being output for the query above)
There are single quotes present in 9.6 whereas they were not present in 9.3.
If nothing else a release note patch is probably warranted but while my first reaction is that 9.6 is the correct output I can find argument for the 9.3 result as well. A hacker is going to need to chime in as to our broader "default expression interpretation rules" here. e.g., "now()" is resolved at CREATE TABLE but "current_timestamp" is resolve during insert...the former supports the 9.3 behavior while the later supports the 9.6 behavior.