mirror of
https://github.com/postgres/postgres.git
synced 2025-10-22 14:32:25 +03:00
Fix problems with cached tuple descriptors disappearing while still in use
by creating a reference-count mechanism, similar to what we did a long time ago for catcache entries. The back branches have an ugly solution involving lots of extra copies, but this way is more efficient. Reference counting is only applied to tupdescs that are actually in caches --- there seems no need to use it for tupdescs that are generated in the executor, since they'll go away during plan shutdown by virtue of being in the per-query memory context. Neil Conway and Tom Lane
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/tupdesc.h,v 1.49 2006/03/16 00:31:55 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/tupdesc.h,v 1.50 2006/06/16 18:42:23 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -57,6 +57,14 @@ typedef struct tupleConstr
|
||||
* tdtypeid is RECORDOID, and tdtypmod can be either -1 for a fully anonymous
|
||||
* row type, or a value >= 0 to allow the rowtype to be looked up in the
|
||||
* typcache.c type cache.
|
||||
*
|
||||
* Tuple descriptors that live in caches (relcache or typcache, at present)
|
||||
* are reference-counted: they can be deleted when their reference count goes
|
||||
* to zero. Tuple descriptors created by the executor need no reference
|
||||
* counting, however: they are simply created in the appropriate memory
|
||||
* context and go away when the context is freed. We set the tdrefcount
|
||||
* field of such a descriptor to -1, while reference-counted descriptors
|
||||
* always have tdrefcount >= 0.
|
||||
*/
|
||||
typedef struct tupleDesc
|
||||
{
|
||||
@@ -67,6 +75,7 @@ typedef struct tupleDesc
|
||||
Oid tdtypeid; /* composite type ID for tuple type */
|
||||
int32 tdtypmod; /* typmod for tuple type */
|
||||
bool tdhasoid; /* tuple has oid attribute in its header */
|
||||
int tdrefcount; /* reference count, or -1 if not counting */
|
||||
} *TupleDesc;
|
||||
|
||||
|
||||
@@ -81,6 +90,21 @@ extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc);
|
||||
|
||||
extern void FreeTupleDesc(TupleDesc tupdesc);
|
||||
|
||||
extern void IncrTupleDescRefCount(TupleDesc tupdesc);
|
||||
extern void DecrTupleDescRefCount(TupleDesc tupdesc);
|
||||
|
||||
#define PinTupleDesc(tupdesc) \
|
||||
do { \
|
||||
if ((tupdesc)->tdrefcount >= 0) \
|
||||
IncrTupleDescRefCount(tupdesc); \
|
||||
} while (0)
|
||||
|
||||
#define ReleaseTupleDesc(tupdesc) \
|
||||
do { \
|
||||
if ((tupdesc)->tdrefcount >= 0) \
|
||||
DecrTupleDescRefCount(tupdesc); \
|
||||
} while (0)
|
||||
|
||||
extern bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2);
|
||||
|
||||
extern void TupleDescInitEntry(TupleDesc desc,
|
||||
|
Reference in New Issue
Block a user