aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/aclchk.c10
-rw-r--r--src/backend/catalog/pg_shdepend.c4
-rw-r--r--src/backend/commands/alter.c22
-rw-r--r--src/backend/libpq/be-fsstubs.c4
-rw-r--r--src/backend/storage/large_object/inv_api.c9
-rw-r--r--src/test/regress/expected/largeobject.out5
-rw-r--r--src/test/regress/expected/largeobject_1.out5
-rw-r--r--src/test/regress/sql/largeobject.sql8
8 files changed, 50 insertions, 17 deletions
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index d1f5dcd8bed..a2aad09e6a0 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -3967,9 +3967,14 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid)
if (superuser_arg(roleid))
return true;
+ /* For large objects, the catalog to consult is pg_largeobject_metadata */
+ if (classid == LargeObjectRelationId)
+ classid = LargeObjectMetadataRelationId;
+
cacheid = get_object_catcache_oid(classid);
if (cacheid != -1)
{
+ /* we can get the object's tuple from the syscache */
HeapTuple tuple;
tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
@@ -3986,7 +3991,6 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid)
else
{
/* for catalogs without an appropriate syscache */
-
Relation rel;
ScanKeyData entry[1];
SysScanDesc scan;
@@ -4306,9 +4310,9 @@ recordExtObjInitPriv(Oid objoid, Oid classoid)
ReleaseSysCache(tuple);
}
- /* pg_largeobject_metadata */
- else if (classoid == LargeObjectMetadataRelationId)
+ else if (classoid == LargeObjectRelationId)
{
+ /* For large objects, we must consult pg_largeobject_metadata */
Datum aclDatum;
bool isNull;
HeapTuple tuple;
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index 91c7f3426f9..ea41d9b7502 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -1618,6 +1618,10 @@ shdepReassignOwned(List *roleids, Oid newrole)
Oid classId = sdepForm->classid;
Relation catalog;
+ /*
+ * For large objects, the catalog to modify is
+ * pg_largeobject_metadata
+ */
if (classId == LargeObjectRelationId)
classId = LargeObjectMetadataRelationId;
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index e95dc31bde3..cbe02853b04 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -929,9 +929,8 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
classId = address.classId;
/*
- * XXX - get_object_address returns Oid of pg_largeobject
- * catalog for OBJECT_LARGEOBJECT because of historical
- * reasons. Fix up it here.
+ * For large objects, the catalog to modify is
+ * pg_largeobject_metadata
*/
if (classId == LargeObjectRelationId)
classId = LargeObjectMetadataRelationId;
@@ -1075,9 +1074,14 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
/* Perform actual update */
CatalogTupleUpdate(rel, &newtup->t_self, newtup);
- /* Update owner dependency reference */
+ /*
+ * Update owner dependency reference. When working on a large object,
+ * we have to translate back to the OID conventionally used for LOs'
+ * classId.
+ */
if (classId == LargeObjectMetadataRelationId)
classId = LargeObjectRelationId;
+
changeDependencyOnOwner(classId, objectId, new_ownerId);
/* Release memory */
@@ -1085,6 +1089,16 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
pfree(nulls);
pfree(replaces);
}
+ else
+ {
+ /*
+ * No need to change anything. But when working on a large object, we
+ * have to translate back to the OID conventionally used for LOs'
+ * classId, or the post-alter hook (if any) will get confused.
+ */
+ if (classId == LargeObjectMetadataRelationId)
+ classId = LargeObjectRelationId;
+ }
InvokeObjectPostAlterHook(classId, objectId, 0);
}
diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c
index d189044a4fc..230c6575320 100644
--- a/src/backend/libpq/be-fsstubs.c
+++ b/src/backend/libpq/be-fsstubs.c
@@ -43,7 +43,7 @@
#include <unistd.h>
#include "access/xact.h"
-#include "catalog/pg_largeobject_metadata.h"
+#include "catalog/pg_largeobject.h"
#include "libpq/be-fsstubs.h"
#include "libpq/libpq-fs.h"
#include "miscadmin.h"
@@ -323,7 +323,7 @@ be_lo_unlink(PG_FUNCTION_ARGS)
* relevant FDs.
*/
if (!lo_compat_privileges &&
- !object_ownercheck(LargeObjectMetadataRelationId, lobjId, GetUserId()))
+ !object_ownercheck(LargeObjectRelationId, lobjId, GetUserId()))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be owner of large object %u", lobjId)));
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index 84e543e7310..cab47f82fb6 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -221,11 +221,10 @@ inv_create(Oid lobjId)
/*
* dependency on the owner of largeobject
*
- * The reason why we use LargeObjectRelationId instead of
- * LargeObjectMetadataRelationId here is to provide backward compatibility
- * to the applications which utilize a knowledge about internal layout of
- * system catalogs. OID of pg_largeobject_metadata and loid of
- * pg_largeobject are same value, so there are no actual differences here.
+ * Note that LO dependencies are recorded using classId
+ * LargeObjectRelationId for backwards-compatibility reasons. Using
+ * LargeObjectMetadataRelationId instead would simplify matters for the
+ * backend, but it'd complicate pg_dump and possibly break other clients.
*/
recordDependencyOnOwner(LargeObjectRelationId,
lobjId_new, GetUserId());
diff --git a/src/test/regress/expected/largeobject.out b/src/test/regress/expected/largeobject.out
index bdcede6728e..4921dd79aee 100644
--- a/src/test/regress/expected/largeobject.out
+++ b/src/test/regress/expected/largeobject.out
@@ -6,7 +6,7 @@
\getenv abs_builddir PG_ABS_BUILDDIR
-- ensure consistent test output regardless of the default bytea format
SET bytea_output TO escape;
--- Test ALTER LARGE OBJECT OWNER, GRANT, COMMENT
+-- Test ALTER LARGE OBJECT OWNER
CREATE ROLE regress_lo_user;
SELECT lo_create(42);
lo_create
@@ -15,8 +15,11 @@ SELECT lo_create(42);
(1 row)
ALTER LARGE OBJECT 42 OWNER TO regress_lo_user;
+-- Test GRANT, COMMENT as non-superuser
+SET SESSION AUTHORIZATION regress_lo_user;
GRANT SELECT ON LARGE OBJECT 42 TO public;
COMMENT ON LARGE OBJECT 42 IS 'the ultimate answer';
+RESET SESSION AUTHORIZATION;
-- Test psql's \lo_list et al (we assume no other LOs exist yet)
\lo_list
Large objects
diff --git a/src/test/regress/expected/largeobject_1.out b/src/test/regress/expected/largeobject_1.out
index d700910c359..7172ddb39bb 100644
--- a/src/test/regress/expected/largeobject_1.out
+++ b/src/test/regress/expected/largeobject_1.out
@@ -6,7 +6,7 @@
\getenv abs_builddir PG_ABS_BUILDDIR
-- ensure consistent test output regardless of the default bytea format
SET bytea_output TO escape;
--- Test ALTER LARGE OBJECT OWNER, GRANT, COMMENT
+-- Test ALTER LARGE OBJECT OWNER
CREATE ROLE regress_lo_user;
SELECT lo_create(42);
lo_create
@@ -15,8 +15,11 @@ SELECT lo_create(42);
(1 row)
ALTER LARGE OBJECT 42 OWNER TO regress_lo_user;
+-- Test GRANT, COMMENT as non-superuser
+SET SESSION AUTHORIZATION regress_lo_user;
GRANT SELECT ON LARGE OBJECT 42 TO public;
COMMENT ON LARGE OBJECT 42 IS 'the ultimate answer';
+RESET SESSION AUTHORIZATION;
-- Test psql's \lo_list et al (we assume no other LOs exist yet)
\lo_list
Large objects
diff --git a/src/test/regress/sql/largeobject.sql b/src/test/regress/sql/largeobject.sql
index 800e4fcc6a2..a4aee02e3a4 100644
--- a/src/test/regress/sql/largeobject.sql
+++ b/src/test/regress/sql/largeobject.sql
@@ -9,13 +9,19 @@
-- ensure consistent test output regardless of the default bytea format
SET bytea_output TO escape;
--- Test ALTER LARGE OBJECT OWNER, GRANT, COMMENT
+-- Test ALTER LARGE OBJECT OWNER
CREATE ROLE regress_lo_user;
SELECT lo_create(42);
ALTER LARGE OBJECT 42 OWNER TO regress_lo_user;
+
+-- Test GRANT, COMMENT as non-superuser
+SET SESSION AUTHORIZATION regress_lo_user;
+
GRANT SELECT ON LARGE OBJECT 42 TO public;
COMMENT ON LARGE OBJECT 42 IS 'the ultimate answer';
+RESET SESSION AUTHORIZATION;
+
-- Test psql's \lo_list et al (we assume no other LOs exist yet)
\lo_list
\lo_list+