mirror of
https://github.com/postgres/postgres.git
synced 2025-10-21 02:52:47 +03:00
This introduces a new function equalRowTypes() that is effectively a
subset of equalTupleDescs() but only compares the number of attributes
and attribute name, type, typmod, and collation. This is enough for
most existing uses of equalTupleDescs(), which are changed to use the
new function. The only remaining callers of equalTupleDescs() are
those that really want to check the full tuple descriptor as such,
without concern about record or row or record type semantics.
The existing function hashTupleDesc() is renamed to hashRowType(),
because it now corresponds more to equalRowTypes().
The purpose of this change is to be clearer about the semantics of the
equality asked for by each caller. (At least one caller had a comment
that questioned whether equalTupleDescs() was too restrictive.) For
example, 4f622503d6
removed attstattarget from the tuple descriptor
structure. It was not fully clear at the time how this should affect
equalTupleDescs(). Now the answer is clear: By their own definitions,
equalRowTypes() does not care, and equalTupleDescs() just compares
whatever is in the tuple descriptor but does not care why it is in
there.
Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com>
Discussion: https://www.postgresql.org/message-id/flat/f656d6d9-6660-4518-a006-2f65cafbebd1%40eisentraut.org
155 lines
5.3 KiB
C
155 lines
5.3 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* tupdesc.h
|
|
* POSTGRES tuple descriptor definitions.
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/access/tupdesc.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#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 */
|
|
bool ccvalid;
|
|
bool ccnoinherit; /* this is a non-inheritable constraint */
|
|
} ConstrCheck;
|
|
|
|
/* This structure contains constraints of a tuple */
|
|
typedef struct TupleConstr
|
|
{
|
|
AttrDefault *defval; /* array */
|
|
ConstrCheck *check; /* array */
|
|
struct AttrMissing *missing; /* missing attributes values, NULL if none */
|
|
uint16 num_defval;
|
|
uint16 num_check;
|
|
bool has_not_null;
|
|
bool has_generated_stored;
|
|
} 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.
|
|
*
|
|
* 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.
|
|
*
|
|
* Note that tdtypeid is never the OID of a domain over composite, even if
|
|
* we are dealing with values that are known (at some higher level) to be of
|
|
* a domain-over-composite type. This is because tdtypeid/tdtypmod need to
|
|
* match up with the type labeling of composite Datums, and those are never
|
|
* explicitly marked as being of a domain type, either.
|
|
*
|
|
* 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 TupleDescData
|
|
{
|
|
int natts; /* number of attributes in the tuple */
|
|
Oid tdtypeid; /* composite type ID for tuple type */
|
|
int32 tdtypmod; /* typmod for tuple type */
|
|
int tdrefcount; /* reference count, or -1 if not counting */
|
|
TupleConstr *constr; /* constraints, or NULL if none */
|
|
/* attrs[N] is the description of Attribute Number N+1 */
|
|
FormData_pg_attribute attrs[FLEXIBLE_ARRAY_MEMBER];
|
|
} TupleDescData;
|
|
typedef struct TupleDescData *TupleDesc;
|
|
|
|
/* Accessor for the i'th attribute of tupdesc. */
|
|
#define TupleDescAttr(tupdesc, i) (&(tupdesc)->attrs[(i)])
|
|
|
|
extern TupleDesc CreateTemplateTupleDesc(int natts);
|
|
|
|
extern TupleDesc CreateTupleDesc(int natts, Form_pg_attribute *attrs);
|
|
|
|
extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc);
|
|
|
|
extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc);
|
|
|
|
#define TupleDescSize(src) \
|
|
(offsetof(struct TupleDescData, attrs) + \
|
|
(src)->natts * sizeof(FormData_pg_attribute))
|
|
|
|
extern void TupleDescCopy(TupleDesc dst, TupleDesc src);
|
|
|
|
extern void TupleDescCopyEntry(TupleDesc dst, AttrNumber dstAttno,
|
|
TupleDesc src, AttrNumber srcAttno);
|
|
|
|
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 bool equalRowTypes(TupleDesc tupdesc1, TupleDesc tupdesc2);
|
|
extern uint32 hashRowType(TupleDesc desc);
|
|
|
|
extern void TupleDescInitEntry(TupleDesc desc,
|
|
AttrNumber attributeNumber,
|
|
const char *attributeName,
|
|
Oid oidtypeid,
|
|
int32 typmod,
|
|
int attdim);
|
|
|
|
extern void TupleDescInitBuiltinEntry(TupleDesc desc,
|
|
AttrNumber attributeNumber,
|
|
const char *attributeName,
|
|
Oid oidtypeid,
|
|
int32 typmod,
|
|
int attdim);
|
|
|
|
extern void TupleDescInitEntryCollation(TupleDesc desc,
|
|
AttrNumber attributeNumber,
|
|
Oid collationid);
|
|
|
|
extern TupleDesc BuildDescFromLists(const List *names, const List *types, const List *typmods, const List *collations);
|
|
|
|
extern Node *TupleDescGetDefault(TupleDesc tupdesc, AttrNumber attnum);
|
|
|
|
#endif /* TUPDESC_H */
|