PostgreSQL Source Code git master
Loading...
Searching...
No Matches
tupdesc.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/toast_compression.h"
#include "access/tupdesc_details.h"
#include "catalog/catalog.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "common/hashfn.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/resowner.h"
#include "utils/syscache.h"
Include dependency graph for tupdesc.c:

Go to the source code of this file.

Functions

static void ResOwnerReleaseTupleDesc (Datum res)
 
static charResOwnerPrintTupleDesc (Datum res)
 
static void ResourceOwnerRememberTupleDesc (ResourceOwner owner, TupleDesc tupdesc)
 
static void ResourceOwnerForgetTupleDesc (ResourceOwner owner, TupleDesc tupdesc)
 
static void populate_compact_attribute_internal (Form_pg_attribute src, CompactAttribute *dst)
 
void populate_compact_attribute (TupleDesc tupdesc, int attnum)
 
void verify_compact_attribute (TupleDesc tupdesc, int attnum)
 
TupleDesc CreateTemplateTupleDesc (int natts)
 
TupleDesc CreateTupleDesc (int natts, Form_pg_attribute *attrs)
 
TupleDesc CreateTupleDescCopy (TupleDesc tupdesc)
 
TupleDesc CreateTupleDescTruncatedCopy (TupleDesc tupdesc, int natts)
 
TupleDesc CreateTupleDescCopyConstr (TupleDesc tupdesc)
 
void TupleDescCopy (TupleDesc dst, TupleDesc src)
 
void TupleDescCopyEntry (TupleDesc dst, AttrNumber dstAttno, TupleDesc src, AttrNumber srcAttno)
 
void TupleDescFinalize (TupleDesc tupdesc)
 
void FreeTupleDesc (TupleDesc tupdesc)
 
void IncrTupleDescRefCount (TupleDesc tupdesc)
 
void DecrTupleDescRefCount (TupleDesc tupdesc)
 
bool equalTupleDescs (TupleDesc tupdesc1, TupleDesc tupdesc2)
 
bool equalRowTypes (TupleDesc tupdesc1, TupleDesc tupdesc2)
 
uint32 hashRowType (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)
 

Variables

static const ResourceOwnerDesc tupdesc_resowner_desc
 

Function Documentation

◆ BuildDescFromLists()

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

Definition at line 1109 of file tupdesc.c.

1110{
1111 int natts;
1113 ListCell *l1;
1114 ListCell *l2;
1115 ListCell *l3;
1116 ListCell *l4;
1117 TupleDesc desc;
1118
1119 natts = list_length(names);
1120 Assert(natts == list_length(types));
1121 Assert(natts == list_length(typmods));
1122 Assert(natts == list_length(collations));
1123
1124 /*
1125 * allocate a new tuple descriptor
1126 */
1127 desc = CreateTemplateTupleDesc(natts);
1128
1129 attnum = 0;
1130 forfour(l1, names, l2, types, l3, typmods, l4, collations)
1131 {
1132 char *attname = strVal(lfirst(l1));
1133 Oid atttypid = lfirst_oid(l2);
1134 int32 atttypmod = lfirst_int(l3);
1135 Oid attcollation = lfirst_oid(l4);
1136
1137 attnum++;
1138
1139 TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
1140 TupleDescInitEntryCollation(desc, attnum, attcollation);
1141 }
1142
1143 TupleDescFinalize(desc);
1144
1145 return desc;
1146}
int16 AttrNumber
Definition attnum.h:21
#define Assert(condition)
Definition c.h:945
int32_t int32
Definition c.h:614
struct typedefs * types
Definition ecpg.c:30
NameData attname
int16 attnum
#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:575
#define lfirst_oid(lc)
Definition pg_list.h:174
unsigned int Oid
static int fb(int x)
TupleDesc CreateTemplateTupleDesc(int natts)
Definition tupdesc.c:165
void TupleDescFinalize(TupleDesc tupdesc)
Definition tupdesc.c:511
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition tupdesc.c:1084
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition tupdesc.c:900
#define strVal(v)
Definition value.h:82

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

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

◆ CreateTemplateTupleDesc()

TupleDesc CreateTemplateTupleDesc ( int  natts)

Definition at line 165 of file tupdesc.c.

166{
167 TupleDesc desc;
168
169 /*
170 * sanity checks
171 */
172 Assert(natts >= 0);
173
174 /*
175 * Allocate enough memory for the tuple descriptor, the CompactAttribute
176 * array and also an array of FormData_pg_attribute.
177 *
178 * Note: the FormData_pg_attribute array stride is
179 * sizeof(FormData_pg_attribute), since we declare the array elements as
180 * FormData_pg_attribute for notational convenience. However, we only
181 * guarantee that the first ATTRIBUTE_FIXED_PART_SIZE bytes of each entry
182 * are valid; most code that copies tupdesc entries around copies just
183 * that much. In principle that could be less due to trailing padding,
184 * although with the current definition of pg_attribute there probably
185 * isn't any padding.
186 */
187 desc = (TupleDesc) palloc(offsetof(struct TupleDescData, compact_attrs) +
188 natts * sizeof(CompactAttribute) +
189 natts * sizeof(FormData_pg_attribute));
190
191 /*
192 * Initialize other fields of the tupdesc.
193 */
194 desc->natts = natts;
195 desc->constr = NULL;
196 desc->tdtypeid = RECORDOID;
197 desc->tdtypmod = -1;
198 desc->tdrefcount = -1; /* assume not reference-counted */
199
200 /* This will be set to the correct value by TupleDescFinalize() */
201 desc->firstNonCachedOffsetAttr = -1;
202 desc->firstNonGuaranteedAttr = -1;
203
204 return desc;
205}
void * palloc(Size size)
Definition mcxt.c:1387
FormData_pg_attribute
int firstNonCachedOffsetAttr
Definition tupdesc.h:154
TupleConstr * constr
Definition tupdesc.h:159
int32 tdtypmod
Definition tupdesc.h:152
int firstNonGuaranteedAttr
Definition tupdesc.h:156
struct TupleDescData * TupleDesc
Definition tupdesc.h:163

References Assert, TupleDescData::constr, fb(), TupleDescData::firstNonCachedOffsetAttr, TupleDescData::firstNonGuaranteedAttr, FormData_pg_attribute, TupleDescData::natts, palloc(), TupleDescData::tdrefcount, TupleDescData::tdtypeid, and TupleDescData::tdtypmod.

Referenced by aclexplode(), addRangeTableEntryForFunction(), AllocateRelationDesc(), BeginCopyTo(), brtuple_disk_tupdesc(), build_function_result_tupdesc_d(), build_row_from_vars(), BuildDescForRelation(), BuildDescFromLists(), BuildHardcodedDescriptor(), ConstructTupleDescriptor(), create_toast_table(), CreateReplicationSlot(), CreateTupleDesc(), CreateTupleDescCopy(), CreateTupleDescCopyConstr(), CreateTupleDescTruncatedCopy(), 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(), materializeQueryResult(), materializeResult(), ordered_set_startup(), pg_buffercache_os_pages_internal(), pg_buffercache_pages(), pg_get_publication_tables(), pg_get_sequence_data(), pg_lock_status(), 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_wal_build_tuple(), pg_visibility_tupdesc(), pg_walfile_name_offset(), ReadReplicationSlot(), SendTablespaceList(), SendTimeLineHistory(), SendXlogRecPtrResult(), show_all_settings(), ShowAllGUCConfig(), ShowGUCConfigOption(), StartReplication(), test_custom_stats_fixed_report(), test_predtest(), tsvector_unnest(), TypeGetTupleDesc(), and WaitStmtResultDesc().

◆ CreateTupleDesc()

TupleDesc CreateTupleDesc ( int  natts,
Form_pg_attribute attrs 
)

Definition at line 216 of file tupdesc.c.

217{
218 TupleDesc desc;
219 int i;
220
221 desc = CreateTemplateTupleDesc(natts);
222
223 for (i = 0; i < natts; ++i)
224 {
227 }
228
229 TupleDescFinalize(desc);
230
231 return desc;
232}
int i
Definition isn.c:77
#define ATTRIBUTE_FIXED_PART_SIZE
void populate_compact_attribute(TupleDesc tupdesc, int attnum)
Definition tupdesc.c:100
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:178

References ATTRIBUTE_FIXED_PART_SIZE, CreateTemplateTupleDesc(), fb(), i, populate_compact_attribute(), TupleDescAttr(), and TupleDescFinalize().

Referenced by AddNewAttributeTuples(), and InsertOneTuple().

◆ CreateTupleDescCopy()

TupleDesc CreateTupleDescCopy ( TupleDesc  tupdesc)

Definition at line 242 of file tupdesc.c.

243{
244 TupleDesc desc;
245 int i;
246
247 desc = CreateTemplateTupleDesc(tupdesc->natts);
248
249 /* Flat-copy the attribute array (unless there are no attributes) */
250 if (desc->natts > 0)
251 memcpy(TupleDescAttr(desc, 0),
252 TupleDescAttr(tupdesc, 0),
253 desc->natts * sizeof(FormData_pg_attribute));
254
255 /*
256 * Since we're not copying constraints and defaults, clear fields
257 * associated with them.
258 */
259 for (i = 0; i < desc->natts; i++)
260 {
262
263 att->attnotnull = false;
264 att->atthasdef = false;
265 att->atthasmissing = false;
266 att->attidentity = '\0';
267 att->attgenerated = '\0';
268
270 }
271
272 /* We can copy the tuple type identification, too */
273 desc->tdtypeid = tupdesc->tdtypeid;
274 desc->tdtypmod = tupdesc->tdtypmod;
275
276 TupleDescFinalize(desc);
277
278 return desc;
279}
FormData_pg_attribute * Form_pg_attribute

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

Referenced by assign_record_type_typmod(), BuildTupleHashTable(), cfunc_hashtable_insert(), CompleteCachedPlan(), 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(), 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(), sql_compile_callback(), storeRow(), update_cached_tupdesc(), and UtilityTupleDescriptor().

◆ CreateTupleDescCopyConstr()

TupleDesc CreateTupleDescCopyConstr ( TupleDesc  tupdesc)

Definition at line 336 of file tupdesc.c.

337{
338 TupleDesc desc;
339 TupleConstr *constr = tupdesc->constr;
340 int i;
341
342 desc = CreateTemplateTupleDesc(tupdesc->natts);
343
344 /* Flat-copy the attribute array (unless there are no attributes) */
345 if (desc->natts > 0)
346 memcpy(TupleDescAttr(desc, 0),
347 TupleDescAttr(tupdesc, 0),
348 desc->natts * sizeof(FormData_pg_attribute));
349
350 for (i = 0; i < desc->natts; i++)
351 {
353
356 }
357
358 /* Copy the TupleConstr data structure, if any */
359 if (constr)
360 {
362
363 cpy->has_not_null = constr->has_not_null;
364 cpy->has_generated_stored = constr->has_generated_stored;
365 cpy->has_generated_virtual = constr->has_generated_virtual;
366
367 if ((cpy->num_defval = constr->num_defval) > 0)
368 {
369 cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault));
370 memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault));
371 for (i = cpy->num_defval - 1; i >= 0; i--)
372 cpy->defval[i].adbin = pstrdup(constr->defval[i].adbin);
373 }
374
375 if (constr->missing)
376 {
377 cpy->missing = (AttrMissing *) palloc(tupdesc->natts * sizeof(AttrMissing));
378 memcpy(cpy->missing, constr->missing, tupdesc->natts * sizeof(AttrMissing));
379 for (i = tupdesc->natts - 1; i >= 0; i--)
380 {
381 if (constr->missing[i].am_present)
382 {
383 CompactAttribute *attr = TupleDescCompactAttr(tupdesc, i);
384
385 cpy->missing[i].am_value = datumCopy(constr->missing[i].am_value,
386 attr->attbyval,
387 attr->attlen);
388 }
389 }
390 }
391
392 if ((cpy->num_check = constr->num_check) > 0)
393 {
394 cpy->check = (ConstrCheck *) palloc(cpy->num_check * sizeof(ConstrCheck));
395 memcpy(cpy->check, constr->check, cpy->num_check * sizeof(ConstrCheck));
396 for (i = cpy->num_check - 1; i >= 0; i--)
397 {
398 cpy->check[i].ccname = pstrdup(constr->check[i].ccname);
399 cpy->check[i].ccbin = pstrdup(constr->check[i].ccbin);
400 cpy->check[i].ccenforced = constr->check[i].ccenforced;
401 cpy->check[i].ccvalid = constr->check[i].ccvalid;
402 cpy->check[i].ccnoinherit = constr->check[i].ccnoinherit;
403 }
404 }
405
406 desc->constr = cpy;
407 }
408
409 /* We can copy the tuple type identification, too */
410 desc->tdtypeid = tupdesc->tdtypeid;
411 desc->tdtypmod = tupdesc->tdtypmod;
412
413 TupleDescFinalize(desc);
414
415 return desc;
416}
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition datum.c:132
#define palloc0_object(type)
Definition fe_memutils.h:75
char * pstrdup(const char *in)
Definition mcxt.c:1781
char * adbin
Definition tupdesc.h:25
char attnullability
Definition tupdesc.h:80
char * ccname
Definition tupdesc.h:30
bool ccenforced
Definition tupdesc.h:32
bool ccnoinherit
Definition tupdesc.h:34
bool ccvalid
Definition tupdesc.h:33
char * ccbin
Definition tupdesc.h:31
bool has_generated_virtual
Definition tupdesc.h:47
bool has_not_null
Definition tupdesc.h:45
AttrDefault * defval
Definition tupdesc.h:40
bool has_generated_stored
Definition tupdesc.h:46
struct AttrMissing * missing
Definition tupdesc.h:42
ConstrCheck * check
Definition tupdesc.h:41
uint16 num_defval
Definition tupdesc.h:43
uint16 num_check
Definition tupdesc.h:44
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
Definition tupdesc.h:195

References AttrDefault::adbin, AttrMissing::am_present, AttrMissing::am_value, CompactAttribute::attbyval, CompactAttribute::attlen, CompactAttribute::attnullability, ConstrCheck::ccbin, ConstrCheck::ccenforced, ConstrCheck::ccname, ConstrCheck::ccnoinherit, ConstrCheck::ccvalid, TupleConstr::check, TupleDescData::constr, CreateTemplateTupleDesc(), datumCopy(), TupleConstr::defval, fb(), FormData_pg_attribute, TupleConstr::has_generated_stored, TupleConstr::has_generated_virtual, TupleConstr::has_not_null, i, TupleConstr::missing, TupleDescData::natts, TupleConstr::num_check, TupleConstr::num_defval, palloc(), palloc0_object, populate_compact_attribute(), pstrdup(), TupleDescData::tdtypeid, TupleDescData::tdtypmod, TupleDescAttr(), TupleDescCompactAttr(), and TupleDescFinalize().

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

◆ CreateTupleDescTruncatedCopy()

TupleDesc CreateTupleDescTruncatedCopy ( TupleDesc  tupdesc,
int  natts 
)

Definition at line 289 of file tupdesc.c.

290{
291 TupleDesc desc;
292 int i;
293
295
296 desc = CreateTemplateTupleDesc(natts);
297
298 /* Flat-copy the attribute array (unless there are no attributes) */
299 if (desc->natts > 0)
300 memcpy(TupleDescAttr(desc, 0),
301 TupleDescAttr(tupdesc, 0),
302 desc->natts * sizeof(FormData_pg_attribute));
303
304 /*
305 * Since we're not copying constraints and defaults, clear fields
306 * associated with them.
307 */
308 for (i = 0; i < desc->natts; i++)
309 {
311
312 att->attnotnull = false;
313 att->atthasdef = false;
314 att->atthasmissing = false;
315 att->attidentity = '\0';
316 att->attgenerated = '\0';
317
319 }
320
321 /* We can copy the tuple type identification, too */
322 desc->tdtypeid = tupdesc->tdtypeid;
323 desc->tdtypmod = tupdesc->tdtypmod;
324
325 TupleDescFinalize(desc);
326
327 return desc;
328}

References Assert, CreateTemplateTupleDesc(), fb(), FormData_pg_attribute, i, TupleDescData::natts, populate_compact_attribute(), TupleDescData::tdtypeid, TupleDescData::tdtypmod, TupleDescAttr(), and TupleDescFinalize().

Referenced by gist_page_items(), index_truncate_tuple(), and initGISTstate().

◆ DecrTupleDescRefCount()

void DecrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 635 of file tupdesc.c.

636{
637 Assert(tupdesc->tdrefcount > 0);
638
640 if (--tupdesc->tdrefcount == 0)
641 FreeTupleDesc(tupdesc);
642}
ResourceOwner CurrentResourceOwner
Definition resowner.c:173
void FreeTupleDesc(TupleDesc tupdesc)
Definition tupdesc.c:560
static void ResourceOwnerForgetTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition tupdesc.c:55

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

Referenced by cache_record_field_properties(), and ExecEvalConvertRowtype().

◆ equalRowTypes()

bool equalRowTypes ( TupleDesc  tupdesc1,
TupleDesc  tupdesc2 
)

Definition at line 835 of file tupdesc.c.

836{
837 if (tupdesc1->natts != tupdesc2->natts)
838 return false;
839 if (tupdesc1->tdtypeid != tupdesc2->tdtypeid)
840 return false;
841
842 for (int i = 0; i < tupdesc1->natts; i++)
843 {
846
847 if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0)
848 return false;
849 if (attr1->atttypid != attr2->atttypid)
850 return false;
851 if (attr1->atttypmod != attr2->atttypmod)
852 return false;
853 if (attr1->attcollation != attr2->attcollation)
854 return false;
855
856 /* Record types derived from tables could have dropped fields. */
857 if (attr1->attisdropped != attr2->attisdropped)
858 return false;
859 }
860
861 return true;
862}
#define NameStr(name)
Definition c.h:837

References fb(), i, NameStr, and TupleDescAttr().

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

◆ equalTupleDescs()

bool equalTupleDescs ( TupleDesc  tupdesc1,
TupleDesc  tupdesc2 
)

Definition at line 648 of file tupdesc.c.

649{
650 int i,
651 n;
652
653 if (tupdesc1->natts != tupdesc2->natts)
654 return false;
655 if (tupdesc1->tdtypeid != tupdesc2->tdtypeid)
656 return false;
657
658 /* tdtypmod and tdrefcount are not checked */
659
660 for (i = 0; i < tupdesc1->natts; i++)
661 {
664
665 /*
666 * We do not need to check every single field here: we can disregard
667 * attrelid and attnum (which were used to place the row in the attrs
668 * array in the first place). It might look like we could dispense
669 * with checking attlen/attbyval/attalign, since these are derived
670 * from atttypid; but in the case of dropped columns we must check
671 * them (since atttypid will be zero for all dropped columns) and in
672 * general it seems safer to check them always.
673 *
674 * We intentionally ignore atthasmissing, since that's not very
675 * relevant in tupdescs, which lack the attmissingval field.
676 */
677 if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0)
678 return false;
679 if (attr1->atttypid != attr2->atttypid)
680 return false;
681 if (attr1->attlen != attr2->attlen)
682 return false;
683 if (attr1->attndims != attr2->attndims)
684 return false;
685 if (attr1->atttypmod != attr2->atttypmod)
686 return false;
687 if (attr1->attbyval != attr2->attbyval)
688 return false;
689 if (attr1->attalign != attr2->attalign)
690 return false;
691 if (attr1->attstorage != attr2->attstorage)
692 return false;
693 if (attr1->attcompression != attr2->attcompression)
694 return false;
695 if (attr1->attnotnull != attr2->attnotnull)
696 return false;
697
698 /*
699 * When the column has a not-null constraint, we also need to consider
700 * its validity aspect, which only manifests in CompactAttribute->
701 * attnullability, so verify that.
702 */
703 if (attr1->attnotnull)
704 {
707
708 Assert(cattr1->attnullability != ATTNULLABLE_UNKNOWN);
709 Assert((cattr1->attnullability == ATTNULLABLE_UNKNOWN) ==
710 (cattr2->attnullability == ATTNULLABLE_UNKNOWN));
711
712 if (cattr1->attnullability != cattr2->attnullability)
713 return false;
714 }
715 if (attr1->atthasdef != attr2->atthasdef)
716 return false;
717 if (attr1->attidentity != attr2->attidentity)
718 return false;
719 if (attr1->attgenerated != attr2->attgenerated)
720 return false;
721 if (attr1->attisdropped != attr2->attisdropped)
722 return false;
723 if (attr1->attislocal != attr2->attislocal)
724 return false;
725 if (attr1->attinhcount != attr2->attinhcount)
726 return false;
727 if (attr1->attcollation != attr2->attcollation)
728 return false;
729 /* variable-length fields are not even present... */
730 }
731
732 if (tupdesc1->constr != NULL)
733 {
734 TupleConstr *constr1 = tupdesc1->constr;
735 TupleConstr *constr2 = tupdesc2->constr;
736
737 if (constr2 == NULL)
738 return false;
739 if (constr1->has_not_null != constr2->has_not_null)
740 return false;
741 if (constr1->has_generated_stored != constr2->has_generated_stored)
742 return false;
743 if (constr1->has_generated_virtual != constr2->has_generated_virtual)
744 return false;
745 n = constr1->num_defval;
746 if (n != (int) constr2->num_defval)
747 return false;
748 /* We assume here that both AttrDefault arrays are in adnum order */
749 for (i = 0; i < n; i++)
750 {
751 AttrDefault *defval1 = constr1->defval + i;
752 AttrDefault *defval2 = constr2->defval + i;
753
754 if (defval1->adnum != defval2->adnum)
755 return false;
756 if (strcmp(defval1->adbin, defval2->adbin) != 0)
757 return false;
758 }
759 if (constr1->missing)
760 {
761 if (!constr2->missing)
762 return false;
763 for (i = 0; i < tupdesc1->natts; i++)
764 {
765 AttrMissing *missval1 = constr1->missing + i;
766 AttrMissing *missval2 = constr2->missing + i;
767
768 if (missval1->am_present != missval2->am_present)
769 return false;
770 if (missval1->am_present)
771 {
773
774 if (!datumIsEqual(missval1->am_value, missval2->am_value,
775 missatt1->attbyval, missatt1->attlen))
776 return false;
777 }
778 }
779 }
780 else if (constr2->missing)
781 return false;
782 n = constr1->num_check;
783 if (n != (int) constr2->num_check)
784 return false;
785
786 /*
787 * Similarly, we rely here on the ConstrCheck entries being sorted by
788 * name. If there are duplicate names, the outcome of the comparison
789 * is uncertain, but that should not happen.
790 */
791 for (i = 0; i < n; i++)
792 {
793 ConstrCheck *check1 = constr1->check + i;
794 ConstrCheck *check2 = constr2->check + i;
795
796 if (!(strcmp(check1->ccname, check2->ccname) == 0 &&
797 strcmp(check1->ccbin, check2->ccbin) == 0 &&
798 check1->ccenforced == check2->ccenforced &&
799 check1->ccvalid == check2->ccvalid &&
800 check1->ccnoinherit == check2->ccnoinherit))
801 return false;
802 }
803 }
804 else if (tupdesc2->constr != NULL)
805 return false;
806 return true;
807}
bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
Definition datum.c:223
#define ATTNULLABLE_UNKNOWN
Definition tupdesc.h:85

References Assert, ATTNULLABLE_UNKNOWN, datumIsEqual(), fb(), i, NameStr, TupleConstr::num_defval, TupleDescAttr(), and TupleDescCompactAttr().

Referenced by RelationFindDeletedTupleInfoByIndex(), RelationFindDeletedTupleInfoSeq(), RelationFindReplTupleSeq(), and RelationRebuildRelation().

◆ FreeTupleDesc()

void FreeTupleDesc ( TupleDesc  tupdesc)

Definition at line 560 of file tupdesc.c.

561{
562 int i;
563
564 /*
565 * Possibly this should assert tdrefcount == 0, to disallow explicit
566 * freeing of un-refcounted tupdescs?
567 */
568 Assert(tupdesc->tdrefcount <= 0);
569
570 if (tupdesc->constr)
571 {
572 if (tupdesc->constr->num_defval > 0)
573 {
574 AttrDefault *attrdef = tupdesc->constr->defval;
575
576 for (i = tupdesc->constr->num_defval - 1; i >= 0; i--)
577 pfree(attrdef[i].adbin);
578 pfree(attrdef);
579 }
580 if (tupdesc->constr->missing)
581 {
582 AttrMissing *attrmiss = tupdesc->constr->missing;
583
584 for (i = tupdesc->natts - 1; i >= 0; i--)
585 {
586 if (attrmiss[i].am_present
587 && !TupleDescAttr(tupdesc, i)->attbyval)
588 pfree(DatumGetPointer(attrmiss[i].am_value));
589 }
591 }
592 if (tupdesc->constr->num_check > 0)
593 {
594 ConstrCheck *check = tupdesc->constr->check;
595
596 for (i = tupdesc->constr->num_check - 1; i >= 0; i--)
597 {
598 pfree(check[i].ccname);
599 pfree(check[i].ccbin);
600 }
601 pfree(check);
602 }
603 pfree(tupdesc->constr);
604 }
605
606 pfree(tupdesc);
607}
void pfree(void *pointer)
Definition mcxt.c:1616
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332

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

Referenced by AddNewAttributeTuples(), AtEOXact_RelationCache(), cfunc_hashtable_delete(), DecrTupleDescRefCount(), do_autovacuum(), ER_mc_callback(), ExecMakeTableFunctionResult(), ExecPrepareTuplestoreResult(), get_record_type_from_query(), get_rel_sync_entry(), InvalidateCompositeTypeCacheEntry(), ordered_set_startup(), PLy_result_dealloc(), RelationDestroyRelation(), ResOwnerReleaseTupleDesc(), RevalidateCachedQuery(), spgendscan(), update_cached_tupdesc(), and walrcv_clear_result().

◆ hashRowType()

uint32 hashRowType ( TupleDesc  desc)

Definition at line 871 of file tupdesc.c.

872{
873 uint32 s;
874 int i;
875
876 s = hash_combine(0, hash_bytes_uint32(desc->natts));
878 for (i = 0; i < desc->natts; ++i)
880
881 return s;
882}
uint32_t uint32
Definition c.h:618
uint32 hash_bytes_uint32(uint32 k)
Definition hashfn.c:610
static uint32 hash_combine(uint32 a, uint32 b)
Definition hashfn.h:68

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

Referenced by cfunc_hash(), record_type_typmod_hash(), and shared_record_table_hash().

◆ IncrTupleDescRefCount()

void IncrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 617 of file tupdesc.c.

618{
619 Assert(tupdesc->tdrefcount >= 0);
620
622 tupdesc->tdrefcount++;
624}
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition resowner.c:449
static void ResourceOwnerRememberTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition tupdesc.c:49

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

Referenced by cache_record_field_properties(), and ExecEvalConvertRowtype().

◆ populate_compact_attribute()

void populate_compact_attribute ( TupleDesc  tupdesc,
int  attnum 
)

Definition at line 100 of file tupdesc.c.

101{
102 Form_pg_attribute src = TupleDescAttr(tupdesc, attnum);
104
105 /*
106 * Don't use TupleDescCompactAttr to prevent infinite recursion in assert
107 * builds.
108 */
109 dst = &tupdesc->compact_attrs[attnum];
110
112}
CompactAttribute compact_attrs[FLEXIBLE_ARRAY_MEMBER]
Definition tupdesc.h:161
static void populate_compact_attribute_internal(Form_pg_attribute src, CompactAttribute *dst)
Definition tupdesc.c:65

References attnum, TupleDescData::compact_attrs, fb(), populate_compact_attribute_internal(), and TupleDescAttr().

Referenced by BuildDescForRelation(), BuildHardcodedDescriptor(), ConstructTupleDescriptor(), create_toast_table(), CreateTupleDesc(), CreateTupleDescCopy(), CreateTupleDescCopyConstr(), CreateTupleDescTruncatedCopy(), formrdesc(), getSpGistTupleDesc(), load_relcache_init_file(), RelationBuildLocalRelation(), RelationBuildTupleDesc(), TupleDescCopy(), TupleDescCopyEntry(), TupleDescInitBuiltinEntry(), and TupleDescInitEntry().

◆ populate_compact_attribute_internal()

static void populate_compact_attribute_internal ( Form_pg_attribute  src,
CompactAttribute dst 
)
inlinestatic

Definition at line 65 of file tupdesc.c.

67{
68 memset(dst, 0, sizeof(CompactAttribute));
69
70 dst->attcacheoff = -1;
71 dst->attlen = src->attlen;
72
73 dst->attbyval = src->attbyval;
74 dst->attispackable = (src->attstorage != TYPSTORAGE_PLAIN);
75 dst->atthasmissing = src->atthasmissing;
76 dst->attisdropped = src->attisdropped;
77 dst->attgenerated = (src->attgenerated != '\0');
78
79 /*
80 * Assign nullability status for this column. Assuming that a constraint
81 * exists, at this point we don't know if a not-null constraint is valid,
82 * so we assign UNKNOWN unless the table is a catalog, in which case we
83 * know it's valid.
84 */
85 dst->attnullability = !src->attnotnull ? ATTNULLABLE_UNRESTRICTED :
88
89 /* Compute numeric alignment requirement, too */
90 dst->attalignby = typalign_to_alignby(src->attalign);
91}
bool IsCatalogRelationOid(Oid relid)
Definition catalog.c:121
#define ATTNULLABLE_VALID
Definition tupdesc.h:86
#define ATTNULLABLE_UNRESTRICTED
Definition tupdesc.h:84
static uint8 typalign_to_alignby(char typalign)
Definition tupmacs.h:302

References ATTNULLABLE_UNKNOWN, ATTNULLABLE_UNRESTRICTED, ATTNULLABLE_VALID, fb(), IsCatalogRelationOid(), and typalign_to_alignby().

Referenced by populate_compact_attribute(), and verify_compact_attribute().

◆ ResourceOwnerForgetTupleDesc()

static void ResourceOwnerForgetTupleDesc ( ResourceOwner  owner,
TupleDesc  tupdesc 
)
inlinestatic

Definition at line 55 of file tupdesc.c.

56{
58}
static Datum PointerGetDatum(const void *X)
Definition postgres.h:342
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition resowner.c:561
static const ResourceOwnerDesc tupdesc_resowner_desc
Definition tupdesc.c:38

References PointerGetDatum(), ResourceOwnerForget(), and tupdesc_resowner_desc.

Referenced by DecrTupleDescRefCount().

◆ ResourceOwnerRememberTupleDesc()

static void ResourceOwnerRememberTupleDesc ( ResourceOwner  owner,
TupleDesc  tupdesc 
)
inlinestatic

Definition at line 49 of file tupdesc.c.

50{
52}
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition resowner.c:521

References PointerGetDatum(), ResourceOwnerRemember(), and tupdesc_resowner_desc.

Referenced by IncrTupleDescRefCount().

◆ ResOwnerPrintTupleDesc()

static char * ResOwnerPrintTupleDesc ( Datum  res)
static

Definition at line 1187 of file tupdesc.c.

1188{
1189 TupleDesc tupdesc = (TupleDesc) DatumGetPointer(res);
1190
1191 return psprintf("TupleDesc %p (%u,%d)",
1192 tupdesc, tupdesc->tdtypeid, tupdesc->tdtypmod);
1193}
char * psprintf(const char *fmt,...)
Definition psprintf.c:43

References DatumGetPointer(), psprintf(), TupleDescData::tdtypeid, and TupleDescData::tdtypmod.

◆ ResOwnerReleaseTupleDesc()

static void ResOwnerReleaseTupleDesc ( Datum  res)
static

Definition at line 1176 of file tupdesc.c.

1177{
1178 TupleDesc tupdesc = (TupleDesc) DatumGetPointer(res);
1179
1180 /* Like DecrTupleDescRefCount, but don't call ResourceOwnerForget() */
1181 Assert(tupdesc->tdrefcount > 0);
1182 if (--tupdesc->tdrefcount == 0)
1183 FreeTupleDesc(tupdesc);
1184}

References Assert, DatumGetPointer(), FreeTupleDesc(), and TupleDescData::tdrefcount.

◆ TupleDescCopy()

void TupleDescCopy ( TupleDesc  dst,
TupleDesc  src 
)

Definition at line 427 of file tupdesc.c.

428{
429 int i;
430
431 /* Flat-copy the header and attribute arrays */
432 memcpy(dst, src, TupleDescSize(src));
433
434 /*
435 * Since we're not copying constraints and defaults, clear fields
436 * associated with them.
437 */
438 for (i = 0; i < dst->natts; i++)
439 {
441
442 att->attnotnull = false;
443 att->atthasdef = false;
444 att->atthasmissing = false;
445 att->attidentity = '\0';
446 att->attgenerated = '\0';
447
449 }
450 dst->constr = NULL;
451
452 /*
453 * Also, assume the destination is not to be ref-counted. (Copying the
454 * source's refcount would be wrong in any case.)
455 */
456 dst->tdrefcount = -1;
457
459}
#define TupleDescSize(src)
Definition tupdesc.h:218

References fb(), i, populate_compact_attribute(), TupleDescAttr(), TupleDescFinalize(), and TupleDescSize.

Referenced by share_tupledesc().

◆ TupleDescCopyEntry()

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

Definition at line 472 of file tupdesc.c.

474{
477
478 /*
479 * sanity checks
480 */
481 Assert(src);
482 Assert(dst);
483 Assert(srcAttno >= 1);
485 Assert(dstAttno >= 1);
487
489
490 dstAtt->attnum = dstAttno;
491
492 /* since we're not copying constraints or defaults, clear these */
493 dstAtt->attnotnull = false;
494 dstAtt->atthasdef = false;
495 dstAtt->atthasmissing = false;
496 dstAtt->attidentity = '\0';
497 dstAtt->attgenerated = '\0';
498
500}

References Assert, ATTRIBUTE_FIXED_PART_SIZE, fb(), populate_compact_attribute(), and TupleDescAttr().

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

◆ TupleDescFinalize()

void TupleDescFinalize ( TupleDesc  tupdesc)

Definition at line 511 of file tupdesc.c.

512{
513 int firstNonCachedOffsetAttr = 0;
514 int firstNonGuaranteedAttr = tupdesc->natts;
515 int off = 0;
516
517 for (int i = 0; i < tupdesc->natts; i++)
518 {
520
521 /*
522 * Find the highest attnum which is guaranteed to exist in all tuples
523 * in the table. We currently only pay attention to byval attributes
524 * to allow additional optimizations during tuple deformation.
525 */
526 if (firstNonGuaranteedAttr == tupdesc->natts &&
527 (cattr->attnullability != ATTNULLABLE_VALID || !cattr->attbyval ||
528 cattr->atthasmissing || cattr->attisdropped || cattr->attlen <= 0))
529 firstNonGuaranteedAttr = i;
530
531 if (cattr->attlen <= 0)
532 break;
533
534 off = att_nominal_alignby(off, cattr->attalignby);
535
536 /*
537 * attcacheoff is an int16, so don't try to cache any offsets larger
538 * than will fit in that type. Any attributes which are offset more
539 * than 2^15 are likely due to variable-length attributes. Since we
540 * don't cache offsets for or beyond variable-length attributes, using
541 * an int16 rather than an int32 here is unlikely to cost us anything.
542 */
543 if (off > PG_INT16_MAX)
544 break;
545
546 cattr->attcacheoff = (int16) off;
547
548 off += cattr->attlen;
549 firstNonCachedOffsetAttr = i + 1;
550 }
551
552 tupdesc->firstNonCachedOffsetAttr = firstNonCachedOffsetAttr;
553 tupdesc->firstNonGuaranteedAttr = firstNonGuaranteedAttr;
554}
int16_t int16
Definition c.h:613
#define PG_INT16_MAX
Definition c.h:672
#define att_nominal_alignby(cur_offset, attalignby)
Definition tupmacs.h:411

References att_nominal_alignby, ATTNULLABLE_VALID, fb(), TupleDescData::firstNonCachedOffsetAttr, TupleDescData::firstNonGuaranteedAttr, i, TupleDescData::natts, PG_INT16_MAX, and TupleDescCompactAttr().

Referenced by aclexplode(), addRangeTableEntryForFunction(), BeginCopyTo(), brtuple_disk_tupdesc(), build_function_result_tupdesc_d(), build_row_from_vars(), BuildDescForRelation(), BuildDescFromLists(), BuildHardcodedDescriptor(), CallStmtResultDesc(), ConstructTupleDescriptor(), create_toast_table(), CreateReplicationSlot(), CreateTupleDesc(), CreateTupleDescCopy(), CreateTupleDescCopyConstr(), CreateTupleDescTruncatedCopy(), dblink_get_pkey(), DefineRelation(), ExecInitFunctionScan(), ExecMakeTableFunctionResult(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), ExplainResultDesc(), formrdesc(), get_expr_result_type(), GetPGVariableResultDesc(), getSpGistTupleDesc(), gistrescan(), IdentifySystem(), init_sexpr(), initGinState(), libpqrcv_processTuples(), load_relcache_init_file(), materializeQueryResult(), materializeResult(), ordered_set_startup(), pg_buffercache_os_pages_internal(), pg_buffercache_pages(), pg_get_publication_tables(), pg_get_sequence_data(), pg_lock_status(), 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_wal_build_tuple(), pg_visibility_tupdesc(), pg_walfile_name_offset(), ReadReplicationSlot(), RelationBuildLocalRelation(), RelationBuildTupleDesc(), resolve_polymorphic_tupdesc(), SendTablespaceList(), SendTimeLineHistory(), SendXlogRecPtrResult(), show_all_settings(), ShowAllGUCConfig(), ShowGUCConfigOption(), StartReplication(), test_custom_stats_fixed_report(), test_predtest(), tsvector_unnest(), TupleDescCopy(), TypeGetTupleDesc(), and WaitStmtResultDesc().

◆ TupleDescGetDefault()

Node * TupleDescGetDefault ( TupleDesc  tupdesc,
AttrNumber  attnum 
)

Definition at line 1152 of file tupdesc.c.

1153{
1154 Node *result = NULL;
1155
1156 if (tupdesc->constr)
1157 {
1158 AttrDefault *attrdef = tupdesc->constr->defval;
1159
1160 for (int i = 0; i < tupdesc->constr->num_defval; i++)
1161 {
1162 if (attrdef[i].adnum == attnum)
1163 {
1164 result = stringToNode(attrdef[i].adbin);
1165 break;
1166 }
1167 }
1168 }
1169
1170 return result;
1171}
void * stringToNode(const char *str)
Definition read.c:90
Definition nodes.h:135

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

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

◆ TupleDescInitBuiltinEntry()

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

Definition at line 976 of file tupdesc.c.

982{
984
985 /* sanity checks */
986 Assert(desc);
989 Assert(attdim >= 0);
991
992 /* initialize the attribute fields */
993 att = TupleDescAttr(desc, attributeNumber - 1);
994 att->attrelid = 0; /* dummy value */
995
996 /* unlike TupleDescInitEntry, we require an attribute name */
998 namestrcpy(&(att->attname), attributeName);
999
1000 att->atttypmod = typmod;
1001
1002 att->attnum = attributeNumber;
1003 att->attndims = attdim;
1004
1005 att->attnotnull = false;
1006 att->atthasdef = false;
1007 att->atthasmissing = false;
1008 att->attidentity = '\0';
1009 att->attgenerated = '\0';
1010 att->attisdropped = false;
1011 att->attislocal = true;
1012 att->attinhcount = 0;
1013 /* variable-length fields are not present in tupledescs */
1014
1015 att->atttypid = oidtypeid;
1016
1017 /*
1018 * Our goal here is to support just enough types to let basic builtin
1019 * commands work without catalog access - e.g. so that we can do certain
1020 * things even in processes that are not connected to a database.
1021 */
1022 switch (oidtypeid)
1023 {
1024 case TEXTOID:
1025 case TEXTARRAYOID:
1026 att->attlen = -1;
1027 att->attbyval = false;
1028 att->attalign = TYPALIGN_INT;
1029 att->attstorage = TYPSTORAGE_EXTENDED;
1030 att->attcompression = InvalidCompressionMethod;
1031 att->attcollation = DEFAULT_COLLATION_OID;
1032 break;
1033
1034 case BOOLOID:
1035 att->attlen = 1;
1036 att->attbyval = true;
1037 att->attalign = TYPALIGN_CHAR;
1038 att->attstorage = TYPSTORAGE_PLAIN;
1039 att->attcompression = InvalidCompressionMethod;
1040 att->attcollation = InvalidOid;
1041 break;
1042
1043 case INT4OID:
1044 att->attlen = 4;
1045 att->attbyval = true;
1046 att->attalign = TYPALIGN_INT;
1047 att->attstorage = TYPSTORAGE_PLAIN;
1048 att->attcompression = InvalidCompressionMethod;
1049 att->attcollation = InvalidOid;
1050 break;
1051
1052 case INT8OID:
1053 att->attlen = 8;
1054 att->attbyval = true;
1055 att->attalign = TYPALIGN_DOUBLE;
1056 att->attstorage = TYPSTORAGE_PLAIN;
1057 att->attcompression = InvalidCompressionMethod;
1058 att->attcollation = InvalidOid;
1059 break;
1060
1061 case OIDOID:
1062 att->attlen = 4;
1063 att->attbyval = true;
1064 att->attalign = TYPALIGN_INT;
1065 att->attstorage = TYPSTORAGE_PLAIN;
1066 att->attcompression = InvalidCompressionMethod;
1067 att->attcollation = InvalidOid;
1068 break;
1069
1070 default:
1071 elog(ERROR, "unsupported type %u", oidtypeid);
1072 }
1073
1075}
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
void namestrcpy(Name name, const char *str)
Definition name.c:233
#define InvalidOid
#define InvalidCompressionMethod

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

906{
907 HeapTuple tuple;
910
911 /*
912 * sanity checks
913 */
914 Assert(desc);
917 Assert(attdim >= 0);
919
920 /*
921 * initialize the attribute fields
922 */
923 att = TupleDescAttr(desc, attributeNumber - 1);
924
925 att->attrelid = 0; /* dummy value */
926
927 /*
928 * Note: attributeName can be NULL, because the planner doesn't always
929 * fill in valid resname values in targetlists, particularly for resjunk
930 * attributes. Also, do nothing if caller wants to re-use the old attname.
931 */
932 if (attributeName == NULL)
933 MemSet(NameStr(att->attname), 0, NAMEDATALEN);
934 else if (attributeName != NameStr(att->attname))
935 namestrcpy(&(att->attname), attributeName);
936
937 att->atttypmod = typmod;
938
939 att->attnum = attributeNumber;
940 att->attndims = attdim;
941
942 att->attnotnull = false;
943 att->atthasdef = false;
944 att->atthasmissing = false;
945 att->attidentity = '\0';
946 att->attgenerated = '\0';
947 att->attisdropped = false;
948 att->attislocal = true;
949 att->attinhcount = 0;
950 /* variable-length fields are not present in tupledescs */
951
953 if (!HeapTupleIsValid(tuple))
954 elog(ERROR, "cache lookup failed for type %u", oidtypeid);
956
957 att->atttypid = oidtypeid;
958 att->attlen = typeForm->typlen;
959 att->attbyval = typeForm->typbyval;
960 att->attalign = typeForm->typalign;
961 att->attstorage = typeForm->typstorage;
962 att->attcompression = InvalidCompressionMethod;
963 att->attcollation = typeForm->typcollation;
964
966
967 ReleaseSysCache(tuple);
968}
#define MemSet(start, val, len)
Definition c.h:1109
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
#define NAMEDATALEN
END_CATALOG_STRUCT typedef FormData_pg_type * Form_pg_type
Definition pg_type.h:265
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221

References Assert, elog, ERROR, fb(), Form_pg_type, GETSTRUCT(), HeapTupleIsValid, InvalidCompressionMethod, MemSet, NAMEDATALEN, NameStr, namestrcpy(), ObjectIdGetDatum(), PG_INT16_MAX, populate_compact_attribute(), ReleaseSysCache(), SearchSysCache1(), and TupleDescAttr().

Referenced by aclexplode(), addRangeTableEntryForFunction(), BeginCopyTo(), brtuple_disk_tupdesc(), build_function_result_tupdesc_d(), build_row_from_vars(), BuildDescForRelation(), BuildDescFromLists(), CallStmtResultDesc(), create_toast_table(), dblink_get_pkey(), ExecInitFunctionScan(), ExecMakeTableFunctionResult(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), ExplainResultDesc(), get_expr_result_type(), GetPGVariableResultDesc(), gistrescan(), init_sexpr(), initGinState(), libpqrcv_processTuples(), materializeQueryResult(), materializeResult(), ordered_set_startup(), pg_buffercache_os_pages_internal(), pg_buffercache_pages(), pg_get_publication_tables(), pg_get_sequence_data(), pg_lock_status(), 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_wal_build_tuple(), pg_visibility_tupdesc(), pg_walfile_name_offset(), resolve_polymorphic_tupdesc(), show_all_settings(), test_custom_stats_fixed_report(), test_predtest(), tsvector_unnest(), TypeGetTupleDesc(), and WaitStmtResultDesc().

◆ TupleDescInitEntryCollation()

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

◆ verify_compact_attribute()

void verify_compact_attribute ( TupleDesc  tupdesc,
int  attnum 
)

Definition at line 125 of file tupdesc.c.

126{
127#ifdef USE_ASSERT_CHECKING
129 Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum);
131
132 /*
133 * Make a temp copy of the TupleDesc's CompactAttribute. This may be a
134 * shared TupleDesc and the attcacheoff might get changed by another
135 * backend.
136 */
137 memcpy(&cattr, &tupdesc->compact_attrs[attnum], sizeof(CompactAttribute));
138
139 /*
140 * Populate the temporary CompactAttribute from the corresponding
141 * Form_pg_attribute
142 */
144
145 /*
146 * Make the attcacheoff match since it's been reset to -1 by
147 * populate_compact_attribute_internal. Same with attnullability.
148 */
149 tmp.attcacheoff = cattr.attcacheoff;
150 tmp.attnullability = cattr.attnullability;
151
152 /* Check the freshly populated CompactAttribute matches the TupleDesc's */
153 Assert(memcmp(&tmp, &cattr, sizeof(CompactAttribute)) == 0);
154#endif
155}
int16 attcacheoff
Definition tupdesc.h:70

References Assert, CompactAttribute::attcacheoff, CompactAttribute::attnullability, attnum, TupleDescData::compact_attrs, fb(), populate_compact_attribute_internal(), and TupleDescAttr().

Referenced by TupleDescCompactAttr().

Variable Documentation

◆ tupdesc_resowner_desc

const ResourceOwnerDesc tupdesc_resowner_desc
static
Initial value:
=
{
.name = "tupdesc reference",
.release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
.release_priority = RELEASE_PRIO_TUPDESC_REFS,
.ReleaseResource = ResOwnerReleaseTupleDesc,
.DebugPrint = ResOwnerPrintTupleDesc
}
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition resowner.h:56
#define RELEASE_PRIO_TUPDESC_REFS
Definition resowner.h:74
static void ResOwnerReleaseTupleDesc(Datum res)
Definition tupdesc.c:1176
static char * ResOwnerPrintTupleDesc(Datum res)
Definition tupdesc.c:1187

Definition at line 38 of file tupdesc.c.

39{
40 .name = "tupdesc reference",
41 .release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
42 .release_priority = RELEASE_PRIO_TUPDESC_REFS,
43 .ReleaseResource = ResOwnerReleaseTupleDesc,
44 .DebugPrint = ResOwnerPrintTupleDesc
45};

Referenced by ResourceOwnerForgetTupleDesc(), and ResourceOwnerRememberTupleDesc().