PostgreSQL Source Code  git master
tupdesc.h File Reference
#include "access/attnum.h"
#include "catalog/pg_attribute.h"
#include "nodes/pg_list.h"
Include dependency graph for tupdesc.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  AttrDefault
 
struct  ConstrCheck
 
struct  TupleConstr
 
struct  TupleDescData
 

Macros

#define TupleDescAttr(tupdesc, i)   (&(tupdesc)->attrs[(i)])
 
#define TupleDescSize(src)
 
#define PinTupleDesc(tupdesc)
 
#define ReleaseTupleDesc(tupdesc)
 

Typedefs

typedef struct AttrDefault AttrDefault
 
typedef struct ConstrCheck ConstrCheck
 
typedef struct TupleConstr TupleConstr
 
typedef struct TupleDescData TupleDescData
 
typedef struct TupleDescDataTupleDesc
 

Functions

TupleDesc CreateTemplateTupleDesc (int natts)
 
TupleDesc CreateTupleDesc (int natts, Form_pg_attribute *attrs)
 
TupleDesc CreateTupleDescCopy (TupleDesc tupdesc)
 
TupleDesc CreateTupleDescCopyConstr (TupleDesc tupdesc)
 
void TupleDescCopy (TupleDesc dst, TupleDesc src)
 
void TupleDescCopyEntry (TupleDesc dst, AttrNumber dstAttno, TupleDesc src, AttrNumber srcAttno)
 
void FreeTupleDesc (TupleDesc tupdesc)
 
void IncrTupleDescRefCount (TupleDesc tupdesc)
 
void DecrTupleDescRefCount (TupleDesc tupdesc)
 
bool equalTupleDescs (TupleDesc tupdesc1, TupleDesc tupdesc2)
 
uint32 hashTupleDesc (TupleDesc desc)
 
void TupleDescInitEntry (TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
 
void TupleDescInitBuiltinEntry (TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
 
void TupleDescInitEntryCollation (TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
 
TupleDesc BuildDescForRelation (List *schema)
 
TupleDesc BuildDescFromLists (List *names, List *types, List *typmods, List *collations)
 

Macro Definition Documentation

◆ PinTupleDesc

#define PinTupleDesc (   tupdesc)
Value:
do { \
if ((tupdesc)->tdrefcount >= 0) \
IncrTupleDescRefCount(tupdesc); \
} while (0)

Definition at line 116 of file tupdesc.h.

◆ ReleaseTupleDesc

#define ReleaseTupleDesc (   tupdesc)
Value:
do { \
if ((tupdesc)->tdrefcount >= 0) \
DecrTupleDescRefCount(tupdesc); \
} while (0)

Definition at line 122 of file tupdesc.h.

◆ TupleDescAttr

#define TupleDescAttr (   tupdesc,
  i 
)    (&(tupdesc)->attrs[(i)])

Definition at line 92 of file tupdesc.h.

◆ TupleDescSize

#define TupleDescSize (   src)
Value:
(offsetof(struct TupleDescData, attrs) + \
(src)->natts * sizeof(FormData_pg_attribute))
FormData_pg_attribute
Definition: pg_attribute.h:191

Definition at line 102 of file tupdesc.h.

Typedef Documentation

◆ AttrDefault

typedef struct AttrDefault AttrDefault

◆ ConstrCheck

typedef struct ConstrCheck ConstrCheck

◆ TupleConstr

typedef struct TupleConstr TupleConstr

◆ TupleDesc

typedef struct TupleDescData* TupleDesc

Definition at line 89 of file tupdesc.h.

◆ TupleDescData

typedef struct TupleDescData TupleDescData

Function Documentation

◆ BuildDescForRelation()

TupleDesc BuildDescForRelation ( List schema)

Definition at line 786 of file tupdesc.c.

787 {
788  int natts;
790  ListCell *l;
791  TupleDesc desc;
792  bool has_not_null;
793  char *attname;
794  Oid atttypid;
795  int32 atttypmod;
796  Oid attcollation;
797  int attdim;
798 
799  /*
800  * allocate a new tuple descriptor
801  */
802  natts = list_length(schema);
803  desc = CreateTemplateTupleDesc(natts);
804  has_not_null = false;
805 
806  attnum = 0;
807 
808  foreach(l, schema)
809  {
810  ColumnDef *entry = lfirst(l);
811  AclResult aclresult;
812  Form_pg_attribute att;
813 
814  /*
815  * for each entry in the list, get the name and type information from
816  * the list and have TupleDescInitEntry fill in the attribute
817  * information we need.
818  */
819  attnum++;
820 
821  attname = entry->colname;
822  typenameTypeIdAndMod(NULL, entry->typeName, &atttypid, &atttypmod);
823 
824  aclresult = pg_type_aclcheck(atttypid, GetUserId(), ACL_USAGE);
825  if (aclresult != ACLCHECK_OK)
826  aclcheck_error_type(aclresult, atttypid);
827 
828  attcollation = GetColumnDefCollation(NULL, entry, atttypid);
829  attdim = list_length(entry->typeName->arrayBounds);
830 
831  if (entry->typeName->setof)
832  ereport(ERROR,
833  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
834  errmsg("column \"%s\" cannot be declared SETOF",
835  attname)));
836 
838  atttypid, atttypmod, attdim);
839  att = TupleDescAttr(desc, attnum - 1);
840 
841  /* Override TupleDescInitEntry's settings as requested */
842  TupleDescInitEntryCollation(desc, attnum, attcollation);
843  if (entry->storage)
844  att->attstorage = entry->storage;
845 
846  /* Fill in additional stuff not handled by TupleDescInitEntry */
847  att->attnotnull = entry->is_not_null;
848  has_not_null |= entry->is_not_null;
849  att->attislocal = entry->is_local;
850  att->attinhcount = entry->inhcount;
851  }
852 
853  if (has_not_null)
854  {
855  TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
856 
857  constr->has_not_null = true;
858  constr->has_generated_stored = false;
859  constr->defval = NULL;
860  constr->missing = NULL;
861  constr->num_defval = 0;
862  constr->check = NULL;
863  constr->num_check = 0;
864  desc->constr = constr;
865  }
866  else
867  {
868  desc->constr = NULL;
869  }
870 
871  return desc;
872 }
AclResult
Definition: acl.h:181
@ ACLCHECK_OK
Definition: acl.h:182
AclResult pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:5105
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition: aclchk.c:3777
int16 AttrNumber
Definition: attnum.h:21
signed int int32
Definition: c.h:430
int errcode(int sqlerrcode)
Definition: elog.c:695
int errmsg(const char *fmt,...)
Definition: elog.c:906
#define ERROR
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:145
void * palloc0(Size size)
Definition: mcxt.c:1176
Oid GetUserId(void)
Definition: miscinit.c:497
void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName, Oid *typeid_p, int32 *typmod_p)
Definition: parse_type.c:310
Oid GetColumnDefCollation(ParseState *pstate, ColumnDef *coldef, Oid typeOid)
Definition: parse_type.c:540
#define ACL_USAGE
Definition: parsenodes.h:91
NameData attname
Definition: pg_attribute.h:41
int16 attnum
Definition: pg_attribute.h:83
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
#define lfirst(lc)
Definition: pg_list.h:170
static int list_length(const List *l)
Definition: pg_list.h:150
unsigned int Oid
Definition: postgres_ext.h:31
bool is_not_null
Definition: parsenodes.h:691
int inhcount
Definition: parsenodes.h:689
char * colname
Definition: parsenodes.h:686
TypeName * typeName
Definition: parsenodes.h:687
char storage
Definition: parsenodes.h:693
bool is_local
Definition: parsenodes.h:690
bool has_not_null
Definition: tupdesc.h:44
AttrDefault * defval
Definition: tupdesc.h:39
bool has_generated_stored
Definition: tupdesc.h:45
struct AttrMissing * missing
Definition: tupdesc.h:41
ConstrCheck * check
Definition: tupdesc.h:40
uint16 num_defval
Definition: tupdesc.h:42
uint16 num_check
Definition: tupdesc.h:43
TupleConstr * constr
Definition: tupdesc.h:85
bool setof
Definition: parsenodes.h:233
List * arrayBounds
Definition: parsenodes.h:237
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:45
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:763
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:583
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92

References ACL_USAGE, aclcheck_error_type(), ACLCHECK_OK, TypeName::arrayBounds, attname, attnum, TupleConstr::check, ColumnDef::colname, TupleDescData::constr, CreateTemplateTupleDesc(), TupleConstr::defval, ereport, errcode(), errmsg(), ERROR, GetColumnDefCollation(), GetUserId(), TupleConstr::has_generated_stored, TupleConstr::has_not_null, ColumnDef::inhcount, ColumnDef::is_local, ColumnDef::is_not_null, lfirst, list_length(), TupleConstr::missing, TupleConstr::num_check, TupleConstr::num_defval, palloc0(), pg_type_aclcheck(), TypeName::setof, ColumnDef::storage, TupleDescAttr, TupleDescInitEntry(), TupleDescInitEntryCollation(), ColumnDef::typeName, and typenameTypeIdAndMod().

Referenced by DefineRelation(), and DefineVirtualRelation().

◆ BuildDescFromLists()

TupleDesc BuildDescFromLists ( List names,
List types,
List typmods,
List collations 
)

Definition at line 886 of file tupdesc.c.

887 {
888  int natts;
890  ListCell *l1;
891  ListCell *l2;
892  ListCell *l3;
893  ListCell *l4;
894  TupleDesc desc;
895 
896  natts = list_length(names);
897  Assert(natts == list_length(types));
898  Assert(natts == list_length(typmods));
899  Assert(natts == list_length(collations));
900 
901  /*
902  * allocate a new tuple descriptor
903  */
904  desc = CreateTemplateTupleDesc(natts);
905 
906  attnum = 0;
907  forfour(l1, names, l2, types, l3, typmods, l4, collations)
908  {
909  char *attname = strVal(lfirst(l1));
910  Oid atttypid = lfirst_oid(l2);
911  int32 atttypmod = lfirst_int(l3);
912  Oid attcollation = lfirst_oid(l4);
913 
914  attnum++;
915 
916  TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
917  TupleDescInitEntryCollation(desc, attnum, attcollation);
918  }
919 
920  return desc;
921 }
struct typedefs * types
Definition: ecpg.c:29
Assert(fmt[strlen(fmt) - 1] !='\n')
#define lfirst_int(lc)
Definition: pg_list.h:171
#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4)
Definition: pg_list.h:522
#define lfirst_oid(lc)
Definition: pg_list.h:172
#define strVal(v)
Definition: value.h:82

References Assert(), attname, attnum, CreateTemplateTupleDesc(), forfour, lfirst, lfirst_int, lfirst_oid, list_length(), strVal, TupleDescInitEntry(), TupleDescInitEntryCollation(), and types.

Referenced by ExecInitFunctionScan(), ExecInitTableFuncScan(), and inline_set_returning_function().

◆ CreateTemplateTupleDesc()

TupleDesc CreateTemplateTupleDesc ( int  natts)

Definition at line 45 of file tupdesc.c.

46 {
47  TupleDesc desc;
48 
49  /*
50  * sanity checks
51  */
52  AssertArg(natts >= 0);
53 
54  /*
55  * Allocate enough memory for the tuple descriptor, including the
56  * attribute rows.
57  *
58  * Note: the attribute array stride is sizeof(FormData_pg_attribute),
59  * since we declare the array elements as FormData_pg_attribute for
60  * notational convenience. However, we only guarantee that the first
61  * ATTRIBUTE_FIXED_PART_SIZE bytes of each entry are valid; most code that
62  * copies tupdesc entries around copies just that much. In principle that
63  * could be less due to trailing padding, although with the current
64  * definition of pg_attribute there probably isn't any padding.
65  */
66  desc = (TupleDesc) palloc(offsetof(struct TupleDescData, attrs) +
67  natts * sizeof(FormData_pg_attribute));
68 
69  /*
70  * Initialize other fields of the tupdesc.
71  */
72  desc->natts = natts;
73  desc->constr = NULL;
74  desc->tdtypeid = RECORDOID;
75  desc->tdtypmod = -1;
76  desc->tdrefcount = -1; /* assume not reference-counted */
77 
78  return desc;
79 }
#define AssertArg(condition)
Definition: c.h:796
void * palloc(Size size)
Definition: mcxt.c:1145
int tdrefcount
Definition: tupdesc.h:84
int32 tdtypmod
Definition: tupdesc.h:83
Oid tdtypeid
Definition: tupdesc.h:82
struct TupleDescData * TupleDesc
Definition: tupdesc.h:89

References AssertArg, TupleDescData::constr, FormData_pg_attribute, TupleDescData::natts, palloc(), TupleDescData::tdrefcount, TupleDescData::tdtypeid, and TupleDescData::tdtypmod.

Referenced by aclexplode(), addRangeTableEntryForFunction(), AllocateRelationDesc(), brtuple_disk_tupdesc(), build_function_result_tupdesc_d(), build_row_from_vars(), BuildDescForRelation(), BuildDescFromLists(), BuildHardcodedDescriptor(), ConstructTupleDescriptor(), create_toast_table(), CreateReplicationSlot(), CreateTupleDesc(), CreateTupleDescCopy(), CreateTupleDescCopyConstr(), dblink_get_pkey(), ExecInitFunctionScan(), ExecMakeTableFunctionResult(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), ExplainResultDesc(), formrdesc(), get_expr_result_type(), GetPGVariableResultDesc(), gistrescan(), IdentifySystem(), init_sexpr(), initGinState(), libpqrcv_processTuples(), load_relcache_init_file(), MakeOldSnapshotTimeMappingTupleDesc(), materializeResult(), ordered_set_startup(), pg_buffercache_pages(), pg_control_checkpoint(), pg_control_init(), pg_control_recovery(), pg_control_system(), pg_get_catalog_foreign_keys(), pg_get_keywords(), pg_get_multixact_members(), pg_get_object_address(), pg_get_publication_tables(), pg_identify_object(), pg_identify_object_as_address(), pg_last_committed_xact(), pg_lock_status(), pg_logdir_ls_internal(), pg_partition_tree(), pg_prepared_xact(), pg_sequence_parameters(), pg_stat_file(), pg_stat_get_archiver(), pg_stat_get_replication_slot(), pg_stat_get_subscription_stats(), pg_stat_get_wal(), pg_timezone_abbrevs(), pg_visibility_map_summary(), pg_visibility_tupdesc(), pg_walfile_name_offset(), pg_xact_commit_timestamp_origin(), prs_setup_firstcall(), ReadReplicationSlot(), SendTablespaceList(), SendTimeLineHistory(), SendXlogRecPtrResult(), show_all_settings(), ShowAllGUCConfig(), ShowGUCConfigOption(), StartReplication(), test_predtest(), ts_setup_firstcall(), tsvector_unnest(), tt_setup_firstcall(), and TypeGetTupleDesc().

◆ CreateTupleDesc()

TupleDesc CreateTupleDesc ( int  natts,
Form_pg_attribute attrs 
)

Definition at line 90 of file tupdesc.c.

91 {
92  TupleDesc desc;
93  int i;
94 
95  desc = CreateTemplateTupleDesc(natts);
96 
97  for (i = 0; i < natts; ++i)
98  memcpy(TupleDescAttr(desc, i), attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
99 
100  return desc;
101 }
int i
Definition: isn.c:73
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:199

References ATTRIBUTE_FIXED_PART_SIZE, CreateTemplateTupleDesc(), i, and TupleDescAttr.

Referenced by AddNewAttributeTuples(), ATExecAddColumn(), and InsertOneTuple().

◆ CreateTupleDescCopy()

TupleDesc CreateTupleDescCopy ( TupleDesc  tupdesc)

Definition at line 111 of file tupdesc.c.

112 {
113  TupleDesc desc;
114  int i;
115 
116  desc = CreateTemplateTupleDesc(tupdesc->natts);
117 
118  /* Flat-copy the attribute array */
119  memcpy(TupleDescAttr(desc, 0),
120  TupleDescAttr(tupdesc, 0),
121  desc->natts * sizeof(FormData_pg_attribute));
122 
123  /*
124  * Since we're not copying constraints and defaults, clear fields
125  * associated with them.
126  */
127  for (i = 0; i < desc->natts; i++)
128  {
129  Form_pg_attribute att = TupleDescAttr(desc, i);
130 
131  att->attnotnull = false;
132  att->atthasdef = false;
133  att->atthasmissing = false;
134  att->attidentity = '\0';
135  att->attgenerated = '\0';
136  }
137 
138  /* We can copy the tuple type identification, too */
139  desc->tdtypeid = tupdesc->tdtypeid;
140  desc->tdtypmod = tupdesc->tdtypmod;
141 
142  return desc;
143 }

References CreateTemplateTupleDesc(), FormData_pg_attribute, i, TupleDescData::natts, TupleDescData::tdtypeid, TupleDescData::tdtypmod, and TupleDescAttr.

Referenced by assign_record_type_typmod(), BuildTupleHashTableExt(), connectby_text(), connectby_text_serial(), CopyCachedPlan(), crosstab(), crosstab_hash(), database_to_xmlschema_internal(), do_autovacuum(), ExecEvalWholeRowVar(), ExecInitForeignScan(), ExecInitFunctionScan(), ExecInsert(), ExecPrepareTuplestoreResult(), FetchPreparedStatementResultDesc(), fmgr_sql(), get_record_type_from_query(), get_tupdesc_for_join_scan_tuples(), GetAfterTriggersStoreSlot(), getSpGistTupleDesc(), init_sexpr(), init_tuple_slot(), make_expanded_record_from_exprecord(), make_expanded_record_from_tupdesc(), materializeResult(), PersistHoldablePortal(), plperl_return_next_internal(), plpgsql_exec_function(), pltcl_func_handler(), PLy_spi_execute_fetch_result(), populate_recordset_worker(), RelationBuildLocalRelation(), RelationNameGetTupleDesc(), RevalidateCachedQuery(), schema_to_xmlschema_internal(), SetSingleFuncCall(), spi_dest_startup(), storeRow(), update_cached_tupdesc(), and UtilityTupleDescriptor().

◆ CreateTupleDescCopyConstr()

TupleDesc CreateTupleDescCopyConstr ( TupleDesc  tupdesc)

Definition at line 151 of file tupdesc.c.

152 {
153  TupleDesc desc;
154  TupleConstr *constr = tupdesc->constr;
155  int i;
156 
157  desc = CreateTemplateTupleDesc(tupdesc->natts);
158 
159  /* Flat-copy the attribute array */
160  memcpy(TupleDescAttr(desc, 0),
161  TupleDescAttr(tupdesc, 0),
162  desc->natts * sizeof(FormData_pg_attribute));
163 
164  /* Copy the TupleConstr data structure, if any */
165  if (constr)
166  {
167  TupleConstr *cpy = (TupleConstr *) palloc0(sizeof(TupleConstr));
168 
169  cpy->has_not_null = constr->has_not_null;
171 
172  if ((cpy->num_defval = constr->num_defval) > 0)
173  {
174  cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault));
175  memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault));
176  for (i = cpy->num_defval - 1; i >= 0; i--)
177  cpy->defval[i].adbin = pstrdup(constr->defval[i].adbin);
178  }
179 
180  if (constr->missing)
181  {
182  cpy->missing = (AttrMissing *) palloc(tupdesc->natts * sizeof(AttrMissing));
183  memcpy(cpy->missing, constr->missing, tupdesc->natts * sizeof(AttrMissing));
184  for (i = tupdesc->natts - 1; i >= 0; i--)
185  {
186  if (constr->missing[i].am_present)
187  {
188  Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
189 
190  cpy->missing[i].am_value = datumCopy(constr->missing[i].am_value,
191  attr->attbyval,
192  attr->attlen);
193  }
194  }
195  }
196 
197  if ((cpy->num_check = constr->num_check) > 0)
198  {
199  cpy->check = (ConstrCheck *) palloc(cpy->num_check * sizeof(ConstrCheck));
200  memcpy(cpy->check, constr->check, cpy->num_check * sizeof(ConstrCheck));
201  for (i = cpy->num_check - 1; i >= 0; i--)
202  {
203  cpy->check[i].ccname = pstrdup(constr->check[i].ccname);
204  cpy->check[i].ccbin = pstrdup(constr->check[i].ccbin);
205  cpy->check[i].ccvalid = constr->check[i].ccvalid;
206  cpy->check[i].ccnoinherit = constr->check[i].ccnoinherit;
207  }
208  }
209 
210  desc->constr = cpy;
211  }
212 
213  /* We can copy the tuple type identification, too */
214  desc->tdtypeid = tupdesc->tdtypeid;
215  desc->tdtypmod = tupdesc->tdtypmod;
216 
217  return desc;
218 }
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
char * pstrdup(const char *in)
Definition: mcxt.c:1392
char * adbin
Definition: tupdesc.h:25
char * ccname
Definition: tupdesc.h:30
bool ccnoinherit
Definition: tupdesc.h:33
bool ccvalid
Definition: tupdesc.h:32
char * ccbin
Definition: tupdesc.h:31

References AttrDefault::adbin, AttrMissing::am_present, AttrMissing::am_value, ConstrCheck::ccbin, ConstrCheck::ccname, ConstrCheck::ccnoinherit, ConstrCheck::ccvalid, TupleConstr::check, TupleDescData::constr, CreateTemplateTupleDesc(), datumCopy(), TupleConstr::defval, FormData_pg_attribute, TupleConstr::has_generated_stored, TupleConstr::has_not_null, i, TupleConstr::missing, TupleDescData::natts, TupleConstr::num_check, TupleConstr::num_defval, palloc(), palloc0(), pstrdup(), TupleDescData::tdtypeid, TupleDescData::tdtypmod, and TupleDescAttr.

Referenced by ATGetQueueEntry(), CatalogCacheInitializeCache(), initGISTstate(), and lookup_rowtype_tupdesc_copy().

◆ DecrTupleDescRefCount()

void DecrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 384 of file tupdesc.c.

385 {
386  Assert(tupdesc->tdrefcount > 0);
387 
389  if (--tupdesc->tdrefcount == 0)
390  FreeTupleDesc(tupdesc);
391 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
void ResourceOwnerForgetTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition: resowner.c:1218
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:309

References Assert(), CurrentResourceOwner, FreeTupleDesc(), ResourceOwnerForgetTupleDesc(), and TupleDescData::tdrefcount.

Referenced by cache_record_field_properties(), ExecEvalConvertRowtype(), and ResourceOwnerReleaseInternal().

◆ equalTupleDescs()

bool equalTupleDescs ( TupleDesc  tupdesc1,
TupleDesc  tupdesc2 
)

Definition at line 402 of file tupdesc.c.

403 {
404  int i,
405  n;
406 
407  if (tupdesc1->natts != tupdesc2->natts)
408  return false;
409  if (tupdesc1->tdtypeid != tupdesc2->tdtypeid)
410  return false;
411 
412  for (i = 0; i < tupdesc1->natts; i++)
413  {
414  Form_pg_attribute attr1 = TupleDescAttr(tupdesc1, i);
415  Form_pg_attribute attr2 = TupleDescAttr(tupdesc2, i);
416 
417  /*
418  * We do not need to check every single field here: we can disregard
419  * attrelid and attnum (which were used to place the row in the attrs
420  * array in the first place). It might look like we could dispense
421  * with checking attlen/attbyval/attalign, since these are derived
422  * from atttypid; but in the case of dropped columns we must check
423  * them (since atttypid will be zero for all dropped columns) and in
424  * general it seems safer to check them always.
425  *
426  * attcacheoff must NOT be checked since it's possibly not set in both
427  * copies. We also intentionally ignore atthasmissing, since that's
428  * not very relevant in tupdescs, which lack the attmissingval field.
429  */
430  if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0)
431  return false;
432  if (attr1->atttypid != attr2->atttypid)
433  return false;
434  if (attr1->attstattarget != attr2->attstattarget)
435  return false;
436  if (attr1->attlen != attr2->attlen)
437  return false;
438  if (attr1->attndims != attr2->attndims)
439  return false;
440  if (attr1->atttypmod != attr2->atttypmod)
441  return false;
442  if (attr1->attbyval != attr2->attbyval)
443  return false;
444  if (attr1->attalign != attr2->attalign)
445  return false;
446  if (attr1->attstorage != attr2->attstorage)
447  return false;
448  if (attr1->attcompression != attr2->attcompression)
449  return false;
450  if (attr1->attnotnull != attr2->attnotnull)
451  return false;
452  if (attr1->atthasdef != attr2->atthasdef)
453  return false;
454  if (attr1->attidentity != attr2->attidentity)
455  return false;
456  if (attr1->attgenerated != attr2->attgenerated)
457  return false;
458  if (attr1->attisdropped != attr2->attisdropped)
459  return false;
460  if (attr1->attislocal != attr2->attislocal)
461  return false;
462  if (attr1->attinhcount != attr2->attinhcount)
463  return false;
464  if (attr1->attcollation != attr2->attcollation)
465  return false;
466  /* variable-length fields are not even present... */
467  }
468 
469  if (tupdesc1->constr != NULL)
470  {
471  TupleConstr *constr1 = tupdesc1->constr;
472  TupleConstr *constr2 = tupdesc2->constr;
473 
474  if (constr2 == NULL)
475  return false;
476  if (constr1->has_not_null != constr2->has_not_null)
477  return false;
478  if (constr1->has_generated_stored != constr2->has_generated_stored)
479  return false;
480  n = constr1->num_defval;
481  if (n != (int) constr2->num_defval)
482  return false;
483  /* We assume here that both AttrDefault arrays are in adnum order */
484  for (i = 0; i < n; i++)
485  {
486  AttrDefault *defval1 = constr1->defval + i;
487  AttrDefault *defval2 = constr2->defval + i;
488 
489  if (defval1->adnum != defval2->adnum)
490  return false;
491  if (strcmp(defval1->adbin, defval2->adbin) != 0)
492  return false;
493  }
494  if (constr1->missing)
495  {
496  if (!constr2->missing)
497  return false;
498  for (i = 0; i < tupdesc1->natts; i++)
499  {
500  AttrMissing *missval1 = constr1->missing + i;
501  AttrMissing *missval2 = constr2->missing + i;
502 
503  if (missval1->am_present != missval2->am_present)
504  return false;
505  if (missval1->am_present)
506  {
507  Form_pg_attribute missatt1 = TupleDescAttr(tupdesc1, i);
508 
509  if (!datumIsEqual(missval1->am_value, missval2->am_value,
510  missatt1->attbyval, missatt1->attlen))
511  return false;
512  }
513  }
514  }
515  else if (constr2->missing)
516  return false;
517  n = constr1->num_check;
518  if (n != (int) constr2->num_check)
519  return false;
520 
521  /*
522  * Similarly, we rely here on the ConstrCheck entries being sorted by
523  * name. If there are duplicate names, the outcome of the comparison
524  * is uncertain, but that should not happen.
525  */
526  for (i = 0; i < n; i++)
527  {
528  ConstrCheck *check1 = constr1->check + i;
529  ConstrCheck *check2 = constr2->check + i;
530 
531  if (!(strcmp(check1->ccname, check2->ccname) == 0 &&
532  strcmp(check1->ccbin, check2->ccbin) == 0 &&
533  check1->ccvalid == check2->ccvalid &&
534  check1->ccnoinherit == check2->ccnoinherit))
535  return false;
536  }
537  }
538  else if (tupdesc2->constr != NULL)
539  return false;
540  return true;
541 }
#define NameStr(name)
Definition: c.h:682
bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
Definition: datum.c:223
AttrNumber adnum
Definition: tupdesc.h:24

References AttrDefault::adbin, AttrDefault::adnum, AttrMissing::am_present, AttrMissing::am_value, ConstrCheck::ccbin, ConstrCheck::ccname, ConstrCheck::ccnoinherit, ConstrCheck::ccvalid, TupleConstr::check, TupleDescData::constr, datumIsEqual(), TupleConstr::defval, TupleConstr::has_generated_stored, TupleConstr::has_not_null, i, TupleConstr::missing, NameStr, TupleDescData::natts, TupleConstr::num_check, TupleConstr::num_defval, TupleDescData::tdtypeid, and TupleDescAttr.

Referenced by acquire_inherited_sample_rows(), ProcedureCreate(), record_type_typmod_compare(), RelationClearRelation(), RelationFindReplTupleSeq(), RevalidateCachedQuery(), and shared_record_table_compare().

◆ FreeTupleDesc()

void FreeTupleDesc ( TupleDesc  tupdesc)

Definition at line 309 of file tupdesc.c.

310 {
311  int i;
312 
313  /*
314  * Possibly this should assert tdrefcount == 0, to disallow explicit
315  * freeing of un-refcounted tupdescs?
316  */
317  Assert(tupdesc->tdrefcount <= 0);
318 
319  if (tupdesc->constr)
320  {
321  if (tupdesc->constr->num_defval > 0)
322  {
323  AttrDefault *attrdef = tupdesc->constr->defval;
324 
325  for (i = tupdesc->constr->num_defval - 1; i >= 0; i--)
326  pfree(attrdef[i].adbin);
327  pfree(attrdef);
328  }
329  if (tupdesc->constr->missing)
330  {
331  AttrMissing *attrmiss = tupdesc->constr->missing;
332 
333  for (i = tupdesc->natts - 1; i >= 0; i--)
334  {
335  if (attrmiss[i].am_present
336  && !TupleDescAttr(tupdesc, i)->attbyval)
337  pfree(DatumGetPointer(attrmiss[i].am_value));
338  }
339  pfree(attrmiss);
340  }
341  if (tupdesc->constr->num_check > 0)
342  {
343  ConstrCheck *check = tupdesc->constr->check;
344 
345  for (i = tupdesc->constr->num_check - 1; i >= 0; i--)
346  {
347  pfree(check[i].ccname);
348  pfree(check[i].ccbin);
349  }
350  pfree(check);
351  }
352  pfree(tupdesc->constr);
353  }
354 
355  pfree(tupdesc);
356 }
void pfree(void *pointer)
Definition: mcxt.c:1252
bool attbyval
Definition: pg_attribute.h:112
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:660

References Assert(), attbyval, TupleConstr::check, TupleDescData::constr, DatumGetPointer(), TupleConstr::defval, i, TupleConstr::missing, TupleDescData::natts, TupleConstr::num_check, TupleConstr::num_defval, pfree(), TupleDescData::tdrefcount, and TupleDescAttr.

Referenced by AddNewAttributeTuples(), AtEOXact_RelationCache(), DecrTupleDescRefCount(), ER_mc_callback(), ExecMakeTableFunctionResult(), ExecPrepareTuplestoreResult(), get_record_type_from_query(), ordered_set_startup(), PLy_result_dealloc(), RelationDestroyRelation(), RevalidateCachedQuery(), spgendscan(), TypeCacheRelCallback(), update_cached_tupdesc(), and walrcv_clear_result().

◆ hashTupleDesc()

uint32 hashTupleDesc ( TupleDesc  desc)

Definition at line 554 of file tupdesc.c.

555 {
556  uint32 s;
557  int i;
558 
559  s = hash_combine(0, hash_uint32(desc->natts));
560  s = hash_combine(s, hash_uint32(desc->tdtypeid));
561  for (i = 0; i < desc->natts; ++i)
562  s = hash_combine(s, hash_uint32(TupleDescAttr(desc, i)->atttypid));
563 
564  return s;
565 }
unsigned int uint32
Definition: c.h:442
static Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
static uint32 hash_combine(uint32 a, uint32 b)
Definition: hashfn.h:68

References hash_combine(), hash_uint32(), i, TupleDescData::natts, TupleDescData::tdtypeid, and TupleDescAttr.

Referenced by record_type_typmod_hash(), and shared_record_table_hash().

◆ IncrTupleDescRefCount()

void IncrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 366 of file tupdesc.c.

367 {
368  Assert(tupdesc->tdrefcount >= 0);
369 
371  tupdesc->tdrefcount++;
373 }
void ResourceOwnerRememberTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition: resowner.c:1209
void ResourceOwnerEnlargeTupleDescs(ResourceOwner owner)
Definition: resowner.c:1198

References Assert(), CurrentResourceOwner, ResourceOwnerEnlargeTupleDescs(), ResourceOwnerRememberTupleDesc(), and TupleDescData::tdrefcount.

Referenced by cache_record_field_properties(), and ExecEvalConvertRowtype().

◆ TupleDescCopy()

void TupleDescCopy ( TupleDesc  dst,
TupleDesc  src 
)

Definition at line 229 of file tupdesc.c.

230 {
231  int i;
232 
233  /* Flat-copy the header and attribute array */
234  memcpy(dst, src, TupleDescSize(src));
235 
236  /*
237  * Since we're not copying constraints and defaults, clear fields
238  * associated with them.
239  */
240  for (i = 0; i < dst->natts; i++)
241  {
242  Form_pg_attribute att = TupleDescAttr(dst, i);
243 
244  att->attnotnull = false;
245  att->atthasdef = false;
246  att->atthasmissing = false;
247  att->attidentity = '\0';
248  att->attgenerated = '\0';
249  }
250  dst->constr = NULL;
251 
252  /*
253  * Also, assume the destination is not to be ref-counted. (Copying the
254  * source's refcount would be wrong in any case.)
255  */
256  dst->tdrefcount = -1;
257 }
#define TupleDescSize(src)
Definition: tupdesc.h:102

References TupleDescData::constr, i, TupleDescData::natts, TupleDescData::tdrefcount, TupleDescAttr, and TupleDescSize.

Referenced by index_truncate_tuple(), and share_tupledesc().

◆ TupleDescCopyEntry()

void TupleDescCopyEntry ( TupleDesc  dst,
AttrNumber  dstAttno,
TupleDesc  src,
AttrNumber  srcAttno 
)

Definition at line 267 of file tupdesc.c.

269 {
270  Form_pg_attribute dstAtt = TupleDescAttr(dst, dstAttno - 1);
271  Form_pg_attribute srcAtt = TupleDescAttr(src, srcAttno - 1);
272 
273  /*
274  * sanity checks
275  */
278  AssertArg(srcAttno >= 1);
279  AssertArg(srcAttno <= src->natts);
280  AssertArg(dstAttno >= 1);
281  AssertArg(dstAttno <= dst->natts);
282 
283  memcpy(dstAtt, srcAtt, ATTRIBUTE_FIXED_PART_SIZE);
284 
285  /*
286  * Aside from updating the attno, we'd better reset attcacheoff.
287  *
288  * XXX Actually, to be entirely safe we'd need to reset the attcacheoff of
289  * all following columns in dst as well. Current usage scenarios don't
290  * require that though, because all following columns will get initialized
291  * by other uses of this function or TupleDescInitEntry. So we cheat a
292  * bit to avoid a useless O(N^2) penalty.
293  */
294  dstAtt->attnum = dstAttno;
295  dstAtt->attcacheoff = -1;
296 
297  /* since we're not copying constraints or defaults, clear these */
298  dstAtt->attnotnull = false;
299  dstAtt->atthasdef = false;
300  dstAtt->atthasmissing = false;
301  dstAtt->attidentity = '\0';
302  dstAtt->attgenerated = '\0';
303 }
#define PointerIsValid(pointer)
Definition: c.h:699

References AssertArg, ATTRIBUTE_FIXED_PART_SIZE, PointerIsValid, and TupleDescAttr.

Referenced by addRangeTableEntryForFunction(), ExecInitFunctionScan(), and ordered_set_startup().

◆ TupleDescInitBuiltinEntry()

void TupleDescInitBuiltinEntry ( TupleDesc  desc,
AttrNumber  attributeNumber,
const char *  attributeName,
Oid  oidtypeid,
int32  typmod,
int  attdim 
)

Definition at line 657 of file tupdesc.c.

663 {
664  Form_pg_attribute att;
665 
666  /* sanity checks */
667  AssertArg(PointerIsValid(desc));
668  AssertArg(attributeNumber >= 1);
669  AssertArg(attributeNumber <= desc->natts);
670 
671  /* initialize the attribute fields */
672  att = TupleDescAttr(desc, attributeNumber - 1);
673  att->attrelid = 0; /* dummy value */
674 
675  /* unlike TupleDescInitEntry, we require an attribute name */
676  Assert(attributeName != NULL);
677  namestrcpy(&(att->attname), attributeName);
678 
679  att->attstattarget = -1;
680  att->attcacheoff = -1;
681  att->atttypmod = typmod;
682 
683  att->attnum = attributeNumber;
684  att->attndims = attdim;
685 
686  att->attnotnull = false;
687  att->atthasdef = false;
688  att->atthasmissing = false;
689  att->attidentity = '\0';
690  att->attgenerated = '\0';
691  att->attisdropped = false;
692  att->attislocal = true;
693  att->attinhcount = 0;
694  /* variable-length fields are not present in tupledescs */
695 
696  att->atttypid = oidtypeid;
697 
698  /*
699  * Our goal here is to support just enough types to let basic builtin
700  * commands work without catalog access - e.g. so that we can do certain
701  * things even in processes that are not connected to a database.
702  */
703  switch (oidtypeid)
704  {
705  case TEXTOID:
706  case TEXTARRAYOID:
707  att->attlen = -1;
708  att->attbyval = false;
709  att->attalign = TYPALIGN_INT;
710  att->attstorage = TYPSTORAGE_EXTENDED;
711  att->attcompression = InvalidCompressionMethod;
712  att->attcollation = DEFAULT_COLLATION_OID;
713  break;
714 
715  case BOOLOID:
716  att->attlen = 1;
717  att->attbyval = true;
718  att->attalign = TYPALIGN_CHAR;
719  att->attstorage = TYPSTORAGE_PLAIN;
720  att->attcompression = InvalidCompressionMethod;
721  att->attcollation = InvalidOid;
722  break;
723 
724  case INT4OID:
725  att->attlen = 4;
726  att->attbyval = true;
727  att->attalign = TYPALIGN_INT;
728  att->attstorage = TYPSTORAGE_PLAIN;
729  att->attcompression = InvalidCompressionMethod;
730  att->attcollation = InvalidOid;
731  break;
732 
733  case INT8OID:
734  att->attlen = 8;
735  att->attbyval = FLOAT8PASSBYVAL;
736  att->attalign = TYPALIGN_DOUBLE;
737  att->attstorage = TYPSTORAGE_PLAIN;
738  att->attcompression = InvalidCompressionMethod;
739  att->attcollation = InvalidOid;
740  break;
741 
742  case OIDOID:
743  att->attlen = 4;
744  att->attbyval = true;
745  att->attalign = TYPALIGN_INT;
746  att->attstorage = TYPSTORAGE_PLAIN;
747  att->attcompression = InvalidCompressionMethod;
748  att->attcollation = InvalidOid;
749  break;
750 
751  default:
752  elog(ERROR, "unsupported type %u", oidtypeid);
753  }
754 }
#define FLOAT8PASSBYVAL
Definition: c.h:571
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidCompressionMethod

References Assert(), AssertArg, elog(), ERROR, FLOAT8PASSBYVAL, InvalidCompressionMethod, InvalidOid, namestrcpy(), PointerIsValid, and TupleDescAttr.

Referenced by CreateReplicationSlot(), IdentifySystem(), ReadReplicationSlot(), SendTablespaceList(), SendTimeLineHistory(), SendXlogRecPtrResult(), ShowAllGUCConfig(), ShowGUCConfigOption(), and StartReplication().

◆ TupleDescInitEntry()

void TupleDescInitEntry ( TupleDesc  desc,
AttrNumber  attributeNumber,
const char *  attributeName,
Oid  oidtypeid,
int32  typmod,
int  attdim 
)

Definition at line 583 of file tupdesc.c.

589 {
590  HeapTuple tuple;
591  Form_pg_type typeForm;
592  Form_pg_attribute att;
593 
594  /*
595  * sanity checks
596  */
597  AssertArg(PointerIsValid(desc));
598  AssertArg(attributeNumber >= 1);
599  AssertArg(attributeNumber <= desc->natts);
600 
601  /*
602  * initialize the attribute fields
603  */
604  att = TupleDescAttr(desc, attributeNumber - 1);
605 
606  att->attrelid = 0; /* dummy value */
607 
608  /*
609  * Note: attributeName can be NULL, because the planner doesn't always
610  * fill in valid resname values in targetlists, particularly for resjunk
611  * attributes. Also, do nothing if caller wants to re-use the old attname.
612  */
613  if (attributeName == NULL)
614  MemSet(NameStr(att->attname), 0, NAMEDATALEN);
615  else if (attributeName != NameStr(att->attname))
616  namestrcpy(&(att->attname), attributeName);
617 
618  att->attstattarget = -1;
619  att->attcacheoff = -1;
620  att->atttypmod = typmod;
621 
622  att->attnum = attributeNumber;
623  att->attndims = attdim;
624 
625  att->attnotnull = false;
626  att->atthasdef = false;
627  att->atthasmissing = false;
628  att->attidentity = '\0';
629  att->attgenerated = '\0';
630  att->attisdropped = false;
631  att->attislocal = true;
632  att->attinhcount = 0;
633  /* variable-length fields are not present in tupledescs */
634 
635  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(oidtypeid));
636  if (!HeapTupleIsValid(tuple))
637  elog(ERROR, "cache lookup failed for type %u", oidtypeid);
638  typeForm = (Form_pg_type) GETSTRUCT(tuple);
639 
640  att->atttypid = oidtypeid;
641  att->attlen = typeForm->typlen;
642  att->attbyval = typeForm->typbyval;
643  att->attalign = typeForm->typalign;
644  att->attstorage = typeForm->typstorage;
645  att->attcompression = InvalidCompressionMethod;
646  att->attcollation = typeForm->typcollation;
647 
648  ReleaseSysCache(tuple);
649 }
#define MemSet(start, val, len)
Definition: c.h:998
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:649
#define NAMEDATALEN
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:600
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1221
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1173
@ TYPEOID
Definition: syscache.h:114

References AssertArg, elog(), ERROR, GETSTRUCT, HeapTupleIsValid, InvalidCompressionMethod, MemSet, NAMEDATALEN, NameStr, namestrcpy(), ObjectIdGetDatum(), PointerIsValid, ReleaseSysCache(), SearchSysCache1(), TupleDescAttr, and TYPEOID.

Referenced by aclexplode(), addRangeTableEntryForFunction(), brtuple_disk_tupdesc(), build_function_result_tupdesc_d(), build_row_from_vars(), BuildDescForRelation(), BuildDescFromLists(), create_toast_table(), dblink_get_pkey(), ExecInitFunctionScan(), ExecMakeTableFunctionResult(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), ExplainResultDesc(), get_expr_result_type(), GetPGVariableResultDesc(), gistrescan(), init_sexpr(), initGinState(), libpqrcv_processTuples(), MakeOldSnapshotTimeMappingTupleDesc(), materializeResult(), ordered_set_startup(), pg_buffercache_pages(), pg_control_checkpoint(), pg_control_init(), pg_control_recovery(), pg_control_system(), pg_get_catalog_foreign_keys(), pg_get_keywords(), pg_get_multixact_members(), pg_get_object_address(), pg_get_publication_tables(), pg_identify_object(), pg_identify_object_as_address(), pg_last_committed_xact(), pg_lock_status(), pg_logdir_ls_internal(), pg_partition_tree(), pg_prepared_xact(), pg_sequence_parameters(), pg_stat_file(), pg_stat_get_archiver(), pg_stat_get_replication_slot(), pg_stat_get_subscription_stats(), pg_stat_get_wal(), pg_timezone_abbrevs(), pg_visibility_map_summary(), pg_visibility_tupdesc(), pg_walfile_name_offset(), pg_xact_commit_timestamp_origin(), prs_setup_firstcall(), resolve_polymorphic_tupdesc(), show_all_settings(), test_predtest(), ts_setup_firstcall(), tsvector_unnest(), tt_setup_firstcall(), and TypeGetTupleDesc().

◆ TupleDescInitEntryCollation()

void TupleDescInitEntryCollation ( TupleDesc  desc,
AttrNumber  attributeNumber,
Oid  collationid 
)

Definition at line 763 of file tupdesc.c.

766 {
767  /*
768  * sanity checks
769  */
770  AssertArg(PointerIsValid(desc));
771  AssertArg(attributeNumber >= 1);
772  AssertArg(attributeNumber <= desc->natts);
773 
774  TupleDescAttr(desc, attributeNumber - 1)->attcollation = collationid;
775 }

References AssertArg, PointerIsValid, and TupleDescAttr.

Referenced by addRangeTableEntryForFunction(), build_row_from_vars(), BuildDescForRelation(), BuildDescFromLists(), ExecInitFunctionScan(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), get_expr_result_type(), initGinState(), and resolve_polymorphic_tupdesc().