PostgreSQL Source Code  git master
tupdesc.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/toast_compression.h"
#include "access/tupdesc_details.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "common/hashfn.h"
#include "miscadmin.h"
#include "parser/parse_type.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/resowner_private.h"
#include "utils/syscache.h"
Include dependency graph for tupdesc.c:

Go to the source code of this file.

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)
 

Function Documentation

◆ BuildDescForRelation()

TupleDesc BuildDescForRelation ( List schema)

Definition at line 777 of file tupdesc.c.

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().

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

◆ BuildDescFromLists()

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

Definition at line 877 of file tupdesc.c.

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

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

878 {
879  int natts;
881  ListCell *l1;
882  ListCell *l2;
883  ListCell *l3;
884  ListCell *l4;
885  TupleDesc desc;
886 
887  natts = list_length(names);
888  Assert(natts == list_length(types));
889  Assert(natts == list_length(typmods));
890  Assert(natts == list_length(collations));
891 
892  /*
893  * allocate a new tuple descriptor
894  */
895  desc = CreateTemplateTupleDesc(natts);
896 
897  attnum = 0;
898  forfour(l1, names, l2, types, l3, typmods, l4, collations)
899  {
900  char *attname = strVal(lfirst(l1));
901  Oid atttypid = lfirst_oid(l2);
902  int32 atttypmod = lfirst_int(l3);
903  Oid attcollation = lfirst_oid(l4);
904 
905  attnum++;
906 
907  TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
908  TupleDescInitEntryCollation(desc, attnum, attcollation);
909  }
910 
911  return desc;
912 }
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:45
#define strVal(v)
Definition: value.h:54
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:429
NameData attname
Definition: pg_attribute.h:41
#define lfirst_int(lc)
Definition: pg_list.h:170
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:754
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:583
int16 attnum
Definition: pg_attribute.h:83
#define Assert(condition)
Definition: c.h:804
#define lfirst(lc)
Definition: pg_list.h:169
static int list_length(const List *l)
Definition: pg_list.h:149
#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4)
Definition: pg_list.h:503
int16 AttrNumber
Definition: attnum.h:21
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ CreateTemplateTupleDesc()

TupleDesc CreateTemplateTupleDesc ( int  natts)

Definition at line 45 of file tupdesc.c.

References AssertArg, TupleDescData::constr, FormData_pg_attribute, TupleDescData::natts, offsetof, 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_notify(), 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_cursor(), pg_get_catalog_foreign_keys(), pg_get_keywords(), pg_get_multixact_members(), pg_get_object_address(), pg_identify_object(), pg_identify_object_as_address(), pg_last_committed_xact(), pg_lock_status(), pg_logdir_ls_internal(), pg_ls_dir(), pg_partition_tree(), pg_prepared_statement(), pg_prepared_xact(), pg_sequence_parameters(), pg_stat_file(), pg_stat_get_archiver(), pg_stat_get_replication_slot(), pg_stat_get_wal(), pg_tablespace_databases(), pg_timezone_abbrevs(), pg_visibility_map_summary(), pg_visibility_tupdesc(), pg_walfile_name_offset(), pg_xact_commit_timestamp_origin(), prs_setup_firstcall(), show_all_file_settings(), show_all_settings(), ShowAllGUCConfig(), ShowGUCConfigOption(), StartReplication(), test_predtest(), ts_setup_firstcall(), tsvector_unnest(), tt_setup_firstcall(), TypeGetTupleDesc(), and verify_heapam_tupdesc().

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 }
int32 tdtypmod
Definition: tupdesc.h:83
TupleConstr * constr
Definition: tupdesc.h:85
#define AssertArg(condition)
Definition: c.h:806
FormData_pg_attribute
Definition: pg_attribute.h:191
Oid tdtypeid
Definition: tupdesc.h:82
struct TupleDescData * TupleDesc
Definition: tupdesc.h:89
void * palloc(Size size)
Definition: mcxt.c:1062
int tdrefcount
Definition: tupdesc.h:84
#define offsetof(type, field)
Definition: c.h:727

◆ CreateTupleDesc()

TupleDesc CreateTupleDesc ( int  natts,
Form_pg_attribute attrs 
)

Definition at line 90 of file tupdesc.c.

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

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

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 }
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:45
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:199
int i

◆ CreateTupleDescCopy()

TupleDesc CreateTupleDescCopy ( TupleDesc  tupdesc)

Definition at line 111 of file tupdesc.c.

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(), deflist_to_tuplestore(), do_autovacuum(), each_worker(), each_worker_jsonb(), elements_worker(), elements_worker_jsonb(), ExecEvalWholeRowVar(), ExecInitForeignScan(), ExecInitFunctionScan(), ExecInsert(), ExecPrepareTuplestoreResult(), FetchPreparedStatementResultDesc(), fmgr_sql(), get_record_type_from_query(), get_tupdesc_for_join_scan_tuples(), getSpGistTupleDesc(), init_sexpr(), make_expanded_record_from_exprecord(), make_expanded_record_from_tupdesc(), materializeResult(), maybe_send_schema(), PersistHoldablePortal(), pg_config(), 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(), text_to_table(), update_cached_tupdesc(), UtilityTupleDescriptor(), and xpath_table().

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 }
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:45
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
int32 tdtypmod
Definition: tupdesc.h:83
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
FormData_pg_attribute
Definition: pg_attribute.h:191
Oid tdtypeid
Definition: tupdesc.h:82
int i

◆ CreateTupleDescCopyConstr()

TupleDesc CreateTupleDescCopyConstr ( TupleDesc  tupdesc)

Definition at line 151 of file tupdesc.c.

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().

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 }
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:45
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
char * pstrdup(const char *in)
Definition: mcxt.c:1299
AttrDefault * defval
Definition: tupdesc.h:39
bool has_generated_stored
Definition: tupdesc.h:45
int32 tdtypmod
Definition: tupdesc.h:83
TupleConstr * constr
Definition: tupdesc.h:85
char * ccname
Definition: tupdesc.h:30
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:131
void * palloc0(Size size)
Definition: mcxt.c:1093
uint16 num_check
Definition: tupdesc.h:43
FormData_pg_attribute
Definition: pg_attribute.h:191
struct AttrMissing * missing
Definition: tupdesc.h:41
uint16 num_defval
Definition: tupdesc.h:42
Oid tdtypeid
Definition: tupdesc.h:82
void * palloc(Size size)
Definition: mcxt.c:1062
int i
char * adbin
Definition: tupdesc.h:25
ConstrCheck * check
Definition: tupdesc.h:40
bool ccvalid
Definition: tupdesc.h:32
bool has_not_null
Definition: tupdesc.h:44
char * ccbin
Definition: tupdesc.h:31
bool ccnoinherit
Definition: tupdesc.h:33

◆ DecrTupleDescRefCount()

void DecrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 384 of file tupdesc.c.

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

Referenced by ATExecAddOf(), cache_record_field_properties(), ExecEvalConvertRowtype(), ExecInitExprRec(), expanded_record_fetch_tupdesc(), make_expanded_record_from_typeid(), ResourceOwnerReleaseInternal(), and transformOfType().

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:1214
#define Assert(condition)
Definition: c.h:804
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:309
int tdrefcount
Definition: tupdesc.h:84

◆ equalTupleDescs()

bool equalTupleDescs ( TupleDesc  tupdesc1,
TupleDesc  tupdesc2 
)

Definition at line 402 of file tupdesc.c.

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().

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 TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
Definition: datum.c:222
AttrDefault * defval
Definition: tupdesc.h:39
bool has_generated_stored
Definition: tupdesc.h:45
TupleConstr * constr
Definition: tupdesc.h:85
char * ccname
Definition: tupdesc.h:30
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
uint16 num_check
Definition: tupdesc.h:43
struct AttrMissing * missing
Definition: tupdesc.h:41
uint16 num_defval
Definition: tupdesc.h:42
Oid tdtypeid
Definition: tupdesc.h:82
int i
AttrNumber adnum
Definition: tupdesc.h:24
char * adbin
Definition: tupdesc.h:25
#define NameStr(name)
Definition: c.h:681
ConstrCheck * check
Definition: tupdesc.h:40
bool ccvalid
Definition: tupdesc.h:32
bool has_not_null
Definition: tupdesc.h:44
char * ccbin
Definition: tupdesc.h:31
bool ccnoinherit
Definition: tupdesc.h:33

◆ FreeTupleDesc()

void FreeTupleDesc ( TupleDesc  tupdesc)

Definition at line 309 of file tupdesc.c.

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(), maybe_send_schema(), ordered_set_startup(), PLy_result_dealloc(), rel_sync_cache_relation_cb(), RelationDestroyRelation(), RevalidateCachedQuery(), spgendscan(), TypeCacheRelCallback(), update_cached_tupdesc(), and walrcv_clear_result().

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 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
AttrDefault * defval
Definition: tupdesc.h:39
bool attbyval
Definition: pg_attribute.h:112
void pfree(void *pointer)
Definition: mcxt.c:1169
TupleConstr * constr
Definition: tupdesc.h:85
uint16 num_check
Definition: tupdesc.h:43
#define Assert(condition)
Definition: c.h:804
#define DatumGetPointer(X)
Definition: postgres.h:593
struct AttrMissing * missing
Definition: tupdesc.h:41
uint16 num_defval
Definition: tupdesc.h:42
int i
int tdrefcount
Definition: tupdesc.h:84
ConstrCheck * check
Definition: tupdesc.h:40

◆ hashTupleDesc()

uint32 hashTupleDesc ( TupleDesc  desc)

Definition at line 554 of file tupdesc.c.

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

Referenced by record_type_typmod_hash(), and shared_record_table_hash().

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 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
unsigned int uint32
Definition: c.h:441
static uint32 hash_combine(uint32 a, uint32 b)
Definition: hashfn.h:68
static Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
Oid tdtypeid
Definition: tupdesc.h:82
int i

◆ IncrTupleDescRefCount()

void IncrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 366 of file tupdesc.c.

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

Referenced by cache_record_field_properties(), and ExecEvalConvertRowtype().

367 {
368  Assert(tupdesc->tdrefcount >= 0);
369 
371  tupdesc->tdrefcount++;
373 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:146
void ResourceOwnerRememberTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition: resowner.c:1205
void ResourceOwnerEnlargeTupleDescs(ResourceOwner owner)
Definition: resowner.c:1194
#define Assert(condition)
Definition: c.h:804
int tdrefcount
Definition: tupdesc.h:84

◆ TupleDescCopy()

void TupleDescCopy ( TupleDesc  dst,
TupleDesc  src 
)

Definition at line 229 of file tupdesc.c.

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

Referenced by index_truncate_tuple(), and share_tupledesc().

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 TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define TupleDescSize(src)
Definition: tupdesc.h:102
TupleConstr * constr
Definition: tupdesc.h:85
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
int i
int tdrefcount
Definition: tupdesc.h:84

◆ TupleDescCopyEntry()

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

Definition at line 267 of file tupdesc.c.

References AssertArg, ATTRIBUTE_FIXED_PART_SIZE, PointerIsValid, and TupleDescAttr.

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

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 TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:199
#define AssertArg(condition)
Definition: c.h:806
#define PointerIsValid(pointer)
Definition: c.h:698

◆ TupleDescInitBuiltinEntry()

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

Definition at line 657 of file tupdesc.c.

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

Referenced by CreateReplicationSlot(), IdentifySystem(), ShowAllGUCConfig(), ShowGUCConfigOption(), and StartReplication().

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  /* attacl, attoptions and attfdwoptions 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  default:
743  elog(ERROR, "unsupported type %u", oidtypeid);
744  }
745 }
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define ERROR
Definition: elog.h:46
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
#define AssertArg(condition)
Definition: c.h:806
#define InvalidOid
Definition: postgres_ext.h:36
#define FLOAT8PASSBYVAL
Definition: c.h:570
#define Assert(condition)
Definition: c.h:804
#define InvalidCompressionMethod
#define elog(elevel,...)
Definition: elog.h:232
#define PointerIsValid(pointer)
Definition: c.h:698

◆ TupleDescInitEntry()

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

Definition at line 583 of file tupdesc.c.

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_notify(), 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_cursor(), pg_get_catalog_foreign_keys(), pg_get_keywords(), pg_get_multixact_members(), pg_get_object_address(), pg_identify_object(), pg_identify_object_as_address(), pg_last_committed_xact(), pg_lock_status(), pg_logdir_ls_internal(), pg_ls_dir(), pg_partition_tree(), pg_prepared_statement(), pg_prepared_xact(), pg_sequence_parameters(), pg_stat_file(), pg_stat_get_archiver(), pg_stat_get_replication_slot(), pg_stat_get_wal(), pg_tablespace_databases(), 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_file_settings(), show_all_settings(), test_predtest(), ts_setup_firstcall(), tsvector_unnest(), tt_setup_firstcall(), TypeGetTupleDesc(), and verify_heapam_tupdesc().

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  /* attacl, attoptions and attfdwoptions 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 GETSTRUCT(TUP)
Definition: htup_details.h:654
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define MemSet(start, val, len)
Definition: c.h:1008
#define NAMEDATALEN
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
#define AssertArg(condition)
Definition: c.h:806
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1127
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1175
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_type * Form_pg_type
Definition: pg_type.h:261
#define InvalidCompressionMethod
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681
#define PointerIsValid(pointer)
Definition: c.h:698

◆ TupleDescInitEntryCollation()

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

Definition at line 754 of file tupdesc.c.

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().

757 {
758  /*
759  * sanity checks
760  */
761  AssertArg(PointerIsValid(desc));
762  AssertArg(attributeNumber >= 1);
763  AssertArg(attributeNumber <= desc->natts);
764 
765  TupleDescAttr(desc, attributeNumber - 1)->attcollation = collationid;
766 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define AssertArg(condition)
Definition: c.h:806
#define PointerIsValid(pointer)
Definition: c.h:698