pgsql-v9.2-add-select-into-checks.v2.patch
application/octet-stream
Filename: pgsql-v9.2-add-select-into-checks.v2.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v9
| File | + | − |
|---|---|---|
| src/backend/executor/execMain.c | 17 | 0 |
| src/test/regress/expected/select_into.out | 39 | 0 |
| src/test/regress/sql/select_into.sql | 37 | 0 |
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index fd7a9ed..708831a 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 = 1; 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..9ed4229 100644
--- a/src/test/regress/expected/select_into.out
+++ b/src/test/regress/expected/select_into.out
@@ -11,3 +11,42 @@ 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 FOR ROLE selinto_user
+ REVOKE INSERT ON TABLES FROM selinto_user;
+GRANT ALL ON SCHEMA selinto_schema TO public;
+SET SESSION AUTHORIZATION selinto_user;
+SELECT * INTO TABLE selinto_schema.tmp1
+ FROM pg_class WHERE relname like '%a%'; -- Error
+ERROR: permission denied for relation tmp1
+SELECT oid AS clsoid, relname, relnatts + 10 AS x
+ INTO selinto_schema.tmp2
+ FROM pg_class WHERE relname like '%b%'; -- Error
+ERROR: permission denied for relation tmp2
+CREATE TABLE selinto_schema.tmp3 (a,b,c)
+ AS SELECT oid,relname,relacl FROM pg_class
+ WHERE relname like '%c%'; -- Error
+ERROR: permission denied for relation tmp3
+RESET SESSION AUTHORIZATION;
+ALTER DEFAULT PRIVILEGES FOR ROLE selinto_user
+ GRANT INSERT ON TABLES TO selinto_user;
+SET SESSION AUTHORIZATION selinto_user;
+SELECT * INTO TABLE selinto_schema.tmp1
+ FROM pg_class WHERE relname like '%a%'; -- OK
+SELECT oid AS clsoid, relname, relnatts + 10 AS x
+ INTO selinto_schema.tmp2
+ FROM pg_class WHERE relname like '%b%'; -- OK
+CREATE TABLE selinto_schema.tmp3 (a,b,c)
+ AS SELECT oid,relname,relacl FROM pg_class
+ WHERE relname like '%c%'; -- OK
+RESET SESSION AUTHORIZATION;
+DROP SCHEMA selinto_schema CASCADE;
+NOTICE: drop cascades to 3 other objects
+DETAIL: drop cascades to table selinto_schema.tmp1
+drop cascades to table selinto_schema.tmp2
+drop cascades to table selinto_schema.tmp3
+DROP USER selinto_user;
diff --git a/src/test/regress/sql/select_into.sql b/src/test/regress/sql/select_into.sql
index 2fa3d1e..039d35c 100644
--- a/src/test/regress/sql/select_into.sql
+++ b/src/test/regress/sql/select_into.sql
@@ -15,3 +15,40 @@ 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 FOR ROLE selinto_user
+ REVOKE INSERT ON TABLES FROM selinto_user;
+GRANT ALL ON SCHEMA selinto_schema TO public;
+
+SET SESSION AUTHORIZATION selinto_user;
+SELECT * INTO TABLE selinto_schema.tmp1
+ FROM pg_class WHERE relname like '%a%'; -- Error
+SELECT oid AS clsoid, relname, relnatts + 10 AS x
+ INTO selinto_schema.tmp2
+ FROM pg_class WHERE relname like '%b%'; -- Error
+CREATE TABLE selinto_schema.tmp3 (a,b,c)
+ AS SELECT oid,relname,relacl FROM pg_class
+ WHERE relname like '%c%'; -- Error
+RESET SESSION AUTHORIZATION;
+
+ALTER DEFAULT PRIVILEGES FOR ROLE selinto_user
+ GRANT INSERT ON TABLES TO selinto_user;
+
+SET SESSION AUTHORIZATION selinto_user;
+SELECT * INTO TABLE selinto_schema.tmp1
+ FROM pg_class WHERE relname like '%a%'; -- OK
+SELECT oid AS clsoid, relname, relnatts + 10 AS x
+ INTO selinto_schema.tmp2
+ FROM pg_class WHERE relname like '%b%'; -- OK
+CREATE TABLE selinto_schema.tmp3 (a,b,c)
+ AS SELECT oid,relname,relacl FROM pg_class
+ WHERE relname like '%c%'; -- OK
+RESET SESSION AUTHORIZATION;
+
+DROP SCHEMA selinto_schema CASCADE;
+DROP USER selinto_user;