First of all, you seem to be confusing locks and table rewrites. The note in the release notes talks about table rewrites - which always take an ACCESS EXCLUSIVE
lock on the table. But here are many other operations that also take locks.
You would need:
ALTER TABLE tbl ALTER ts_col TYPE timestamptz;
Unless you want to set a specific time zone in the conversion, not the current time zone of your session:
ALTER TABLE tbl ALTER ts_col TYPE timestamptz USING ts_col AT TIME ZONE 'Europe/London';
Be sure to use a time zone name in this case, not a simple offset nor an abbreviation. Details:
The manual:
ALTER TABLE
changes the definition of an existing table. There are
several subforms described below. Note that the lock level required
may differ for each subform. An ACCESS EXCLUSIVE
lock is held unless
explicitly noted.
ALTER column_name TYPE data_type
takes such an ACCESS EXCLUSIVE
lock. While the internal storage format of timestamp
and timestamptz
are identical, the internal value is typically changed by the conversion (depending on the time zone setting of the session!). Postgres has to write a new version of every row in the table, so this requires a table rewrite as well. Since the operation took an ACCESS EXCLUSIVE
lock there is no need to keep old row versions and you will see no dead tuples after the conversion.
fiddle - demonstrating the role of the time zone setting on the conversion. I also added an example converting varchar
to text
, which does not require a table rewrite - unless you move to a shorter length modifier.
Old sqlfiddle - note the output cast to text
(ts_col::text
) to keep the JDBC layer in sqlfiddle from adding more (unwanted!) representation magic.
Concurrent transactions trying to access the table after your transaction has started will wait until this transaction has finished.
You could try to keep the lock time short by preparing a new table in the background, delete the old table and rename the new, but this will make concurrent transactions fail with an error like:
ERROR: could not open relation with OID 123456
Details:
"Similar cases" for timestamp
/ timestamptz
Like varchar
or numeric
timestamp
, time
and interval
types allow modifiers. For example, timestamps store up to 6 digits for fractional seconds per default, but you can modify that: timestamp(0)
does not store fractional seconds.
The conversion from varchar(10)
-> varchar(20)
does not requires a table rewrite because values in the source type are guaranteed to fit (binary compatible) in the target type as well.
The same is true for timestamp (0)
-> timestamp
or timestamptz(3)
-> timestamptz(5)
. That's what the manual refers to in the quoted passage in the release notes:
Table rewrites are also avoided in similar cases involving the
interval
, timestamp
, and timestamptz
types.