diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index fd7a9ed..4b28bfd 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -2395,6 +2395,8 @@ OpenIntoRel(QueryDesc *queryDesc) Datum reloptions; Oid intoRelationId; DR_intorel *myState; + RangeTblEntry *rte; + AttrNumber attnum; static char *validnsps[] = HEAP_RELOPT_NAMESPACES; Assert(into); @@ -2517,6 +2519,21 @@ OpenIntoRel(QueryDesc *queryDesc) intoRelationDesc = heap_open(intoRelationId, AccessExclusiveLock); /* + * check INSERT permission on the constructed table. + */ + rte = makeNode(RangeTblEntry); + rte->rtekind = RTE_RELATION; + rte->relid = intoRelationId; + rte->relkind = RELKIND_RELATION; + rte->requiredPerms = ACL_INSERT; + + for (attnum = 0; attnum < queryDesc->tupDesc->natts; attnum++) + rte->modifiedCols = bms_add_member(rte->modifiedCols, + attnum - FirstLowInvalidHeapAttributeNumber); + + ExecCheckRTPerms(list_make1(rte), true); + + /* * Now replace the query's DestReceiver with one for SELECT INTO */ queryDesc->dest = CreateDestReceiver(DestIntoRel); diff --git a/src/test/regress/expected/select_into.out b/src/test/regress/expected/select_into.out index 503efe0..777268e 100644 --- a/src/test/regress/expected/select_into.out +++ b/src/test/regress/expected/select_into.out @@ -11,3 +11,17 @@ SELECT * FROM onek2 WHERE onek2.unique1 < 2; DROP TABLE tmp1; +-- +-- SELECT INTO and INSERT permission, if owner is not allowed to insert. +-- +CREATE SCHEMA selinto_schema; +CREATE USER selinto_user; +ALTER DEFAULT PRIVILEGES IN SCHEMA selinto_schema + REVOKE INSERT ON TABLES FROM selinto_user; +SET SESSION AUTHORIZATION selinto_user; +SELECT * INTO TABLE selinto_schema.tmp1 + FROM onek WHERE onek.unique1 < 2; -- Error +ERROR: permission denied for relation onek +RESET SESSION AUTHORIZATION; +DROP SCHEMA selinto_schema CASCADE; +DROP USER selinto_user; diff --git a/src/test/regress/sql/select_into.sql b/src/test/regress/sql/select_into.sql index 2fa3d1e..4b4ff1c 100644 --- a/src/test/regress/sql/select_into.sql +++ b/src/test/regress/sql/select_into.sql @@ -15,3 +15,19 @@ SELECT * WHERE onek2.unique1 < 2; DROP TABLE tmp1; + +-- +-- SELECT INTO and INSERT permission, if owner is not allowed to insert. +-- +CREATE SCHEMA selinto_schema; +CREATE USER selinto_user; +ALTER DEFAULT PRIVILEGES IN SCHEMA selinto_schema + REVOKE INSERT ON TABLES FROM selinto_user; + +SET SESSION AUTHORIZATION selinto_user; +SELECT * INTO TABLE selinto_schema.tmp1 + FROM onek WHERE onek.unique1 < 2; -- Error +RESET SESSION AUTHORIZATION; + +DROP SCHEMA selinto_schema CASCADE; +DROP USER selinto_user;