PostgreSQL Source Code  git master
tupdesc.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/tupdesc_details.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "parser/parse_type.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/hashutils.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 794 of file tupdesc.c.

References ACL_USAGE, aclcheck_error_type(), ACLCHECK_OK, TypeName::arrayBounds, attcollation, attname, attnum, atttypid, 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().

795 {
796  int natts;
798  ListCell *l;
799  TupleDesc desc;
800  bool has_not_null;
801  char *attname;
802  Oid atttypid;
803  int32 atttypmod;
805  int attdim;
806 
807  /*
808  * allocate a new tuple descriptor
809  */
810  natts = list_length(schema);
811  desc = CreateTemplateTupleDesc(natts);
812  has_not_null = false;
813 
814  attnum = 0;
815 
816  foreach(l, schema)
817  {
818  ColumnDef *entry = lfirst(l);
819  AclResult aclresult;
820  Form_pg_attribute att;
821 
822  /*
823  * for each entry in the list, get the name and type information from
824  * the list and have TupleDescInitEntry fill in the attribute
825  * information we need.
826  */
827  attnum++;
828 
829  attname = entry->colname;
830  typenameTypeIdAndMod(NULL, entry->typeName, &atttypid, &atttypmod);
831 
832  aclresult = pg_type_aclcheck(atttypid, GetUserId(), ACL_USAGE);
833  if (aclresult != ACLCHECK_OK)
834  aclcheck_error_type(aclresult, atttypid);
835 
836  attcollation = GetColumnDefCollation(NULL, entry, atttypid);
837  attdim = list_length(entry->typeName->arrayBounds);
838 
839  if (entry->typeName->setof)
840  ereport(ERROR,
841  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
842  errmsg("column \"%s\" cannot be declared SETOF",
843  attname)));
844 
845  TupleDescInitEntry(desc, attnum, attname,
846  atttypid, atttypmod, attdim);
847  att = TupleDescAttr(desc, attnum - 1);
848 
849  /* Override TupleDescInitEntry's settings as requested */
850  TupleDescInitEntryCollation(desc, attnum, attcollation);
851  if (entry->storage)
852  att->attstorage = entry->storage;
853 
854  /* Fill in additional stuff not handled by TupleDescInitEntry */
855  att->attnotnull = entry->is_not_null;
856  has_not_null |= entry->is_not_null;
857  att->attislocal = entry->is_local;
858  att->attinhcount = entry->inhcount;
859  }
860 
861  if (has_not_null)
862  {
863  TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
864 
865  constr->has_not_null = true;
866  constr->has_generated_stored = false;
867  constr->defval = NULL;
868  constr->missing = NULL;
869  constr->num_defval = 0;
870  constr->check = NULL;
871  constr->num_check = 0;
872  desc->constr = constr;
873  }
874  else
875  {
876  desc->constr = NULL;
877  }
878 
879  return desc;
880 }
char storage
Definition: parsenodes.h:652
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
bool is_local
Definition: parsenodes.h:649
Oid GetUserId(void)
Definition: miscinit.c:380
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
int errcode(int sqlerrcode)
Definition: elog.c:608
bool is_not_null
Definition: parsenodes.h:650
unsigned int Oid
Definition: postgres_ext.h:31
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition: aclchk.c:3665
signed int int32
Definition: c.h:347
AttrDefault * defval
Definition: tupdesc.h:39
bool has_generated_stored
Definition: tupdesc.h:45
#define ERROR
Definition: elog.h:43
NameData attname
Definition: pg_attribute.h:40
bool setof
Definition: parsenodes.h:211
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:769
Oid attcollation
Definition: pg_attribute.h:164
TupleConstr * constr
Definition: tupdesc.h:85
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
#define ACL_USAGE
Definition: parsenodes.h:82
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
Oid atttypid
Definition: pg_attribute.h:49
#define ereport(elevel, rest)
Definition: elog.h:141
Oid GetColumnDefCollation(ParseState *pstate, ColumnDef *coldef, Oid typeOid)
Definition: parse_type.c:538
void * palloc0(Size size)
Definition: mcxt.c:980
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:79
#define lfirst(lc)
Definition: pg_list.h:190
static int list_length(const List *l)
Definition: pg_list.h:169
TypeName * typeName
Definition: parsenodes.h:647
struct AttrMissing * missing
Definition: tupdesc.h:41
uint16 num_defval
Definition: tupdesc.h:42
List * arrayBounds
Definition: parsenodes.h:215
int errmsg(const char *fmt,...)
Definition: elog.c:822
int inhcount
Definition: parsenodes.h:648
char * colname
Definition: parsenodes.h:646
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:4741
int16 AttrNumber
Definition: attnum.h:21

◆ BuildDescFromLists()

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

Definition at line 894 of file tupdesc.c.

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

Referenced by ExecInitFunctionScan(), and ExecInitTableFuncScan().

895 {
896  int natts;
898  ListCell *l1;
899  ListCell *l2;
900  ListCell *l3;
901  ListCell *l4;
902  TupleDesc desc;
903 
904  natts = list_length(names);
905  Assert(natts == list_length(types));
906  Assert(natts == list_length(typmods));
907  Assert(natts == list_length(collations));
908 
909  /*
910  * allocate a new tuple descriptor
911  */
912  desc = CreateTemplateTupleDesc(natts);
913 
914  attnum = 0;
915  forfour(l1, names, l2, types, l3, typmods, l4, collations)
916  {
917  char *attname = strVal(lfirst(l1));
918  Oid atttypid = lfirst_oid(l2);
919  int32 atttypmod = lfirst_int(l3);
921 
922  attnum++;
923 
924  TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
925  TupleDescInitEntryCollation(desc, attnum, attcollation);
926  }
927 
928  return desc;
929 }
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
#define strVal(v)
Definition: value.h:54
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:347
NameData attname
Definition: pg_attribute.h:40
#define lfirst_int(lc)
Definition: pg_list.h:191
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:769
Oid attcollation
Definition: pg_attribute.h:164
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
Oid atttypid
Definition: pg_attribute.h:49
int16 attnum
Definition: pg_attribute.h:79
#define Assert(condition)
Definition: c.h:739
#define lfirst(lc)
Definition: pg_list.h:190
static int list_length(const List *l)
Definition: pg_list.h:169
#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4)
Definition: pg_list.h:476
int16 AttrNumber
Definition: attnum.h:21
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ CreateTemplateTupleDesc()

TupleDesc CreateTemplateTupleDesc ( int  natts)

Definition at line 44 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(), materializeResult(), ordered_set_startup(), pg_buffercache_pages(), pg_control_checkpoint(), pg_control_init(), pg_control_recovery(), pg_control_system(), pg_cursor(), 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_files(), pg_partition_tree(), pg_prepared_statement(), pg_prepared_xact(), pg_sequence_parameters(), pg_stat_file(), pg_stat_get_archiver(), pg_timezone_abbrevs(), pg_timezone_names(), pg_visibility_map_summary(), pg_visibility_tupdesc(), pg_walfile_name_offset(), prs_setup_firstcall(), show_all_file_settings(), show_all_settings(), ShowAllGUCConfig(), ShowGUCConfigOption(), StartReplication(), test_predtest(), ts_setup_firstcall(), tsvector_unnest(), tt_setup_firstcall(), and TypeGetTupleDesc().

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

◆ CreateTupleDesc()

TupleDesc CreateTupleDesc ( int  natts,
Form_pg_attribute attrs 
)

Definition at line 89 of file tupdesc.c.

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

Referenced by InsertOneTuple().

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

◆ CreateTupleDescCopy()

TupleDesc CreateTupleDescCopy ( TupleDesc  tupdesc)

Definition at line 110 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(), check_sql_fn_retval(), 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(), ExecPrepareTuplestoreResult(), FetchPreparedStatementResultDesc(), fmgr_sql(), get_record_type_from_query(), init_sexpr(), make_expanded_record_from_exprecord(), make_expanded_record_from_tupdesc(), materializeResult(), 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(), update_cached_tupdesc(), UtilityTupleDescriptor(), and xpath_table().

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

◆ CreateTupleDescCopyConstr()

TupleDesc CreateTupleDescCopyConstr ( TupleDesc  tupdesc)

Definition at line 150 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().

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

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

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

394 {
395  Assert(tupdesc->tdrefcount > 0);
396 
398  if (--tupdesc->tdrefcount == 0)
399  FreeTupleDesc(tupdesc);
400 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ResourceOwnerForgetTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition: resowner.c:1161
#define Assert(condition)
Definition: c.h:739
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:313
int tdrefcount
Definition: tupdesc.h:84

◆ equalTupleDescs()

bool equalTupleDescs ( TupleDesc  tupdesc1,
TupleDesc  tupdesc2 
)

Definition at line 411 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().

412 {
413  int i,
414  j,
415  n;
416 
417  if (tupdesc1->natts != tupdesc2->natts)
418  return false;
419  if (tupdesc1->tdtypeid != tupdesc2->tdtypeid)
420  return false;
421 
422  for (i = 0; i < tupdesc1->natts; i++)
423  {
424  Form_pg_attribute attr1 = TupleDescAttr(tupdesc1, i);
425  Form_pg_attribute attr2 = TupleDescAttr(tupdesc2, i);
426 
427  /*
428  * We do not need to check every single field here: we can disregard
429  * attrelid and attnum (which were used to place the row in the attrs
430  * array in the first place). It might look like we could dispense
431  * with checking attlen/attbyval/attalign, since these are derived
432  * from atttypid; but in the case of dropped columns we must check
433  * them (since atttypid will be zero for all dropped columns) and in
434  * general it seems safer to check them always.
435  *
436  * attcacheoff must NOT be checked since it's possibly not set in both
437  * copies.
438  */
439  if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0)
440  return false;
441  if (attr1->atttypid != attr2->atttypid)
442  return false;
443  if (attr1->attstattarget != attr2->attstattarget)
444  return false;
445  if (attr1->attlen != attr2->attlen)
446  return false;
447  if (attr1->attndims != attr2->attndims)
448  return false;
449  if (attr1->atttypmod != attr2->atttypmod)
450  return false;
451  if (attr1->attbyval != attr2->attbyval)
452  return false;
453  if (attr1->attstorage != attr2->attstorage)
454  return false;
455  if (attr1->attalign != attr2->attalign)
456  return false;
457  if (attr1->attnotnull != attr2->attnotnull)
458  return false;
459  if (attr1->atthasdef != attr2->atthasdef)
460  return false;
461  if (attr1->attidentity != attr2->attidentity)
462  return false;
463  if (attr1->attgenerated != attr2->attgenerated)
464  return false;
465  if (attr1->attisdropped != attr2->attisdropped)
466  return false;
467  if (attr1->attislocal != attr2->attislocal)
468  return false;
469  if (attr1->attinhcount != attr2->attinhcount)
470  return false;
471  if (attr1->attcollation != attr2->attcollation)
472  return false;
473  /* attacl, attoptions and attfdwoptions are not even present... */
474  }
475 
476  if (tupdesc1->constr != NULL)
477  {
478  TupleConstr *constr1 = tupdesc1->constr;
479  TupleConstr *constr2 = tupdesc2->constr;
480 
481  if (constr2 == NULL)
482  return false;
483  if (constr1->has_not_null != constr2->has_not_null)
484  return false;
485  if (constr1->has_generated_stored != constr2->has_generated_stored)
486  return false;
487  n = constr1->num_defval;
488  if (n != (int) constr2->num_defval)
489  return false;
490  for (i = 0; i < n; i++)
491  {
492  AttrDefault *defval1 = constr1->defval + i;
493  AttrDefault *defval2 = constr2->defval;
494 
495  /*
496  * We can't assume that the items are always read from the system
497  * catalogs in the same order; so use the adnum field to identify
498  * the matching item to compare.
499  */
500  for (j = 0; j < n; defval2++, j++)
501  {
502  if (defval1->adnum == defval2->adnum)
503  break;
504  }
505  if (j >= n)
506  return false;
507  if (strcmp(defval1->adbin, defval2->adbin) != 0)
508  return false;
509  }
510  if (constr1->missing)
511  {
512  if (!constr2->missing)
513  return false;
514  for (i = 0; i < tupdesc1->natts; i++)
515  {
516  AttrMissing *missval1 = constr1->missing + i;
517  AttrMissing *missval2 = constr2->missing + i;
518 
519  if (missval1->am_present != missval2->am_present)
520  return false;
521  if (missval1->am_present)
522  {
523  Form_pg_attribute missatt1 = TupleDescAttr(tupdesc1, i);
524 
525  if (!datumIsEqual(missval1->am_value, missval2->am_value,
526  missatt1->attbyval, missatt1->attlen))
527  return false;
528  }
529  }
530  }
531  else if (constr2->missing)
532  return false;
533  n = constr1->num_check;
534  if (n != (int) constr2->num_check)
535  return false;
536  for (i = 0; i < n; i++)
537  {
538  ConstrCheck *check1 = constr1->check + i;
539  ConstrCheck *check2 = constr2->check;
540 
541  /*
542  * Similarly, don't assume that the checks are always read in the
543  * same order; match them up by name and contents. (The name
544  * *should* be unique, but...)
545  */
546  for (j = 0; j < n; check2++, j++)
547  {
548  if (strcmp(check1->ccname, check2->ccname) == 0 &&
549  strcmp(check1->ccbin, check2->ccbin) == 0 &&
550  check1->ccvalid == check2->ccvalid &&
551  check1->ccnoinherit == check2->ccnoinherit)
552  break;
553  }
554  if (j >= n)
555  return false;
556  }
557  }
558  else if (tupdesc2->constr != NULL)
559  return false;
560  return true;
561 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
Definition: datum.c:221
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:200
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:616
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 313 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 AtEOXact_RelationCache(), DecrTupleDescRefCount(), ER_mc_callback(), ExecMakeTableFunctionResult(), ExecPrepareTuplestoreResult(), get_record_type_from_query(), ordered_set_startup(), PLy_result_dealloc(), RelationDestroyRelation(), RevalidateCachedQuery(), TypeCacheRelCallback(), update_cached_tupdesc(), and walrcv_clear_result().

314 {
315  int i;
316 
317  /*
318  * Possibly this should assert tdrefcount == 0, to disallow explicit
319  * freeing of un-refcounted tupdescs?
320  */
321  Assert(tupdesc->tdrefcount <= 0);
322 
323  if (tupdesc->constr)
324  {
325  if (tupdesc->constr->num_defval > 0)
326  {
327  AttrDefault *attrdef = tupdesc->constr->defval;
328 
329  for (i = tupdesc->constr->num_defval - 1; i >= 0; i--)
330  {
331  if (attrdef[i].adbin)
332  pfree(attrdef[i].adbin);
333  }
334  pfree(attrdef);
335  }
336  if (tupdesc->constr->missing)
337  {
338  AttrMissing *attrmiss = tupdesc->constr->missing;
339 
340  for (i = tupdesc->natts - 1; i >= 0; i--)
341  {
342  if (attrmiss[i].am_present
343  && !TupleDescAttr(tupdesc, i)->attbyval)
344  pfree(DatumGetPointer(attrmiss[i].am_value));
345  }
346  pfree(attrmiss);
347  }
348  if (tupdesc->constr->num_check > 0)
349  {
350  ConstrCheck *check = tupdesc->constr->check;
351 
352  for (i = tupdesc->constr->num_check - 1; i >= 0; i--)
353  {
354  if (check[i].ccname)
355  pfree(check[i].ccname);
356  if (check[i].ccbin)
357  pfree(check[i].ccbin);
358  }
359  pfree(check);
360  }
361  pfree(tupdesc->constr);
362  }
363 
364  pfree(tupdesc);
365 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
AttrDefault * defval
Definition: tupdesc.h:39
bool attbyval
Definition: pg_attribute.h:108
void pfree(void *pointer)
Definition: mcxt.c:1056
TupleConstr * constr
Definition: tupdesc.h:85
uint16 num_check
Definition: tupdesc.h:43
#define Assert(condition)
Definition: c.h:739
#define DatumGetPointer(X)
Definition: postgres.h:549
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 574 of file tupdesc.c.

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

Referenced by record_type_typmod_hash(), and shared_record_table_hash().

575 {
576  uint32 s;
577  int i;
578 
579  s = hash_combine(0, hash_uint32(desc->natts));
580  s = hash_combine(s, hash_uint32(desc->tdtypeid));
581  for (i = 0; i < desc->natts; ++i)
582  s = hash_combine(s, hash_uint32(TupleDescAttr(desc, i)->atttypid));
583 
584  return s;
585 }
static uint32 hash_combine(uint32 a, uint32 b)
Definition: hashutils.h:36
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
Datum hash_uint32(uint32 k)
Definition: hashfn.c:613
unsigned int uint32
Definition: c.h:359
Oid atttypid
Definition: pg_attribute.h:49
Oid tdtypeid
Definition: tupdesc.h:82
int i

◆ IncrTupleDescRefCount()

void IncrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 375 of file tupdesc.c.

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

Referenced by cache_record_field_properties().

376 {
377  Assert(tupdesc->tdrefcount >= 0);
378 
380  tupdesc->tdrefcount++;
382 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:142
void ResourceOwnerRememberTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition: resowner.c:1152
void ResourceOwnerEnlargeTupleDescs(ResourceOwner owner)
Definition: resowner.c:1141
#define Assert(condition)
Definition: c.h:739
int tdrefcount
Definition: tupdesc.h:84

◆ TupleDescCopy()

void TupleDescCopy ( TupleDesc  dst,
TupleDesc  src 
)

Definition at line 233 of file tupdesc.c.

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

Referenced by index_truncate_tuple(), and share_tupledesc().

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

◆ TupleDescCopyEntry()

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

Definition at line 271 of file tupdesc.c.

References AssertArg, ATTRIBUTE_FIXED_PART_SIZE, PointerIsValid, and TupleDescAttr.

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

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

◆ TupleDescInitBuiltinEntry()

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

Definition at line 676 of file tupdesc.c.

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

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

682 {
683  Form_pg_attribute att;
684 
685  /* sanity checks */
686  AssertArg(PointerIsValid(desc));
687  AssertArg(attributeNumber >= 1);
688  AssertArg(attributeNumber <= desc->natts);
689 
690  /* initialize the attribute fields */
691  att = TupleDescAttr(desc, attributeNumber - 1);
692  att->attrelid = 0; /* dummy value */
693 
694  /* unlike TupleDescInitEntry, we require an attribute name */
695  Assert(attributeName != NULL);
696  namestrcpy(&(att->attname), attributeName);
697 
698  att->attstattarget = -1;
699  att->attcacheoff = -1;
700  att->atttypmod = typmod;
701 
702  att->attnum = attributeNumber;
703  att->attndims = attdim;
704 
705  att->attnotnull = false;
706  att->atthasdef = false;
707  att->atthasmissing = false;
708  att->attidentity = '\0';
709  att->attgenerated = '\0';
710  att->attisdropped = false;
711  att->attislocal = true;
712  att->attinhcount = 0;
713  /* attacl, attoptions and attfdwoptions are not present in tupledescs */
714 
715  att->atttypid = oidtypeid;
716 
717  /*
718  * Our goal here is to support just enough types to let basic builtin
719  * commands work without catalog access - e.g. so that we can do certain
720  * things even in processes that are not connected to a database.
721  */
722  switch (oidtypeid)
723  {
724  case TEXTOID:
725  case TEXTARRAYOID:
726  att->attlen = -1;
727  att->attbyval = false;
728  att->attalign = 'i';
729  att->attstorage = 'x';
730  att->attcollation = DEFAULT_COLLATION_OID;
731  break;
732 
733  case BOOLOID:
734  att->attlen = 1;
735  att->attbyval = true;
736  att->attalign = 'c';
737  att->attstorage = 'p';
738  att->attcollation = InvalidOid;
739  break;
740 
741  case INT4OID:
742  att->attlen = 4;
743  att->attbyval = true;
744  att->attalign = 'i';
745  att->attstorage = 'p';
746  att->attcollation = InvalidOid;
747  break;
748 
749  case INT8OID:
750  att->attlen = 8;
751  att->attbyval = FLOAT8PASSBYVAL;
752  att->attalign = 'd';
753  att->attstorage = 'p';
754  att->attcollation = InvalidOid;
755  break;
756 
757  default:
758  elog(ERROR, "unsupported type %u", oidtypeid);
759  }
760 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
int namestrcpy(Name name, const char *str)
Definition: name.c:250
#define ERROR
Definition: elog.h:43
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
#define AssertArg(condition)
Definition: c.h:741
#define InvalidOid
Definition: postgres_ext.h:36
#define FLOAT8PASSBYVAL
Definition: c.h:497
#define Assert(condition)
Definition: c.h:739
#define elog(elevel,...)
Definition: elog.h:228
#define PointerIsValid(pointer)
Definition: c.h:633

◆ TupleDescInitEntry()

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

Definition at line 603 of file tupdesc.c.

References AssertArg, elog, ERROR, GETSTRUCT, HeapTupleIsValid, 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(), materializeResult(), ordered_set_startup(), pg_buffercache_pages(), pg_control_checkpoint(), pg_control_init(), pg_control_recovery(), pg_control_system(), pg_cursor(), 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_files(), pg_partition_tree(), pg_prepared_statement(), pg_prepared_xact(), pg_sequence_parameters(), pg_stat_file(), pg_stat_get_archiver(), pg_timezone_abbrevs(), pg_timezone_names(), pg_visibility_map_summary(), pg_visibility_tupdesc(), pg_walfile_name_offset(), prs_setup_firstcall(), resolve_polymorphic_tupdesc(), show_all_file_settings(), show_all_settings(), test_predtest(), ts_setup_firstcall(), tsvector_unnest(), tt_setup_firstcall(), and TypeGetTupleDesc().

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

◆ TupleDescInitEntryCollation()

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

Definition at line 769 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().

772 {
773  /*
774  * sanity checks
775  */
776  AssertArg(PointerIsValid(desc));
777  AssertArg(attributeNumber >= 1);
778  AssertArg(attributeNumber <= desc->natts);
779 
780  TupleDescAttr(desc, attributeNumber - 1)->attcollation = collationid;
781 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define AssertArg(condition)
Definition: c.h:741
#define PointerIsValid(pointer)
Definition: c.h:633