On Tue, Apr 28, 2015 at 09:15:49AM -0400, Bruce Momjian wrote:
> > It seems to me that waiting for 9.6 for what's arguably a bug fix is too
> > much.  It's not like this is a new feature.  Why don't we just make sure
> > it is as correct as possible and get it done for 9.5?  It's not even in
> > beta yet, nor feature freeze.
> 
> Well, I applied what I thought would work, but did not handle three
> cases:
> 
> *  checking of hasoids by index specifications
> *  queries with multiple LIKE'ed tables
> *  matching inheritance behavior
> 
> I am unclear if I should be addressing such complex issues at this point
> in the development cycle.  I can certainly apply this patch, but I need
> someone else to tell me it is good and should be applied.  I am also
> thinking such review time would be better spent on patches submitted
> long before mine.

I have added regression tests to the patch, attached.  I have included
Tom's test that doesn't directly use LIKE.

-- 
  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 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;
-- 
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