Fix handling of CREATE TABLE LIKE with inheritance.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 21 Aug 2020 19:00:43 +0000 (15:00 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 21 Aug 2020 19:00:43 +0000 (15:00 -0400)
commit21f8b1811ac1b61c38970c27711a7ed7fafedba6
tree2282c40aacd3c4a063d950f0890356d50eec8254
parentaa4da2674ca2d9d31af4082e1cf3837b55a85a43
Fix handling of CREATE TABLE LIKE with inheritance.

If a CREATE TABLE command uses both LIKE and traditional inheritance,
Vars in CHECK constraints and expression indexes that are absorbed
from a LIKE parent table tended to get mis-numbered, resulting in
wrong answers and/or bizarre error messages (though probably not any
actual crashes, thanks to validation occurring in the executor).

In v12 and up, the same could happen to Vars in GENERATED expressions,
even in cases with no LIKE clause but multiple traditional-inheritance
parents.

The cause of the problem for LIKE is that parse_utilcmd.c supposed
it could renumber such Vars correctly during transformCreateStmt(),
which it cannot since we have not yet accounted for columns added via
inheritance.  Fix that by postponing processing of LIKE INCLUDING
CONSTRAINTS, DEFAULTS, GENERATED, INDEXES till after we've performed
DefineRelation().

The error with GENERATED and multiple inheritance is a simple oversight
in MergeAttributes(); it knows it has to renumber Vars in inherited
CHECK constraints, but forgot to apply the same processing to inherited
GENERATED expressions (a/k/a defaults).

Per bug #16272 from Tom Gottfried.  The non-GENERATED variants of the
issue are ancient, presumably dating right back to the addition of
CREATE TABLE LIKE; hence back-patch to all supported branches.

Discussion: https://postgr.es/m/16272-6e32da020e9a9381@postgresql.org
src/backend/parser/parse_utilcmd.c
src/backend/tcop/utility.c
src/include/parser/parse_utilcmd.h
src/test/regress/expected/create_table_like.out
src/test/regress/sql/create_table_like.sql