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 BuildDescFromLists (const List *names, const List *types, const List *typmods, const List *collations)
 
NodeTupleDescGetDefault (TupleDesc tupdesc, AttrNumber attnum)
 

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:193

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

◆ BuildDescFromLists()

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

Definition at line 814 of file tupdesc.c.

815 {
816  int natts;
818  ListCell *l1;
819  ListCell *l2;
820  ListCell *l3;
821  ListCell *l4;
822  TupleDesc desc;
823 
824  natts = list_length(names);
825  Assert(natts == list_length(types));
826  Assert(natts == list_length(typmods));
827  Assert(natts == list_length(collations));
828 
829  /*
830  * allocate a new tuple descriptor
831  */
832  desc = CreateTemplateTupleDesc(natts);
833 
834  attnum = 0;
835  forfour(l1, names, l2, types, l3, typmods, l4, collations)
836  {
837  char *attname = strVal(lfirst(l1));
838  Oid atttypid = lfirst_oid(l2);
839  int32 atttypmod = lfirst_int(l3);
840  Oid attcollation = lfirst_oid(l4);
841 
842  attnum++;
843 
844  TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
845  TupleDescInitEntryCollation(desc, attnum, attcollation);
846  }
847 
848  return desc;
849 }
int16 AttrNumber
Definition: attnum.h:21
signed int int32
Definition: c.h:483
struct typedefs * types
Definition: ecpg.c:29
Assert(fmt[strlen(fmt) - 1] !='\n')
NameData attname
Definition: pg_attribute.h:41
int16 attnum
Definition: pg_attribute.h:74
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
#define lfirst_int(lc)
Definition: pg_list.h:173
#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4)
Definition: pg_list.h:524
#define lfirst_oid(lc)
Definition: pg_list.h:174
unsigned int Oid
Definition: postgres_ext.h:31
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:67
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:789
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:605
#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 67 of file tupdesc.c.

68 {
69  TupleDesc desc;
70 
71  /*
72  * sanity checks
73  */
74  Assert(natts >= 0);
75 
76  /*
77  * Allocate enough memory for the tuple descriptor, including the
78  * attribute rows.
79  *
80  * Note: the attribute array stride is sizeof(FormData_pg_attribute),
81  * since we declare the array elements as FormData_pg_attribute for
82  * notational convenience. However, we only guarantee that the first
83  * ATTRIBUTE_FIXED_PART_SIZE bytes of each entry are valid; most code that
84  * copies tupdesc entries around copies just that much. In principle that
85  * could be less due to trailing padding, although with the current
86  * definition of pg_attribute there probably isn't any padding.
87  */
88  desc = (TupleDesc) palloc(offsetof(struct TupleDescData, attrs) +
89  natts * sizeof(FormData_pg_attribute));
90 
91  /*
92  * Initialize other fields of the tupdesc.
93  */
94  desc->natts = natts;
95  desc->constr = NULL;
96  desc->tdtypeid = RECORDOID;
97  desc->tdtypmod = -1;
98  desc->tdrefcount = -1; /* assume not reference-counted */
99 
100  return desc;
101 }
void * palloc(Size size)
Definition: mcxt.c:1226
int tdrefcount
Definition: tupdesc.h:84
TupleConstr * constr
Definition: tupdesc.h:85
int32 tdtypmod
Definition: tupdesc.h:83
Oid tdtypeid
Definition: tupdesc.h:82
struct TupleDescData * TupleDesc
Definition: tupdesc.h:89

References Assert(), 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(), materializeResult(), ordered_set_startup(), pg_buffercache_pages(), pg_get_publication_tables(), pg_lock_status(), pg_logdir_ls_internal(), pg_prepared_xact(), pg_stat_file(), pg_stat_get_archiver(), pg_stat_get_backend_subxact(), pg_stat_get_replication_slot(), pg_stat_get_subscription_stats(), pg_stat_get_wal(), pg_visibility_tupdesc(), pg_walfile_name_offset(), ReadReplicationSlot(), SendTablespaceList(), SendTimeLineHistory(), SendXlogRecPtrResult(), show_all_settings(), ShowAllGUCConfig(), ShowGUCConfigOption(), StartReplication(), test_predtest(), tsvector_unnest(), and TypeGetTupleDesc().

◆ CreateTupleDesc()

TupleDesc CreateTupleDesc ( int  natts,
Form_pg_attribute attrs 
)

Definition at line 112 of file tupdesc.c.

113 {
114  TupleDesc desc;
115  int i;
116 
117  desc = CreateTemplateTupleDesc(natts);
118 
119  for (i = 0; i < natts; ++i)
120  memcpy(TupleDescAttr(desc, i), attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
121 
122  return desc;
123 }
int i
Definition: isn.c:73
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:201
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92

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

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

◆ CreateTupleDescCopy()

TupleDesc CreateTupleDescCopy ( TupleDesc  tupdesc)

Definition at line 133 of file tupdesc.c.

134 {
135  TupleDesc desc;
136  int i;
137 
138  desc = CreateTemplateTupleDesc(tupdesc->natts);
139 
140  /* Flat-copy the attribute array */
141  memcpy(TupleDescAttr(desc, 0),
142  TupleDescAttr(tupdesc, 0),
143  desc->natts * sizeof(FormData_pg_attribute));
144 
145  /*
146  * Since we're not copying constraints and defaults, clear fields
147  * associated with them.
148  */
149  for (i = 0; i < desc->natts; i++)
150  {
151  Form_pg_attribute att = TupleDescAttr(desc, i);
152 
153  att->attnotnull = false;
154  att->atthasdef = false;
155  att->atthasmissing = false;
156  att->attidentity = '\0';
157  att->attgenerated = '\0';
158  }
159 
160  /* We can copy the tuple type identification, too */
161  desc->tdtypeid = tupdesc->tdtypeid;
162  desc->tdtypmod = tupdesc->tdtypmod;
163 
164  return desc;
165 }
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209

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(), gist_page_items(), init_sexpr(), InitMaterializedSRF(), 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(), spi_dest_startup(), storeRow(), update_cached_tupdesc(), and UtilityTupleDescriptor().

◆ CreateTupleDescCopyConstr()

TupleDesc CreateTupleDescCopyConstr ( TupleDesc  tupdesc)

Definition at line 173 of file tupdesc.c.

174 {
175  TupleDesc desc;
176  TupleConstr *constr = tupdesc->constr;
177  int i;
178 
179  desc = CreateTemplateTupleDesc(tupdesc->natts);
180 
181  /* Flat-copy the attribute array */
182  memcpy(TupleDescAttr(desc, 0),
183  TupleDescAttr(tupdesc, 0),
184  desc->natts * sizeof(FormData_pg_attribute));
185 
186  /* Copy the TupleConstr data structure, if any */
187  if (constr)
188  {
189  TupleConstr *cpy = (TupleConstr *) palloc0(sizeof(TupleConstr));
190 
191  cpy->has_not_null = constr->has_not_null;
193 
194  if ((cpy->num_defval = constr->num_defval) > 0)
195  {
196  cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault));
197  memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault));
198  for (i = cpy->num_defval - 1; i >= 0; i--)
199  cpy->defval[i].adbin = pstrdup(constr->defval[i].adbin);
200  }
201 
202  if (constr->missing)
203  {
204  cpy->missing = (AttrMissing *) palloc(tupdesc->natts * sizeof(AttrMissing));
205  memcpy(cpy->missing, constr->missing, tupdesc->natts * sizeof(AttrMissing));
206  for (i = tupdesc->natts - 1; i >= 0; i--)
207  {
208  if (constr->missing[i].am_present)
209  {
210  Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
211 
212  cpy->missing[i].am_value = datumCopy(constr->missing[i].am_value,
213  attr->attbyval,
214  attr->attlen);
215  }
216  }
217  }
218 
219  if ((cpy->num_check = constr->num_check) > 0)
220  {
221  cpy->check = (ConstrCheck *) palloc(cpy->num_check * sizeof(ConstrCheck));
222  memcpy(cpy->check, constr->check, cpy->num_check * sizeof(ConstrCheck));
223  for (i = cpy->num_check - 1; i >= 0; i--)
224  {
225  cpy->check[i].ccname = pstrdup(constr->check[i].ccname);
226  cpy->check[i].ccbin = pstrdup(constr->check[i].ccbin);
227  cpy->check[i].ccvalid = constr->check[i].ccvalid;
228  cpy->check[i].ccnoinherit = constr->check[i].ccnoinherit;
229  }
230  }
231 
232  desc->constr = cpy;
233  }
234 
235  /* We can copy the tuple type identification, too */
236  desc->tdtypeid = tupdesc->tdtypeid;
237  desc->tdtypmod = tupdesc->tdtypmod;
238 
239  return desc;
240 }
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:132
char * pstrdup(const char *in)
Definition: mcxt.c:1644
void * palloc0(Size size)
Definition: mcxt.c:1257
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
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

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(), init_tuple_slot(), initGISTstate(), and lookup_rowtype_tupdesc_copy().

◆ DecrTupleDescRefCount()

void DecrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 406 of file tupdesc.c.

407 {
408  Assert(tupdesc->tdrefcount > 0);
409 
411  if (--tupdesc->tdrefcount == 0)
412  FreeTupleDesc(tupdesc);
413 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:164
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:331
static void ResourceOwnerForgetTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition: tupdesc.c:54

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

Referenced by cache_record_field_properties(), and ExecEvalConvertRowtype().

◆ equalTupleDescs()

bool equalTupleDescs ( TupleDesc  tupdesc1,
TupleDesc  tupdesc2 
)

Definition at line 424 of file tupdesc.c.

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

332 {
333  int i;
334 
335  /*
336  * Possibly this should assert tdrefcount == 0, to disallow explicit
337  * freeing of un-refcounted tupdescs?
338  */
339  Assert(tupdesc->tdrefcount <= 0);
340 
341  if (tupdesc->constr)
342  {
343  if (tupdesc->constr->num_defval > 0)
344  {
345  AttrDefault *attrdef = tupdesc->constr->defval;
346 
347  for (i = tupdesc->constr->num_defval - 1; i >= 0; i--)
348  pfree(attrdef[i].adbin);
349  pfree(attrdef);
350  }
351  if (tupdesc->constr->missing)
352  {
353  AttrMissing *attrmiss = tupdesc->constr->missing;
354 
355  for (i = tupdesc->natts - 1; i >= 0; i--)
356  {
357  if (attrmiss[i].am_present
358  && !TupleDescAttr(tupdesc, i)->attbyval)
359  pfree(DatumGetPointer(attrmiss[i].am_value));
360  }
361  pfree(attrmiss);
362  }
363  if (tupdesc->constr->num_check > 0)
364  {
365  ConstrCheck *check = tupdesc->constr->check;
366 
367  for (i = tupdesc->constr->num_check - 1; i >= 0; i--)
368  {
369  pfree(check[i].ccname);
370  pfree(check[i].ccbin);
371  }
372  pfree(check);
373  }
374  pfree(tupdesc->constr);
375  }
376 
377  pfree(tupdesc);
378 }
void pfree(void *pointer)
Definition: mcxt.c:1456
bool attbyval
Definition: pg_attribute.h:103
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312

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(), ResOwnerReleaseTupleDesc(), RevalidateCachedQuery(), spgendscan(), TypeCacheRelCallback(), update_cached_tupdesc(), and walrcv_clear_result().

◆ hashTupleDesc()

uint32 hashTupleDesc ( TupleDesc  desc)

Definition at line 576 of file tupdesc.c.

577 {
578  uint32 s;
579  int i;
580 
581  s = hash_combine(0, hash_uint32(desc->natts));
582  s = hash_combine(s, hash_uint32(desc->tdtypeid));
583  for (i = 0; i < desc->natts; ++i)
584  s = hash_combine(s, hash_uint32(TupleDescAttr(desc, i)->atttypid));
585 
586  return s;
587 }
unsigned int uint32
Definition: c.h:495
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 388 of file tupdesc.c.

389 {
390  Assert(tupdesc->tdrefcount >= 0);
391 
393  tupdesc->tdrefcount++;
395 }
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:448
static void ResourceOwnerRememberTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition: tupdesc.c:48

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

Referenced by cache_record_field_properties(), and ExecEvalConvertRowtype().

◆ TupleDescCopy()

void TupleDescCopy ( TupleDesc  dst,
TupleDesc  src 
)

Definition at line 251 of file tupdesc.c.

252 {
253  int i;
254 
255  /* Flat-copy the header and attribute array */
256  memcpy(dst, src, TupleDescSize(src));
257 
258  /*
259  * Since we're not copying constraints and defaults, clear fields
260  * associated with them.
261  */
262  for (i = 0; i < dst->natts; i++)
263  {
264  Form_pg_attribute att = TupleDescAttr(dst, i);
265 
266  att->attnotnull = false;
267  att->atthasdef = false;
268  att->atthasmissing = false;
269  att->attidentity = '\0';
270  att->attgenerated = '\0';
271  }
272  dst->constr = NULL;
273 
274  /*
275  * Also, assume the destination is not to be ref-counted. (Copying the
276  * source's refcount would be wrong in any case.)
277  */
278  dst->tdrefcount = -1;
279 }
#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 289 of file tupdesc.c.

291 {
292  Form_pg_attribute dstAtt = TupleDescAttr(dst, dstAttno - 1);
293  Form_pg_attribute srcAtt = TupleDescAttr(src, srcAttno - 1);
294 
295  /*
296  * sanity checks
297  */
298  Assert(PointerIsValid(src));
299  Assert(PointerIsValid(dst));
300  Assert(srcAttno >= 1);
301  Assert(srcAttno <= src->natts);
302  Assert(dstAttno >= 1);
303  Assert(dstAttno <= dst->natts);
304 
305  memcpy(dstAtt, srcAtt, ATTRIBUTE_FIXED_PART_SIZE);
306 
307  /*
308  * Aside from updating the attno, we'd better reset attcacheoff.
309  *
310  * XXX Actually, to be entirely safe we'd need to reset the attcacheoff of
311  * all following columns in dst as well. Current usage scenarios don't
312  * require that though, because all following columns will get initialized
313  * by other uses of this function or TupleDescInitEntry. So we cheat a
314  * bit to avoid a useless O(N^2) penalty.
315  */
316  dstAtt->attnum = dstAttno;
317  dstAtt->attcacheoff = -1;
318 
319  /* since we're not copying constraints or defaults, clear these */
320  dstAtt->attnotnull = false;
321  dstAtt->atthasdef = false;
322  dstAtt->atthasmissing = false;
323  dstAtt->attidentity = '\0';
324  dstAtt->attgenerated = '\0';
325 }
#define PointerIsValid(pointer)
Definition: c.h:752

References Assert(), ATTRIBUTE_FIXED_PART_SIZE, PointerIsValid, and TupleDescAttr.

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

◆ TupleDescGetDefault()

Node* TupleDescGetDefault ( TupleDesc  tupdesc,
AttrNumber  attnum 
)

Definition at line 855 of file tupdesc.c.

856 {
857  Node *result = NULL;
858 
859  if (tupdesc->constr)
860  {
861  AttrDefault *attrdef = tupdesc->constr->defval;
862 
863  for (int i = 0; i < tupdesc->constr->num_defval; i++)
864  {
865  if (attrdef[i].adnum == attnum)
866  {
867  result = stringToNode(attrdef[i].adbin);
868  break;
869  }
870  }
871  }
872 
873  return result;
874 }
void * stringToNode(const char *str)
Definition: read.c:90
Definition: nodes.h:129

References attnum, TupleDescData::constr, TupleConstr::defval, i, TupleConstr::num_defval, and stringToNode().

Referenced by build_column_default(), expandTableLikeClause(), and MergeAttributes().

◆ TupleDescInitBuiltinEntry()

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

Definition at line 681 of file tupdesc.c.

687 {
688  Form_pg_attribute att;
689 
690  /* sanity checks */
691  Assert(PointerIsValid(desc));
692  Assert(attributeNumber >= 1);
693  Assert(attributeNumber <= desc->natts);
694  Assert(attdim >= 0);
695  Assert(attdim <= PG_INT16_MAX);
696 
697  /* initialize the attribute fields */
698  att = TupleDescAttr(desc, attributeNumber - 1);
699  att->attrelid = 0; /* dummy value */
700 
701  /* unlike TupleDescInitEntry, we require an attribute name */
702  Assert(attributeName != NULL);
703  namestrcpy(&(att->attname), attributeName);
704 
705  att->attstattarget = -1;
706  att->attcacheoff = -1;
707  att->atttypmod = typmod;
708 
709  att->attnum = attributeNumber;
710  att->attndims = attdim;
711 
712  att->attnotnull = false;
713  att->atthasdef = false;
714  att->atthasmissing = false;
715  att->attidentity = '\0';
716  att->attgenerated = '\0';
717  att->attisdropped = false;
718  att->attislocal = true;
719  att->attinhcount = 0;
720  /* variable-length fields are not present in tupledescs */
721 
722  att->atttypid = oidtypeid;
723 
724  /*
725  * Our goal here is to support just enough types to let basic builtin
726  * commands work without catalog access - e.g. so that we can do certain
727  * things even in processes that are not connected to a database.
728  */
729  switch (oidtypeid)
730  {
731  case TEXTOID:
732  case TEXTARRAYOID:
733  att->attlen = -1;
734  att->attbyval = false;
735  att->attalign = TYPALIGN_INT;
736  att->attstorage = TYPSTORAGE_EXTENDED;
737  att->attcompression = InvalidCompressionMethod;
738  att->attcollation = DEFAULT_COLLATION_OID;
739  break;
740 
741  case BOOLOID:
742  att->attlen = 1;
743  att->attbyval = true;
744  att->attalign = TYPALIGN_CHAR;
745  att->attstorage = TYPSTORAGE_PLAIN;
746  att->attcompression = InvalidCompressionMethod;
747  att->attcollation = InvalidOid;
748  break;
749 
750  case INT4OID:
751  att->attlen = 4;
752  att->attbyval = true;
753  att->attalign = TYPALIGN_INT;
754  att->attstorage = TYPSTORAGE_PLAIN;
755  att->attcompression = InvalidCompressionMethod;
756  att->attcollation = InvalidOid;
757  break;
758 
759  case INT8OID:
760  att->attlen = 8;
761  att->attbyval = FLOAT8PASSBYVAL;
762  att->attalign = TYPALIGN_DOUBLE;
763  att->attstorage = TYPSTORAGE_PLAIN;
764  att->attcompression = InvalidCompressionMethod;
765  att->attcollation = InvalidOid;
766  break;
767 
768  case OIDOID:
769  att->attlen = 4;
770  att->attbyval = true;
771  att->attalign = TYPALIGN_INT;
772  att->attstorage = TYPSTORAGE_PLAIN;
773  att->attcompression = InvalidCompressionMethod;
774  att->attcollation = InvalidOid;
775  break;
776 
777  default:
778  elog(ERROR, "unsupported type %u", oidtypeid);
779  }
780 }
#define FLOAT8PASSBYVAL
Definition: c.h:624
#define PG_INT16_MAX
Definition: c.h:575
#define ERROR
Definition: elog.h:39
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define InvalidOid
Definition: postgres_ext.h:36
#define InvalidCompressionMethod

References Assert(), elog(), ERROR, FLOAT8PASSBYVAL, InvalidCompressionMethod, InvalidOid, namestrcpy(), PG_INT16_MAX, 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 605 of file tupdesc.c.

611 {
612  HeapTuple tuple;
613  Form_pg_type typeForm;
614  Form_pg_attribute att;
615 
616  /*
617  * sanity checks
618  */
619  Assert(PointerIsValid(desc));
620  Assert(attributeNumber >= 1);
621  Assert(attributeNumber <= desc->natts);
622  Assert(attdim >= 0);
623  Assert(attdim <= PG_INT16_MAX);
624 
625  /*
626  * initialize the attribute fields
627  */
628  att = TupleDescAttr(desc, attributeNumber - 1);
629 
630  att->attrelid = 0; /* dummy value */
631 
632  /*
633  * Note: attributeName can be NULL, because the planner doesn't always
634  * fill in valid resname values in targetlists, particularly for resjunk
635  * attributes. Also, do nothing if caller wants to re-use the old attname.
636  */
637  if (attributeName == NULL)
638  MemSet(NameStr(att->attname), 0, NAMEDATALEN);
639  else if (attributeName != NameStr(att->attname))
640  namestrcpy(&(att->attname), attributeName);
641 
642  att->attstattarget = -1;
643  att->attcacheoff = -1;
644  att->atttypmod = typmod;
645 
646  att->attnum = attributeNumber;
647  att->attndims = attdim;
648 
649  att->attnotnull = false;
650  att->atthasdef = false;
651  att->atthasmissing = false;
652  att->attidentity = '\0';
653  att->attgenerated = '\0';
654  att->attisdropped = false;
655  att->attislocal = true;
656  att->attinhcount = 0;
657  /* variable-length fields are not present in tupledescs */
658 
659  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(oidtypeid));
660  if (!HeapTupleIsValid(tuple))
661  elog(ERROR, "cache lookup failed for type %u", oidtypeid);
662  typeForm = (Form_pg_type) GETSTRUCT(tuple);
663 
664  att->atttypid = oidtypeid;
665  att->attlen = typeForm->typlen;
666  att->attbyval = typeForm->typbyval;
667  att->attalign = typeForm->typalign;
668  att->attstorage = typeForm->typstorage;
669  att->attcompression = InvalidCompressionMethod;
670  att->attcollation = typeForm->typcollation;
671 
672  ReleaseSysCache(tuple);
673 }
#define MemSet(start, val, len)
Definition: c.h:1009
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
#define NAMEDATALEN
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:868
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:820
@ TYPEOID
Definition: syscache.h:114

References Assert(), elog(), ERROR, GETSTRUCT, HeapTupleIsValid, InvalidCompressionMethod, MemSet, NAMEDATALEN, NameStr, namestrcpy(), ObjectIdGetDatum(), PG_INT16_MAX, 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(), materializeResult(), ordered_set_startup(), pg_buffercache_pages(), pg_get_publication_tables(), pg_lock_status(), pg_logdir_ls_internal(), pg_prepared_xact(), pg_stat_file(), pg_stat_get_archiver(), pg_stat_get_backend_subxact(), pg_stat_get_replication_slot(), pg_stat_get_subscription_stats(), pg_stat_get_wal(), pg_visibility_tupdesc(), pg_walfile_name_offset(), resolve_polymorphic_tupdesc(), show_all_settings(), test_predtest(), tsvector_unnest(), and TypeGetTupleDesc().

◆ TupleDescInitEntryCollation()

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

Definition at line 789 of file tupdesc.c.

792 {
793  /*
794  * sanity checks
795  */
796  Assert(PointerIsValid(desc));
797  Assert(attributeNumber >= 1);
798  Assert(attributeNumber <= desc->natts);
799 
800  TupleDescAttr(desc, attributeNumber - 1)->attcollation = collationid;
801 }

References Assert(), 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().