postgresql/src/include/access/tupdesc.h
Tom Lane 06e10abc0b 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
2006-06-16 18:42:24 +00:00

122 lines
4.0 KiB
C

/*-------------------------------------------------------------------------
*
* tupdesc.h
* POSTGRES tuple descriptor definitions.
*
*
* 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.50 2006/06/16 18:42:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef TUPDESC_H
#define TUPDESC_H
#include "access/attnum.h"
#include "catalog/pg_attribute.h"
#include "nodes/pg_list.h"
typedef struct attrDefault
{
AttrNumber adnum;
char *adbin; /* nodeToString representation of expr */
} AttrDefault;
typedef struct constrCheck
{
char *ccname;
char *ccbin; /* nodeToString representation of expr */
} ConstrCheck;
/* This structure contains constraints of a tuple */
typedef struct tupleConstr
{
AttrDefault *defval; /* array */
ConstrCheck *check; /* array */
uint16 num_defval;
uint16 num_check;
bool has_not_null;
} TupleConstr;
/*
* This struct is passed around within the backend to describe the structure
* of tuples. For tuples coming from on-disk relations, the information is
* collected from the pg_attribute, pg_attrdef, and pg_constraint catalogs.
* Transient row types (such as the result of a join query) have anonymous
* TupleDesc structs that generally omit any constraint info; therefore the
* structure is designed to let the constraints be omitted efficiently.
*
* Note that only user attributes, not system attributes, are mentioned in
* TupleDesc; with the exception that tdhasoid indicates if OID is present.
*
* If the tupdesc is known to correspond to a named rowtype (such as a table's
* rowtype) then tdtypeid identifies that type and tdtypmod is -1. Otherwise
* 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
{
int natts; /* number of attributes in the tuple */
Form_pg_attribute *attrs;
/* attrs[N] is a pointer to the description of Attribute Number N+1 */
TupleConstr *constr; /* constraints, or NULL if none */
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;
extern TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid);
extern TupleDesc CreateTupleDesc(int natts, bool hasoid,
Form_pg_attribute *attrs);
extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc);
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,
AttrNumber attributeNumber,
const char *attributeName,
Oid oidtypeid,
int32 typmod,
int attdim);
extern TupleDesc BuildDescForRelation(List *schema);
extern TupleDesc BuildDescFromLists(List *names, List *types, List *typmods);
#endif /* TUPDESC_H */