On Sat, Apr 25, 2015 at 11:11:52PM -0400, Tom Lane wrote:
> Hm, good point; INHERITS will silently override such a specification:
> 
> regression=# create table base1 (f1 int) with oids;
> CREATE TABLE
> regression=# create table c2 () inherits (base1) without oids;
> CREATE TABLE
> regression=# \d+ c2
>                           Table "public.c2"
>  Column |  Type   | Modifiers | Storage | Stats target | Description 
> --------+---------+-----------+---------+--------------+-------------
>  f1     | integer |           | plain   |              | 
> Inherits: base1
> Has OIDs: yes
> 
> > Though I guess unlike inherits there is no
> > reason to mandate the final result be identical to the base table - though
> > here is something to be said for pointing out the inconsistency and
> > requiring the user to alter table if indeed they want to have the oid-ness
> > changed.
> 
> Yeah, LIKE doesn't necessarily have to behave the same as INHERITS;
> but probably we should follow that precedent unless we have a specific
> argument not to.  Which I don't.

Agreed.  Here is an attached patch for 9.6 which works for multiple
LIKE'ed tables with multiple inheritance and index creation.  I figured
out why Tom's OID primary key test was failing so I now process the
columns and LIKE first, then the constraints.  There is also no longer a
dependency on default_with_oids.

-- 
  Bruce Momjian  <br...@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + Everyone has their own god. +
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
new file mode 100644
index 73924ae..d442bb0
*** 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.
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to