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 <[email protected]> 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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers