mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Allow CREATE TABLE (LIKE ...) from composite type
The only reason this didn't work before was that parserOpenTable() rejects composite types. So use relation_openrv() directly and manually do the errposition() setup that parserOpenTable() does.
This commit is contained in:
parent
d923125b77
commit
b59ca98209
@ -370,7 +370,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
|
|||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
The <literal>LIKE</literal> clause can also be used to copy columns from
|
The <literal>LIKE</literal> clause can also be used to copy columns from
|
||||||
views or foreign tables. Inapplicable options (e.g., <literal>INCLUDING
|
views, foreign tables, or composite types. Inapplicable options (e.g., <literal>INCLUDING
|
||||||
INDEXES</literal> from a view) are ignored.
|
INDEXES</literal> from a view) are ignored.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
@ -636,26 +636,42 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
|
|||||||
TupleConstr *constr;
|
TupleConstr *constr;
|
||||||
AclResult aclresult;
|
AclResult aclresult;
|
||||||
char *comment;
|
char *comment;
|
||||||
|
ParseCallbackState pcbstate;
|
||||||
|
|
||||||
relation = parserOpenTable(cxt->pstate, table_like_clause->relation,
|
setup_parser_errposition_callback(&pcbstate, cxt->pstate, table_like_clause->relation->location);
|
||||||
AccessShareLock);
|
|
||||||
|
relation = relation_openrv(table_like_clause->relation, AccessShareLock);
|
||||||
|
|
||||||
if (relation->rd_rel->relkind != RELKIND_RELATION
|
if (relation->rd_rel->relkind != RELKIND_RELATION
|
||||||
&& relation->rd_rel->relkind != RELKIND_VIEW
|
&& relation->rd_rel->relkind != RELKIND_VIEW
|
||||||
&& relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE)
|
&& relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE
|
||||||
|
&& relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
errmsg("LIKE source relation \"%s\" is not a table, view, or foreign table",
|
errmsg("\"%s\" is not a table, view, composite type, or foreign table",
|
||||||
table_like_clause->relation->relname)));
|
table_like_clause->relation->relname)));
|
||||||
|
|
||||||
|
cancel_parser_errposition_callback(&pcbstate);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for SELECT privileges
|
* Check for privileges
|
||||||
*/
|
*/
|
||||||
aclresult = pg_class_aclcheck(RelationGetRelid(relation), GetUserId(),
|
if (relation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
|
||||||
|
{
|
||||||
|
aclresult = pg_type_aclcheck(relation->rd_rel->reltype, GetUserId(),
|
||||||
|
ACL_USAGE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, ACL_KIND_TYPE,
|
||||||
|
RelationGetRelationName(relation));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aclresult = pg_class_aclcheck(RelationGetRelid(relation), GetUserId(),
|
||||||
ACL_SELECT);
|
ACL_SELECT);
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
aclcheck_error(aclresult, ACL_KIND_CLASS,
|
aclcheck_error(aclresult, ACL_KIND_CLASS,
|
||||||
RelationGetRelationName(relation));
|
RelationGetRelationName(relation));
|
||||||
|
}
|
||||||
|
|
||||||
tupleDesc = RelationGetDescr(relation);
|
tupleDesc = RelationGetDescr(relation);
|
||||||
constr = tupleDesc->constr;
|
constr = tupleDesc->constr;
|
||||||
|
@ -8,6 +8,10 @@ CREATE TABLE inhx (xx text DEFAULT 'text');
|
|||||||
*/
|
*/
|
||||||
CREATE TABLE ctla (aa TEXT);
|
CREATE TABLE ctla (aa TEXT);
|
||||||
CREATE TABLE ctlb (bb TEXT) INHERITS (ctla);
|
CREATE TABLE ctlb (bb TEXT) INHERITS (ctla);
|
||||||
|
CREATE TABLE foo (LIKE nonexistent);
|
||||||
|
ERROR: relation "nonexistent" does not exist
|
||||||
|
LINE 1: CREATE TABLE foo (LIKE nonexistent);
|
||||||
|
^
|
||||||
CREATE TABLE inhe (ee text, LIKE inhx) inherits (ctlb);
|
CREATE TABLE inhe (ee text, LIKE inhx) inherits (ctlb);
|
||||||
INSERT INTO inhe VALUES ('ee-col1', 'ee-col2', DEFAULT, 'ee-col4');
|
INSERT INTO inhe VALUES ('ee-col1', 'ee-col2', DEFAULT, 'ee-col4');
|
||||||
SELECT * FROM inhe; /* Columns aa, bb, xx value NULL, ee */
|
SELECT * FROM inhe; /* Columns aa, bb, xx value NULL, ee */
|
||||||
@ -224,18 +228,16 @@ NOTICE: drop cascades to table inhe
|
|||||||
CREATE TABLE ctlt4 (a int, b text);
|
CREATE TABLE ctlt4 (a int, b text);
|
||||||
CREATE SEQUENCE ctlseq1;
|
CREATE SEQUENCE ctlseq1;
|
||||||
CREATE TABLE ctlt10 (LIKE ctlseq1); -- fail
|
CREATE TABLE ctlt10 (LIKE ctlseq1); -- fail
|
||||||
ERROR: LIKE source relation "ctlseq1" is not a table, view, or foreign table
|
ERROR: "ctlseq1" is not a table, view, composite type, or foreign table
|
||||||
|
LINE 1: CREATE TABLE ctlt10 (LIKE ctlseq1);
|
||||||
|
^
|
||||||
CREATE VIEW ctlv1 AS SELECT * FROM ctlt4;
|
CREATE VIEW ctlv1 AS SELECT * FROM ctlt4;
|
||||||
CREATE TABLE ctlt11 (LIKE ctlv1);
|
CREATE TABLE ctlt11 (LIKE ctlv1);
|
||||||
CREATE TABLE ctlt11a (LIKE ctlv1 INCLUDING ALL);
|
CREATE TABLE ctlt11a (LIKE ctlv1 INCLUDING ALL);
|
||||||
CREATE TYPE ctlty1 AS (a int, b text);
|
CREATE TYPE ctlty1 AS (a int, b text);
|
||||||
CREATE TABLE ctlt12 (LIKE ctlty1); -- currently fails
|
CREATE TABLE ctlt12 (LIKE ctlty1);
|
||||||
ERROR: "ctlty1" is a composite type
|
|
||||||
LINE 1: CREATE TABLE ctlt12 (LIKE ctlty1);
|
|
||||||
^
|
|
||||||
DROP SEQUENCE ctlseq1;
|
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;
|
||||||
NOTICE: table "ctlt10" does not exist, skipping
|
NOTICE: table "ctlt10" does not exist, skipping
|
||||||
NOTICE: table "ctlt12" does not exist, skipping
|
|
||||||
|
@ -10,6 +10,8 @@ CREATE TABLE inhx (xx text DEFAULT 'text');
|
|||||||
CREATE TABLE ctla (aa TEXT);
|
CREATE TABLE ctla (aa TEXT);
|
||||||
CREATE TABLE ctlb (bb TEXT) INHERITS (ctla);
|
CREATE TABLE ctlb (bb TEXT) INHERITS (ctla);
|
||||||
|
|
||||||
|
CREATE TABLE foo (LIKE nonexistent);
|
||||||
|
|
||||||
CREATE TABLE inhe (ee text, LIKE inhx) inherits (ctlb);
|
CREATE TABLE inhe (ee text, LIKE inhx) inherits (ctlb);
|
||||||
INSERT INTO inhe VALUES ('ee-col1', 'ee-col2', DEFAULT, 'ee-col4');
|
INSERT INTO inhe VALUES ('ee-col1', 'ee-col2', DEFAULT, 'ee-col4');
|
||||||
SELECT * FROM inhe; /* Columns aa, bb, xx value NULL, ee */
|
SELECT * FROM inhe; /* Columns aa, bb, xx value NULL, ee */
|
||||||
@ -111,7 +113,7 @@ CREATE TABLE ctlt11 (LIKE ctlv1);
|
|||||||
CREATE TABLE ctlt11a (LIKE ctlv1 INCLUDING ALL);
|
CREATE TABLE ctlt11a (LIKE ctlv1 INCLUDING ALL);
|
||||||
|
|
||||||
CREATE TYPE ctlty1 AS (a int, b text);
|
CREATE TYPE ctlty1 AS (a int, b text);
|
||||||
CREATE TABLE ctlt12 (LIKE ctlty1); -- currently fails
|
CREATE TABLE ctlt12 (LIKE ctlty1);
|
||||||
|
|
||||||
DROP SEQUENCE ctlseq1;
|
DROP SEQUENCE ctlseq1;
|
||||||
DROP TYPE ctlty1;
|
DROP TYPE ctlty1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user