Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 68330c8

Browse files
committed
Fix CREATE TABLE ... LIKE ... WITH OIDS.
Having a WITH OIDS specification should result in the creation of an OID column, but commit b943f50 broke that in the case that there were LIKE tables without OIDS. Commentary in that patch makes it look like this was intentional, but if so it was based on a faulty reading of what inheritance does: the parent tables can add an OID column, but they can't subtract one. AFAICS, the behavior ought to be that you get an OID column if any of the inherited tables, LIKE tables, or WITH clause ask for one. Also, revert that patch's unnecessary split of transformCreateStmt's loop over the tableElts list into two passes. That seems to have been based on a misunderstanding as well: we already have two-pass processing here, we don't need three passes. Per bug #14474 from Jeff Dafoe. Back-patch to 9.6 where the misbehavior was introduced. Report: https://postgr.es/m/20161222145304.25620.47445@wrigleys.postgresql.org
1 parent 77cd0dc commit 68330c8

File tree

3 files changed

+31
-36
lines changed

3 files changed

+31
-36
lines changed

src/backend/parser/parse_utilcmd.c

+19-34
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
#include "rewrite/rewriteManip.h"
6060
#include "utils/acl.h"
6161
#include "utils/builtins.h"
62-
#include "utils/guc.h"
6362
#include "utils/lsyscache.h"
6463
#include "utils/rel.h"
6564
#include "utils/syscache.h"
@@ -249,10 +248,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
249248

250249
/*
251250
* Run through each primary element in the table creation clause. Separate
252-
* column defs from constraints, and do preliminary analysis. We have to
253-
* process column-defining clauses first because it can control the
254-
* presence of columns which are referenced by columns referenced by
255-
* constraints.
251+
* column defs from constraints, and do preliminary analysis.
256252
*/
257253
foreach(elements, stmt->tableElts)
258254
{
@@ -264,17 +260,13 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
264260
transformColumnDefinition(&cxt, (ColumnDef *) element);
265261
break;
266262

267-
case T_TableLikeClause:
268-
if (!like_found)
269-
{
270-
cxt.hasoids = false;
271-
like_found = true;
272-
}
273-
transformTableLikeClause(&cxt, (TableLikeClause *) element);
263+
case T_Constraint:
264+
transformTableConstraint(&cxt, (Constraint *) element);
274265
break;
275266

276-
case T_Constraint:
277-
/* process later */
267+
case T_TableLikeClause:
268+
like_found = true;
269+
transformTableLikeClause(&cxt, (TableLikeClause *) element);
278270
break;
279271

280272
default:
@@ -284,26 +276,19 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
284276
}
285277
}
286278

287-
if (like_found)
288-
{
289-
/*
290-
* To match INHERITS, the existence of any LIKE table with OIDs causes
291-
* the new table to have oids. For the same reason, WITH/WITHOUT OIDs
292-
* is also ignored with LIKE. We prepend because the first oid option
293-
* list entry is honored. Our prepended WITHOUT OIDS clause will be
294-
* overridden if an inherited table has oids.
295-
*/
279+
/*
280+
* If we had any LIKE tables, they may require creation of an OID column
281+
* even though the command's own WITH clause didn't ask for one (or,
282+
* perhaps, even specifically rejected having one). Insert a WITH option
283+
* to ensure that happens. We prepend to the list because the first oid
284+
* option will be honored, and we want to override anything already there.
285+
* (But note that DefineRelation will override this again to add an OID
286+
* column if one appears in an inheritance parent table.)
287+
*/
288+
if (like_found && cxt.hasoids)
296289
stmt->options = lcons(makeDefElem("oids",
297-
(Node *) makeInteger(cxt.hasoids)), stmt->options);
298-
}
299-
300-
foreach(elements, stmt->tableElts)
301-
{
302-
Node *element = lfirst(elements);
303-
304-
if (nodeTag(element) == T_Constraint)
305-
transformTableConstraint(&cxt, (Constraint *) element);
306-
}
290+
(Node *) makeInteger(true)),
291+
stmt->options);
307292

308293
/*
309294
* transformIndexConstraints wants cxt.alist to contain only index
@@ -902,7 +887,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
902887
}
903888

904889
/* We use oids if at least one LIKE'ed table has oids. */
905-
cxt->hasoids = cxt->hasoids || relation->rd_rel->relhasoids;
890+
cxt->hasoids |= relation->rd_rel->relhasoids;
906891

907892
/*
908893
* Copy CHECK constraints if requested, being careful to adjust attribute

src/test/regress/expected/create_table_like.out

+8-1
Original file line numberDiff line numberDiff line change
@@ -254,4 +254,11 @@ SELECT oid FROM like_test4;
254254
-----
255255
(0 rows)
256256

257-
DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3, like_test4;
257+
CREATE TABLE like_test5 (z INTEGER, LIKE no_oid) WITH OIDS;
258+
SELECT oid FROM like_test5;
259+
oid
260+
-----
261+
(0 rows)
262+
263+
DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3,
264+
like_test4, like_test5;

src/test/regress/sql/create_table_like.sql

+4-1
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,7 @@ CREATE TABLE like_test3 (z INTEGER, LIKE has_oid, LIKE no_oid);
131131
SELECT oid FROM like_test3;
132132
CREATE TABLE like_test4 (z INTEGER, PRIMARY KEY(oid), LIKE has_oid);
133133
SELECT oid FROM like_test4;
134-
DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3, like_test4;
134+
CREATE TABLE like_test5 (z INTEGER, LIKE no_oid) WITH OIDS;
135+
SELECT oid FROM like_test5;
136+
DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3,
137+
like_test4, like_test5;

0 commit comments

Comments
 (0)