5656#include "rewrite/rewriteManip.h"
5757#include "utils/acl.h"
5858#include "utils/builtins.h"
59+ #include "utils/guc.h"
5960#include "utils/lsyscache.h"
6061#include "utils/rel.h"
6162#include "utils/syscache.h"
@@ -150,6 +151,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
150151 Oid namespaceid ;
151152 Oid existing_relid ;
152153 ParseCallbackState pcbstate ;
154+ bool like_found = false;
153155
154156 /*
155157 * We must not scribble on the passed-in CreateStmt, so copy it. (This is
@@ -242,7 +244,10 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
242244
243245 /*
244246 * Run through each primary element in the table creation clause. Separate
245- * column defs from constraints, and do preliminary analysis.
247+ * column defs from constraints, and do preliminary analysis. We have to
248+ * process column-defining clauses first because it can control the
249+ * presence of columns which are referenced by columns referenced by
250+ * constraints.
246251 */
247252 foreach (elements , stmt -> tableElts )
248253 {
@@ -254,21 +259,47 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
254259 transformColumnDefinition (& cxt , (ColumnDef * ) element );
255260 break ;
256261
257- case T_Constraint :
258- transformTableConstraint (& cxt , (Constraint * ) element );
259- break ;
260-
261262 case T_TableLikeClause :
263+ if (!like_found )
264+ {
265+ cxt .hasoids = false;
266+ like_found = true;
267+ }
262268 transformTableLikeClause (& cxt , (TableLikeClause * ) element );
263269 break ;
264270
271+ case T_Constraint :
272+ /* process later */
273+ break ;
274+
265275 default :
266276 elog (ERROR , "unrecognized node type: %d" ,
267277 (int ) nodeTag (element ));
268278 break ;
269279 }
270280 }
271281
282+ if (like_found )
283+ {
284+ /*
285+ * To match INHERITS, the existance of any LIKE table with OIDs
286+ * causes the new table to have oids. For the same reason,
287+ * WITH/WITHOUT OIDs is also ignored with LIKE. We prepend
288+ * because the first oid option list entry is honored. Our
289+ * prepended WITHOUT OIDS clause will be overridden if an
290+ * inherited table has oids.
291+ */
292+ stmt -> options = lcons (makeDefElem ("oids" ,
293+ (Node * )makeInteger (cxt .hasoids )), stmt -> options );
294+ }
295+
296+ foreach (elements , stmt -> tableElts )
297+ {
298+ Node * element = lfirst (elements );
299+
300+ if (nodeTag (element ) == T_Constraint )
301+ transformTableConstraint (& cxt , (Constraint * ) element );
302+ }
272303 /*
273304 * transformIndexConstraints wants cxt.alist to contain only index
274305 * statements, so transfer anything we already have into save_alist.
@@ -860,6 +891,9 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
860891 }
861892 }
862893
894+ /* We use oids if at least one LIKE'ed table has oids. */
895+ cxt -> hasoids = cxt -> hasoids || relation -> rd_rel -> relhasoids ;
896+
863897 /*
864898 * Copy CHECK constraints if requested, being careful to adjust attribute
865899 * numbers so they match the child.
0 commit comments