Skip to content

Commit 0d90dc1

Browse files
committed
Avoid a few more SET DATA TYPE table rewrites.
When the new type is an unconstrained domain over the old type, we don't need to rewrite the table. Noah Misch and Robert Haas
1 parent 8e1124e commit 0d90dc1

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed

doc/src/sgml/ref/alter_table.sgml

+8-7
Original file line numberDiff line numberDiff line change
@@ -766,13 +766,14 @@ ALTER TABLE <replaceable class="PARAMETER">name</replaceable>
766766
<para>
767767
Adding a column with a non-null default or changing the type of an
768768
existing column will require the entire table and indexes to be rewritten.
769-
As an exception, if the old type type is binary coercible to the new
770-
type and the <literal>USING</> clause does not change the column contents,
771-
a table rewrite is not needed, but any indexes on the affected columns
772-
must still be rebuilt. Adding or removing a system <literal>oid</> column
773-
also requires rewriting the entire table. Table and/or index rebuilds may
774-
take a significant amount of time for a large table; and will temporarily
775-
require as much as double the disk space.
769+
As an exception, if the <literal>USING</> clause does not change the column
770+
contents and the old type is either binary coercible to the new type or
771+
an unconstrained domain over the new type, a table rewrite is not needed,
772+
but any indexes on the affected columns must still be rebuilt. Adding or
773+
removing a system <literal>oid</> column also requires rewriting the entire
774+
table. Table and/or index rebuilds may take a significant amount of time
775+
for a large table; and will temporarily require as much as double the disk
776+
space.
776777
</para>
777778

778779
<para>

src/backend/commands/tablecmds.c

+16-4
Original file line numberDiff line numberDiff line change
@@ -6632,10 +6632,14 @@ ATPrepAlterColumnType(List **wqueue,
66326632
}
66336633

66346634
/*
6635-
* When the data type of a column is changed, a rewrite might not be require
6636-
* if the data type is being changed to its current type, or more interestingly
6637-
* to a type to which it is binary coercible. But we must check carefully that
6638-
* the USING clause isn't trying to insert some other value.
6635+
* When the data type of a column is changed, a rewrite might not be required
6636+
* if the new type is sufficiently identical to the old one, and the USING
6637+
* clause isn't trying to insert some other value. It's safe to skip the
6638+
* rewrite if the old type is binary coercible to the new type, or if the
6639+
* new type is an unconstrained domain over the old type. In the case of a
6640+
* constrained domain, we could get by with scanning the table and checking
6641+
* the constraint rather than actually rewriting it, but we don't currently
6642+
* try to do that.
66396643
*/
66406644
static bool
66416645
ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno)
@@ -6649,6 +6653,14 @@ ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno)
66496653
return false;
66506654
else if (IsA(expr, RelabelType))
66516655
expr = (Node *) ((RelabelType *) expr)->arg;
6656+
else if (IsA(expr, CoerceToDomain))
6657+
{
6658+
CoerceToDomain *d = (CoerceToDomain *) expr;
6659+
6660+
if (GetDomainConstraints(d->resulttype) != NIL)
6661+
return true;
6662+
expr = (Node *) d->arg;
6663+
}
66526664
else
66536665
return true;
66546666
}

0 commit comments

Comments
 (0)