No. It's not completely the same.
NULL is just the default default (sic!) of data types.
All built-in data types shipped with Postgres 12 have
NULL as default1. But that does not necessarily apply to all types.
CREATE TYPE and
CREATE DOMAIN offer to set any default, which applies to all table column of that type unless an explicit
DEFAULT is set.
1 Except for one exotic exception: a data type shipped with the information schema and typically not visible in the schema search path:
information_schema.time_stamp, which defaults to
('now'::text)::timestamp(2) with time zone.
Demonstrating with a
domain as that's shorter. But the same applies to non-domain data types:
CREATE DOMAIN text_x AS TEXT DEFAULT 'X';
CREATE TABLE tbl (
, col_without_default text_x
, col_with_default text_x DEFAULT NULL
The default value of
col_without_default is 'X', while the one of
INSERT INTO tbl(id) VALUES (1) RETURNING *;
id | col_without_default | col_with_default
-: | :------------------ | :---------------
1 | X | null