/* * inv_open -- access an existing large object. * * Returns: * Large object descriptor, appropriately filled in. The descriptor * and subsidiary data are allocated in the specified memory context, * which must be suitably long-lived for the caller's purposes. */ LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt) { LargeObjectDesc *retval; Snapshot snapshot = NULL; int descflags = 0; if (flags & INV_WRITE) { snapshot = NULL; /* instantaneous MVCC snapshot */ descflags = IFS_WRLOCK | IFS_RDLOCK; } else if (flags & INV_READ) { snapshot = GetActiveSnapshot(); descflags = IFS_RDLOCK; } else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid flags for opening a large object: %d", flags))); /* Can't use LargeObjectExists here because we need to specify snapshot */ if (!myLargeObjectExists(lobjId, snapshot)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("large object %u does not exist", lobjId))); /* * We must register the snapshot in TopTransaction's resowner, because it * must stay alive until the LO is closed rather than until the current * portal shuts down. Do this after checking that the LO exists, to avoid * leaking the snapshot if an error is thrown. */ if (snapshot) snapshot = RegisterSnapshotOnOwner(snapshot, TopTransactionResourceOwner); /* All set, create a descriptor */ retval = (LargeObjectDesc *) MemoryContextAlloc(mcxt, sizeof(LargeObjectDesc)); retval->id = lobjId; retval->subid = GetCurrentSubTransactionId(); retval->offset = 0; retval->snapshot = snapshot; retval->flags = descflags; return retval; }
/* * inv_open -- access an existing large object. * * Returns: * Large object descriptor, appropriately filled in. The descriptor * and subsidiary data are allocated in the specified memory context, * which must be suitably long-lived for the caller's purposes. */ LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt) { LargeObjectDesc *retval; retval = (LargeObjectDesc *) MemoryContextAlloc(mcxt, sizeof(LargeObjectDesc)); retval->id = lobjId; retval->subid = GetCurrentSubTransactionId(); retval->offset = 0; if (flags & INV_WRITE) { retval->snapshot = SnapshotNow; retval->flags = IFS_WRLOCK | IFS_RDLOCK; } else if (flags & INV_READ) { /* * We must register the snapshot in TopTransaction's resowner, because * it must stay alive until the LO is closed rather than until the * current portal shuts down. */ retval->snapshot = RegisterSnapshotOnOwner(GetActiveSnapshot(), TopTransactionResourceOwner); retval->flags = IFS_RDLOCK; } else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid flags for opening a large object: %d", flags))); /* Can't use LargeObjectExists here because it always uses SnapshotNow */ if (!myLargeObjectExists(lobjId, retval->snapshot)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("large object %u does not exist", lobjId))); return retval; }
/* * inv_open -- access an existing large object. * * Returns: * Large object descriptor, appropriately filled in. The descriptor * and subsidiary data are allocated in the specified memory context, * which must be suitably long-lived for the caller's purposes. */ LargeObjectDesc * inv_open(Oid lobjId, int flags, MemoryContext mcxt) { LargeObjectDesc *retval; retval = (LargeObjectDesc *) MemoryContextAlloc(mcxt, sizeof(LargeObjectDesc)); retval->id = lobjId; retval->subid = GetCurrentSubTransactionId(); retval->offset = 0; if (flags & INV_WRITE) { retval->snapshot = SnapshotNow; retval->flags = IFS_WRLOCK | IFS_RDLOCK; } else if (flags & INV_READ) { /* be sure to copy snap into mcxt */ MemoryContext oldContext = MemoryContextSwitchTo(mcxt); retval->snapshot = CopySnapshot(ActiveSnapshot); retval->flags = IFS_RDLOCK; MemoryContextSwitchTo(oldContext); } else elog(ERROR, "invalid flags: %d", flags); /* Can't use LargeObjectExists here because it always uses SnapshotNow */ if (!myLargeObjectExists(lobjId, retval->snapshot)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("large object %u does not exist", lobjId))); return retval; }