aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_utilcmd.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2015-10-05 21:19:16 -0400
committerBruce Momjian <bruce@momjian.us>2015-10-05 21:19:16 -0400
commitb943f502b788a3708ca660785fd14a4ee938fdcd (patch)
tree218ef8c4f5e3143fb4d43ee67ffd4371bb036466 /src/backend/parser/parse_utilcmd.c
parent28b3a3d41a8b72841a3f5067217f639a7d337c0e (diff)
downloadpostgresql-b943f502b788a3708ca660785fd14a4ee938fdcd.tar.gz
postgresql-b943f502b788a3708ca660785fd14a4ee938fdcd.zip
Have CREATE TABLE LIKE add OID column if any LIKEd table has one
Also, process constraints for LIKEd tables at the end so an OID column can be referenced in a constraint. Report by Tom Lane
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r--src/backend/parser/parse_utilcmd.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 16d40c72406..14384d58dbe 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -56,6 +56,7 @@
#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"
@@ -150,6 +151,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
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
@@ -242,7 +244,10 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
/*
* Run through each primary element in the table creation clause. Separate
- * column defs from constraints, and do preliminary analysis.
+ * 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)
{
@@ -254,14 +259,19 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
transformColumnDefinition(&cxt, (ColumnDef *) element);
break;
- case T_Constraint:
- transformTableConstraint(&cxt, (Constraint *) 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));
@@ -269,6 +279,27 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
}
}
+ 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.
@@ -860,6 +891,9 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
}
}
+ /* 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.