mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 00:01:55 -04:00
Compare commits
No commits in common. "b485ad7f07c80efbfd47329f138f0fe3a5acf013" and "0e917508b89dd21c5bcd9183e77585f01055a20d" have entirely different histories.
b485ad7f07
...
0e917508b8
@ -4103,14 +4103,9 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid)
|
|||||||
if (superuser_arg(roleid))
|
if (superuser_arg(roleid))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* For large objects, the catalog to consult is pg_largeobject_metadata */
|
|
||||||
if (classid == LargeObjectRelationId)
|
|
||||||
classid = LargeObjectMetadataRelationId;
|
|
||||||
|
|
||||||
cacheid = get_object_catcache_oid(classid);
|
cacheid = get_object_catcache_oid(classid);
|
||||||
if (cacheid != -1)
|
if (cacheid != -1)
|
||||||
{
|
{
|
||||||
/* we can get the object's tuple from the syscache */
|
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
|
||||||
tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
|
tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid));
|
||||||
@ -4127,6 +4122,7 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* for catalogs without an appropriate syscache */
|
/* for catalogs without an appropriate syscache */
|
||||||
|
|
||||||
Relation rel;
|
Relation rel;
|
||||||
ScanKeyData entry[1];
|
ScanKeyData entry[1];
|
||||||
SysScanDesc scan;
|
SysScanDesc scan;
|
||||||
@ -4446,9 +4442,9 @@ recordExtObjInitPriv(Oid objoid, Oid classoid)
|
|||||||
|
|
||||||
ReleaseSysCache(tuple);
|
ReleaseSysCache(tuple);
|
||||||
}
|
}
|
||||||
else if (classoid == LargeObjectRelationId)
|
/* pg_largeobject_metadata */
|
||||||
|
else if (classoid == LargeObjectMetadataRelationId)
|
||||||
{
|
{
|
||||||
/* For large objects, we must consult pg_largeobject_metadata */
|
|
||||||
Datum aclDatum;
|
Datum aclDatum;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
@ -1614,9 +1614,20 @@ shdepReassignOwned(List *roleids, Oid newrole)
|
|||||||
case DatabaseRelationId:
|
case DatabaseRelationId:
|
||||||
case TSConfigRelationId:
|
case TSConfigRelationId:
|
||||||
case TSDictionaryRelationId:
|
case TSDictionaryRelationId:
|
||||||
AlterObjectOwner_internal(sdepForm->classid,
|
{
|
||||||
sdepForm->objid,
|
Oid classId = sdepForm->classid;
|
||||||
newrole);
|
Relation catalog;
|
||||||
|
|
||||||
|
if (classId == LargeObjectRelationId)
|
||||||
|
classId = LargeObjectMetadataRelationId;
|
||||||
|
|
||||||
|
catalog = table_open(classId, RowExclusiveLock);
|
||||||
|
|
||||||
|
AlterObjectOwner_internal(catalog, sdepForm->objid,
|
||||||
|
newrole);
|
||||||
|
|
||||||
|
table_close(catalog, NoLock);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -918,7 +918,9 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
|
|||||||
case OBJECT_TSDICTIONARY:
|
case OBJECT_TSDICTIONARY:
|
||||||
case OBJECT_TSCONFIGURATION:
|
case OBJECT_TSCONFIGURATION:
|
||||||
{
|
{
|
||||||
|
Relation catalog;
|
||||||
Relation relation;
|
Relation relation;
|
||||||
|
Oid classId;
|
||||||
ObjectAddress address;
|
ObjectAddress address;
|
||||||
|
|
||||||
address = get_object_address(stmt->objectType,
|
address = get_object_address(stmt->objectType,
|
||||||
@ -927,9 +929,20 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
|
|||||||
AccessExclusiveLock,
|
AccessExclusiveLock,
|
||||||
false);
|
false);
|
||||||
Assert(relation == NULL);
|
Assert(relation == NULL);
|
||||||
|
classId = address.classId;
|
||||||
|
|
||||||
AlterObjectOwner_internal(address.classId, address.objectId,
|
/*
|
||||||
newowner);
|
* XXX - get_object_address returns Oid of pg_largeobject
|
||||||
|
* catalog for OBJECT_LARGEOBJECT because of historical
|
||||||
|
* reasons. Fix up it here.
|
||||||
|
*/
|
||||||
|
if (classId == LargeObjectRelationId)
|
||||||
|
classId = LargeObjectMetadataRelationId;
|
||||||
|
|
||||||
|
catalog = table_open(classId, RowExclusiveLock);
|
||||||
|
|
||||||
|
AlterObjectOwner_internal(catalog, address.objectId, newowner);
|
||||||
|
table_close(catalog, RowExclusiveLock);
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
@ -947,32 +960,25 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
|
|||||||
* cases (won't work for tables, nor other cases where we need to do more than
|
* cases (won't work for tables, nor other cases where we need to do more than
|
||||||
* change the ownership column of a single catalog entry).
|
* change the ownership column of a single catalog entry).
|
||||||
*
|
*
|
||||||
* classId: OID of catalog containing object
|
* rel: catalog relation containing object (RowExclusiveLock'd by caller)
|
||||||
* objectId: OID of object to change the ownership of
|
* objectId: OID of object to change the ownership of
|
||||||
* new_ownerId: OID of new object owner
|
* new_ownerId: OID of new object owner
|
||||||
*
|
|
||||||
* This will work on large objects, but we have to beware of the fact that
|
|
||||||
* classId isn't the OID of the catalog to modify in that case.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
AlterObjectOwner_internal(Oid classId, Oid objectId, Oid new_ownerId)
|
AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
|
||||||
{
|
{
|
||||||
/* For large objects, the catalog to modify is pg_largeobject_metadata */
|
Oid classId = RelationGetRelid(rel);
|
||||||
Oid catalogId = (classId == LargeObjectRelationId) ? LargeObjectMetadataRelationId : classId;
|
AttrNumber Anum_oid = get_object_attnum_oid(classId);
|
||||||
AttrNumber Anum_oid = get_object_attnum_oid(catalogId);
|
AttrNumber Anum_owner = get_object_attnum_owner(classId);
|
||||||
AttrNumber Anum_owner = get_object_attnum_owner(catalogId);
|
AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
|
||||||
AttrNumber Anum_namespace = get_object_attnum_namespace(catalogId);
|
AttrNumber Anum_acl = get_object_attnum_acl(classId);
|
||||||
AttrNumber Anum_acl = get_object_attnum_acl(catalogId);
|
AttrNumber Anum_name = get_object_attnum_name(classId);
|
||||||
AttrNumber Anum_name = get_object_attnum_name(catalogId);
|
|
||||||
Relation rel;
|
|
||||||
HeapTuple oldtup;
|
HeapTuple oldtup;
|
||||||
Datum datum;
|
Datum datum;
|
||||||
bool isnull;
|
bool isnull;
|
||||||
Oid old_ownerId;
|
Oid old_ownerId;
|
||||||
Oid namespaceId = InvalidOid;
|
Oid namespaceId = InvalidOid;
|
||||||
|
|
||||||
rel = table_open(catalogId, RowExclusiveLock);
|
|
||||||
|
|
||||||
oldtup = get_catalog_object_by_oid(rel, Anum_oid, objectId);
|
oldtup = get_catalog_object_by_oid(rel, Anum_oid, objectId);
|
||||||
if (oldtup == NULL)
|
if (oldtup == NULL)
|
||||||
elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
|
elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
|
||||||
@ -1020,8 +1026,7 @@ AlterObjectOwner_internal(Oid classId, Oid objectId, Oid new_ownerId)
|
|||||||
snprintf(namebuf, sizeof(namebuf), "%u", objectId);
|
snprintf(namebuf, sizeof(namebuf), "%u", objectId);
|
||||||
objname = namebuf;
|
objname = namebuf;
|
||||||
}
|
}
|
||||||
aclcheck_error(ACLCHECK_NOT_OWNER,
|
aclcheck_error(ACLCHECK_NOT_OWNER, get_object_type(classId, objectId),
|
||||||
get_object_type(catalogId, objectId),
|
|
||||||
objname);
|
objname);
|
||||||
}
|
}
|
||||||
/* Must be able to become new owner */
|
/* Must be able to become new owner */
|
||||||
@ -1074,6 +1079,8 @@ AlterObjectOwner_internal(Oid classId, Oid objectId, Oid new_ownerId)
|
|||||||
CatalogTupleUpdate(rel, &newtup->t_self, newtup);
|
CatalogTupleUpdate(rel, &newtup->t_self, newtup);
|
||||||
|
|
||||||
/* Update owner dependency reference */
|
/* Update owner dependency reference */
|
||||||
|
if (classId == LargeObjectMetadataRelationId)
|
||||||
|
classId = LargeObjectRelationId;
|
||||||
changeDependencyOnOwner(classId, objectId, new_ownerId);
|
changeDependencyOnOwner(classId, objectId, new_ownerId);
|
||||||
|
|
||||||
/* Release memory */
|
/* Release memory */
|
||||||
@ -1082,8 +1089,5 @@ AlterObjectOwner_internal(Oid classId, Oid objectId, Oid new_ownerId)
|
|||||||
pfree(replaces);
|
pfree(replaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note the post-alter hook gets classId not catalogId */
|
|
||||||
InvokeObjectPostAlterHook(classId, objectId, 0);
|
InvokeObjectPostAlterHook(classId, objectId, 0);
|
||||||
|
|
||||||
table_close(rel, RowExclusiveLock);
|
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/pg_largeobject.h"
|
#include "catalog/pg_largeobject_metadata.h"
|
||||||
#include "libpq/be-fsstubs.h"
|
#include "libpq/be-fsstubs.h"
|
||||||
#include "libpq/libpq-fs.h"
|
#include "libpq/libpq-fs.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
@ -323,7 +323,7 @@ be_lo_unlink(PG_FUNCTION_ARGS)
|
|||||||
* relevant FDs.
|
* relevant FDs.
|
||||||
*/
|
*/
|
||||||
if (!lo_compat_privileges &&
|
if (!lo_compat_privileges &&
|
||||||
!object_ownercheck(LargeObjectRelationId, lobjId, GetUserId()))
|
!object_ownercheck(LargeObjectMetadataRelationId, lobjId, GetUserId()))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
errmsg("must be owner of large object %u", lobjId)));
|
errmsg("must be owner of large object %u", lobjId)));
|
||||||
|
@ -569,7 +569,7 @@ PrefetchSharedBuffer(SMgrRelation smgr_reln,
|
|||||||
* recovery if the relation file doesn't exist.
|
* recovery if the relation file doesn't exist.
|
||||||
*/
|
*/
|
||||||
if ((io_direct_flags & IO_DIRECT_DATA) == 0 &&
|
if ((io_direct_flags & IO_DIRECT_DATA) == 0 &&
|
||||||
smgrprefetch(smgr_reln, forkNum, blockNum, 1))
|
smgrprefetch(smgr_reln, forkNum, blockNum))
|
||||||
{
|
{
|
||||||
result.initiated_io = true;
|
result.initiated_io = true;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ PrefetchLocalBuffer(SMgrRelation smgr, ForkNumber forkNum,
|
|||||||
#ifdef USE_PREFETCH
|
#ifdef USE_PREFETCH
|
||||||
/* Not in buffers, so initiate prefetch */
|
/* Not in buffers, so initiate prefetch */
|
||||||
if ((io_direct_flags & IO_DIRECT_DATA) == 0 &&
|
if ((io_direct_flags & IO_DIRECT_DATA) == 0 &&
|
||||||
smgrprefetch(smgr, forkNum, blockNum, 1))
|
smgrprefetch(smgr, forkNum, blockNum))
|
||||||
{
|
{
|
||||||
result.initiated_io = true;
|
result.initiated_io = true;
|
||||||
}
|
}
|
||||||
|
@ -221,10 +221,11 @@ inv_create(Oid lobjId)
|
|||||||
/*
|
/*
|
||||||
* dependency on the owner of largeobject
|
* dependency on the owner of largeobject
|
||||||
*
|
*
|
||||||
* Note that LO dependencies are recorded using classId
|
* The reason why we use LargeObjectRelationId instead of
|
||||||
* LargeObjectRelationId for backwards-compatibility reasons. Using
|
* LargeObjectMetadataRelationId here is to provide backward compatibility
|
||||||
* LargeObjectMetadataRelationId instead would simplify matters for the
|
* to the applications which utilize a knowledge about internal layout of
|
||||||
* backend, but it'd complicate pg_dump and possibly break other clients.
|
* system catalogs. OID of pg_largeobject_metadata and loid of
|
||||||
|
* pg_largeobject are same value, so there are no actual differences here.
|
||||||
*/
|
*/
|
||||||
recordDependencyOnOwner(LargeObjectRelationId,
|
recordDependencyOnOwner(LargeObjectRelationId,
|
||||||
lobjId_new, GetUserId());
|
lobjId_new, GetUserId());
|
||||||
|
@ -710,44 +710,27 @@ mdclose(SMgrRelation reln, ForkNumber forknum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mdprefetch() -- Initiate asynchronous read of the specified blocks of a relation
|
* mdprefetch() -- Initiate asynchronous read of the specified block of a relation
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
|
mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum)
|
||||||
int nblocks)
|
|
||||||
{
|
{
|
||||||
#ifdef USE_PREFETCH
|
#ifdef USE_PREFETCH
|
||||||
|
off_t seekpos;
|
||||||
|
MdfdVec *v;
|
||||||
|
|
||||||
Assert((io_direct_flags & IO_DIRECT_DATA) == 0);
|
Assert((io_direct_flags & IO_DIRECT_DATA) == 0);
|
||||||
|
|
||||||
if ((uint64) blocknum + nblocks > (uint64) MaxBlockNumber + 1)
|
v = _mdfd_getseg(reln, forknum, blocknum, false,
|
||||||
|
InRecovery ? EXTENSION_RETURN_NULL : EXTENSION_FAIL);
|
||||||
|
if (v == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (nblocks > 0)
|
seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
|
||||||
{
|
|
||||||
off_t seekpos;
|
|
||||||
MdfdVec *v;
|
|
||||||
int nblocks_this_segment;
|
|
||||||
|
|
||||||
v = _mdfd_getseg(reln, forknum, blocknum, false,
|
Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE);
|
||||||
InRecovery ? EXTENSION_RETURN_NULL : EXTENSION_FAIL);
|
|
||||||
if (v == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));
|
(void) FilePrefetch(v->mdfd_vfd, seekpos, BLCKSZ, WAIT_EVENT_DATA_FILE_PREFETCH);
|
||||||
|
|
||||||
Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE);
|
|
||||||
|
|
||||||
nblocks_this_segment =
|
|
||||||
Min(nblocks,
|
|
||||||
RELSEG_SIZE - (blocknum % ((BlockNumber) RELSEG_SIZE)));
|
|
||||||
|
|
||||||
(void) FilePrefetch(v->mdfd_vfd, seekpos, BLCKSZ * nblocks_this_segment,
|
|
||||||
WAIT_EVENT_DATA_FILE_PREFETCH);
|
|
||||||
|
|
||||||
blocknum += nblocks_this_segment;
|
|
||||||
nblocks -= nblocks_this_segment;
|
|
||||||
}
|
|
||||||
#endif /* USE_PREFETCH */
|
#endif /* USE_PREFETCH */
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -54,7 +54,7 @@ typedef struct f_smgr
|
|||||||
void (*smgr_zeroextend) (SMgrRelation reln, ForkNumber forknum,
|
void (*smgr_zeroextend) (SMgrRelation reln, ForkNumber forknum,
|
||||||
BlockNumber blocknum, int nblocks, bool skipFsync);
|
BlockNumber blocknum, int nblocks, bool skipFsync);
|
||||||
bool (*smgr_prefetch) (SMgrRelation reln, ForkNumber forknum,
|
bool (*smgr_prefetch) (SMgrRelation reln, ForkNumber forknum,
|
||||||
BlockNumber blocknum, int nblocks);
|
BlockNumber blocknum);
|
||||||
void (*smgr_read) (SMgrRelation reln, ForkNumber forknum,
|
void (*smgr_read) (SMgrRelation reln, ForkNumber forknum,
|
||||||
BlockNumber blocknum, void *buffer);
|
BlockNumber blocknum, void *buffer);
|
||||||
void (*smgr_write) (SMgrRelation reln, ForkNumber forknum,
|
void (*smgr_write) (SMgrRelation reln, ForkNumber forknum,
|
||||||
@ -547,10 +547,9 @@ smgrzeroextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
|
|||||||
* record).
|
* record).
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
|
smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum)
|
||||||
int nblocks)
|
|
||||||
{
|
{
|
||||||
return smgrsw[reln->smgr_which].smgr_prefetch(reln, forknum, blocknum, nblocks);
|
return smgrsw[reln->smgr_which].smgr_prefetch(reln, forknum, blocknum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/objectaddress.h"
|
#include "catalog/objectaddress.h"
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
|
#include "utils/relcache.h"
|
||||||
|
|
||||||
extern ObjectAddress ExecRenameStmt(RenameStmt *stmt);
|
extern ObjectAddress ExecRenameStmt(RenameStmt *stmt);
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ extern Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
|
|||||||
ObjectAddresses *objsMoved);
|
ObjectAddresses *objsMoved);
|
||||||
|
|
||||||
extern ObjectAddress ExecAlterOwnerStmt(AlterOwnerStmt *stmt);
|
extern ObjectAddress ExecAlterOwnerStmt(AlterOwnerStmt *stmt);
|
||||||
extern void AlterObjectOwner_internal(Oid classId, Oid objectId,
|
extern void AlterObjectOwner_internal(Relation rel, Oid objectId,
|
||||||
Oid new_ownerId);
|
Oid new_ownerId);
|
||||||
|
|
||||||
#endif /* ALTER_H */
|
#endif /* ALTER_H */
|
||||||
|
@ -31,7 +31,7 @@ extern void mdextend(SMgrRelation reln, ForkNumber forknum,
|
|||||||
extern void mdzeroextend(SMgrRelation reln, ForkNumber forknum,
|
extern void mdzeroextend(SMgrRelation reln, ForkNumber forknum,
|
||||||
BlockNumber blocknum, int nblocks, bool skipFsync);
|
BlockNumber blocknum, int nblocks, bool skipFsync);
|
||||||
extern bool mdprefetch(SMgrRelation reln, ForkNumber forknum,
|
extern bool mdprefetch(SMgrRelation reln, ForkNumber forknum,
|
||||||
BlockNumber blocknum, int nblocks);
|
BlockNumber blocknum);
|
||||||
extern void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
|
extern void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
|
||||||
void *buffer);
|
void *buffer);
|
||||||
extern void mdwrite(SMgrRelation reln, ForkNumber forknum,
|
extern void mdwrite(SMgrRelation reln, ForkNumber forknum,
|
||||||
|
@ -95,7 +95,7 @@ extern void smgrextend(SMgrRelation reln, ForkNumber forknum,
|
|||||||
extern void smgrzeroextend(SMgrRelation reln, ForkNumber forknum,
|
extern void smgrzeroextend(SMgrRelation reln, ForkNumber forknum,
|
||||||
BlockNumber blocknum, int nblocks, bool skipFsync);
|
BlockNumber blocknum, int nblocks, bool skipFsync);
|
||||||
extern bool smgrprefetch(SMgrRelation reln, ForkNumber forknum,
|
extern bool smgrprefetch(SMgrRelation reln, ForkNumber forknum,
|
||||||
BlockNumber blocknum, int nblocks);
|
BlockNumber blocknum);
|
||||||
extern void smgrread(SMgrRelation reln, ForkNumber forknum,
|
extern void smgrread(SMgrRelation reln, ForkNumber forknum,
|
||||||
BlockNumber blocknum, void *buffer);
|
BlockNumber blocknum, void *buffer);
|
||||||
extern void smgrwrite(SMgrRelation reln, ForkNumber forknum,
|
extern void smgrwrite(SMgrRelation reln, ForkNumber forknum,
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\getenv abs_builddir PG_ABS_BUILDDIR
|
\getenv abs_builddir PG_ABS_BUILDDIR
|
||||||
-- ensure consistent test output regardless of the default bytea format
|
-- ensure consistent test output regardless of the default bytea format
|
||||||
SET bytea_output TO escape;
|
SET bytea_output TO escape;
|
||||||
-- Test ALTER LARGE OBJECT OWNER
|
-- Test ALTER LARGE OBJECT OWNER, GRANT, COMMENT
|
||||||
CREATE ROLE regress_lo_user;
|
CREATE ROLE regress_lo_user;
|
||||||
SELECT lo_create(42);
|
SELECT lo_create(42);
|
||||||
lo_create
|
lo_create
|
||||||
@ -15,11 +15,8 @@ SELECT lo_create(42);
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
ALTER LARGE OBJECT 42 OWNER TO regress_lo_user;
|
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;
|
GRANT SELECT ON LARGE OBJECT 42 TO public;
|
||||||
COMMENT ON LARGE OBJECT 42 IS 'the ultimate answer';
|
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)
|
-- Test psql's \lo_list et al (we assume no other LOs exist yet)
|
||||||
\lo_list
|
\lo_list
|
||||||
Large objects
|
Large objects
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
\getenv abs_builddir PG_ABS_BUILDDIR
|
\getenv abs_builddir PG_ABS_BUILDDIR
|
||||||
-- ensure consistent test output regardless of the default bytea format
|
-- ensure consistent test output regardless of the default bytea format
|
||||||
SET bytea_output TO escape;
|
SET bytea_output TO escape;
|
||||||
-- Test ALTER LARGE OBJECT OWNER
|
-- Test ALTER LARGE OBJECT OWNER, GRANT, COMMENT
|
||||||
CREATE ROLE regress_lo_user;
|
CREATE ROLE regress_lo_user;
|
||||||
SELECT lo_create(42);
|
SELECT lo_create(42);
|
||||||
lo_create
|
lo_create
|
||||||
@ -15,11 +15,8 @@ SELECT lo_create(42);
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
ALTER LARGE OBJECT 42 OWNER TO regress_lo_user;
|
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;
|
GRANT SELECT ON LARGE OBJECT 42 TO public;
|
||||||
COMMENT ON LARGE OBJECT 42 IS 'the ultimate answer';
|
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)
|
-- Test psql's \lo_list et al (we assume no other LOs exist yet)
|
||||||
\lo_list
|
\lo_list
|
||||||
Large objects
|
Large objects
|
||||||
|
@ -9,19 +9,13 @@
|
|||||||
-- ensure consistent test output regardless of the default bytea format
|
-- ensure consistent test output regardless of the default bytea format
|
||||||
SET bytea_output TO escape;
|
SET bytea_output TO escape;
|
||||||
|
|
||||||
-- Test ALTER LARGE OBJECT OWNER
|
-- Test ALTER LARGE OBJECT OWNER, GRANT, COMMENT
|
||||||
CREATE ROLE regress_lo_user;
|
CREATE ROLE regress_lo_user;
|
||||||
SELECT lo_create(42);
|
SELECT lo_create(42);
|
||||||
ALTER LARGE OBJECT 42 OWNER TO regress_lo_user;
|
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;
|
GRANT SELECT ON LARGE OBJECT 42 TO public;
|
||||||
COMMENT ON LARGE OBJECT 42 IS 'the ultimate answer';
|
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)
|
-- Test psql's \lo_list et al (we assume no other LOs exist yet)
|
||||||
\lo_list
|
\lo_list
|
||||||
\lo_list+
|
\lo_list+
|
||||||
|
Loading…
x
Reference in New Issue
Block a user