mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
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
This commit is contained in:
parent
28b3a3d41a
commit
b943f502b7
@ -56,6 +56,7 @@
|
|||||||
#include "rewrite/rewriteManip.h"
|
#include "rewrite/rewriteManip.h"
|
||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/guc.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
@ -150,6 +151,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
|
|||||||
Oid namespaceid;
|
Oid namespaceid;
|
||||||
Oid existing_relid;
|
Oid existing_relid;
|
||||||
ParseCallbackState pcbstate;
|
ParseCallbackState pcbstate;
|
||||||
|
bool like_found = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must not scribble on the passed-in CreateStmt, so copy it. (This is
|
* 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
|
* 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)
|
foreach(elements, stmt->tableElts)
|
||||||
{
|
{
|
||||||
@ -254,12 +259,17 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
|
|||||||
transformColumnDefinition(&cxt, (ColumnDef *) element);
|
transformColumnDefinition(&cxt, (ColumnDef *) element);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_Constraint:
|
case T_TableLikeClause:
|
||||||
transformTableConstraint(&cxt, (Constraint *) element);
|
if (!like_found)
|
||||||
|
{
|
||||||
|
cxt.hasoids = false;
|
||||||
|
like_found = true;
|
||||||
|
}
|
||||||
|
transformTableLikeClause(&cxt, (TableLikeClause *) element);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_TableLikeClause:
|
case T_Constraint:
|
||||||
transformTableLikeClause(&cxt, (TableLikeClause *) element);
|
/* process later */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -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
|
* transformIndexConstraints wants cxt.alist to contain only index
|
||||||
* statements, so transfer anything we already have into save_alist.
|
* 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
|
* Copy CHECK constraints if requested, being careful to adjust attribute
|
||||||
* numbers so they match the child.
|
* numbers so they match the child.
|
||||||
|
@ -250,3 +250,6 @@ ERROR: relation "as_select1" already exists
|
|||||||
CREATE TABLE IF NOT EXISTS 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';
|
||||||
NOTICE: relation "as_select1" already exists, skipping
|
NOTICE: relation "as_select1" already exists, skipping
|
||||||
DROP TABLE as_select1;
|
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;
|
||||||
|
@ -228,3 +228,30 @@ DROP TYPE ctlty1;
|
|||||||
DROP VIEW ctlv1;
|
DROP VIEW ctlv1;
|
||||||
DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12;
|
DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12;
|
||||||
NOTICE: table "ctlt10" does not exist, skipping
|
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;
|
||||||
|
@ -265,3 +265,7 @@ CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
|
|||||||
CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
|
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';
|
CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
|
||||||
DROP TABLE as_select1;
|
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;
|
||||||
|
@ -119,3 +119,16 @@ DROP SEQUENCE ctlseq1;
|
|||||||
DROP TYPE ctlty1;
|
DROP TYPE ctlty1;
|
||||||
DROP VIEW ctlv1;
|
DROP VIEW ctlv1;
|
||||||
DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12;
|
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user