diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c new file mode 100644 index 0a55db4..a76f957 *** a/src/backend/parser/parse_utilcmd.c --- b/src/backend/parser/parse_utilcmd.c *************** *** 56,61 **** --- 56,62 ---- #include "rewrite/rewriteManip.h" #include "utils/acl.h" #include "utils/builtins.h" + #include "utils/guc.h" #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/syscache.h" *************** transformCreateStmt(CreateStmt *stmt, co *** 150,155 **** --- 151,157 ---- Oid namespaceid; Oid existing_relid; ParseCallbackState pcbstate; + bool like_found = false; /* * We must not scribble on the passed-in CreateStmt, so copy it. (This is *************** transformCreateStmt(CreateStmt *stmt, co *** 242,248 **** /* * Run through each primary element in the table creation clause. Separate ! * column defs from constraints, and do preliminary analysis. */ foreach(elements, stmt->tableElts) { --- 244,253 ---- /* * Run through each primary element in the table creation clause. Separate ! * column defs from constraints, and do preliminary analysis. We have to ! * process column-defining clauses first because it can control the ! * presence of columns which are referenced by columns referenced by ! * constraints. */ foreach(elements, stmt->tableElts) { *************** transformCreateStmt(CreateStmt *stmt, co *** 254,267 **** transformColumnDefinition(&cxt, (ColumnDef *) element); break; - case T_Constraint: - transformTableConstraint(&cxt, (Constraint *) element); - break; - case T_TableLikeClause: transformTableLikeClause(&cxt, (TableLikeClause *) element); break; default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(element)); --- 259,277 ---- transformColumnDefinition(&cxt, (ColumnDef *) element); break; case T_TableLikeClause: + if (!like_found) + { + cxt.hasoids = false; + like_found = true; + } transformTableLikeClause(&cxt, (TableLikeClause *) element); break; + case T_Constraint: + /* process later */ + break; + default: elog(ERROR, "unrecognized node type: %d", (int) nodeTag(element)); *************** transformCreateStmt(CreateStmt *stmt, co *** 269,274 **** --- 279,305 ---- } } + if (like_found) + { + /* + * To match INHERITS, the existance of any LIKE table with OIDs + * causes the new table to have oids. For the same reason, + * WITH/WITHOUT OIDs is also ignored with LIKE. We prepend + * because the first oid option list entry is honored. Our + * prepended WITHOUT OIDS clause will be overridden if an + * inherited table has oids. + */ + stmt->options = lcons(makeDefElem("oids", + (Node *)makeInteger(cxt.hasoids)), stmt->options); + } + + foreach(elements, stmt->tableElts) + { + Node *element = lfirst(elements); + + if (nodeTag(element) == T_Constraint) + transformTableConstraint(&cxt, (Constraint *) element); + } /* * transformIndexConstraints wants cxt.alist to contain only index * statements, so transfer anything we already have into save_alist. *************** transformTableLikeClause(CreateStmtConte *** 860,865 **** --- 891,899 ---- } } + /* We use oids if at least one LIKE'ed table has oids. */ + cxt->hasoids = cxt->hasoids || relation->rd_rel->relhasoids; + /* * Copy CHECK constraints if requested, being careful to adjust attribute * numbers so they match the child. diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out new file mode 100644 index 8ba7bbc..41ceb87 *** a/src/test/regress/expected/create_table.out --- b/src/test/regress/expected/create_table.out *************** ERROR: relation "as_select1" already ex *** 250,252 **** --- 250,255 ---- CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'; NOTICE: relation "as_select1" already exists, skipping DROP TABLE as_select1; + -- check that the oid column is added before the primary key is checked + CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS; + DROP TABLE oid_pk; diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out new file mode 100644 index a5fac7b..97edde1 *** a/src/test/regress/expected/create_table_like.out --- b/src/test/regress/expected/create_table_like.out *************** DROP TYPE ctlty1; *** 228,230 **** --- 228,257 ---- DROP VIEW ctlv1; DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12; NOTICE: table "ctlt10" does not exist, skipping + /* LIKE WITH OIDS */ + CREATE TABLE has_oid (x INTEGER) WITH OIDS; + CREATE TABLE no_oid (y INTEGER); + CREATE TABLE like_test (z INTEGER, LIKE has_oid); + SELECT oid FROM like_test; + oid + ----- + (0 rows) + + CREATE TABLE like_test2 (z INTEGER, LIKE no_oid); + SELECT oid FROM like_test2; -- fail + ERROR: column "oid" does not exist + LINE 1: SELECT oid FROM like_test2; + ^ + CREATE TABLE like_test3 (z INTEGER, LIKE has_oid, LIKE no_oid); + SELECT oid FROM like_test3; + oid + ----- + (0 rows) + + CREATE TABLE like_test4 (z INTEGER, PRIMARY KEY(oid), LIKE has_oid); + SELECT oid FROM like_test4; + oid + ----- + (0 rows) + + DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3, like_test4; diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql new file mode 100644 index 03bb5ff..78bdc8b *** a/src/test/regress/sql/create_table.sql --- b/src/test/regress/sql/create_table.sql *************** CREATE TABLE as_select1 AS SELECT * FROM *** 265,267 **** --- 265,271 ---- CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'; CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'; DROP TABLE as_select1; + + -- check that the oid column is added before the primary key is checked + CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS; + DROP TABLE oid_pk; diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql new file mode 100644 index 2d017bc..6dded1f *** a/src/test/regress/sql/create_table_like.sql --- b/src/test/regress/sql/create_table_like.sql *************** DROP SEQUENCE ctlseq1; *** 119,121 **** --- 119,134 ---- DROP TYPE ctlty1; DROP VIEW ctlv1; DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12; + + /* LIKE WITH OIDS */ + CREATE TABLE has_oid (x INTEGER) WITH OIDS; + CREATE TABLE no_oid (y INTEGER); + CREATE TABLE like_test (z INTEGER, LIKE has_oid); + SELECT oid FROM like_test; + CREATE TABLE like_test2 (z INTEGER, LIKE no_oid); + SELECT oid FROM like_test2; -- fail + CREATE TABLE like_test3 (z INTEGER, LIKE has_oid, LIKE no_oid); + SELECT oid FROM like_test3; + CREATE TABLE like_test4 (z INTEGER, PRIMARY KEY(oid), LIKE has_oid); + SELECT oid FROM like_test4; + DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3, like_test4;