PostgreSQL Source Code  git master
tupdesc.c File Reference
#include "postgres.h"
#include "access/hash.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, bool hasoid)
 
TupleDesc CreateTupleDesc (int natts, bool hasoid, 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 786 of file tupdesc.c.

References ACL_USAGE, aclcheck_error_type(), ACLCHECK_OK, TypeName::arrayBounds, attcollation, attname, attnum, atttypid, tupleConstr::check, ColumnDef::colname, tupleDesc::constr, CreateTemplateTupleDesc(), tupleConstr::defval, ereport, errcode(), errmsg(), ERROR, GetColumnDefCollation(), GetUserId(), 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().

787 {
788  int natts;
790  ListCell *l;
791  TupleDesc desc;
792  bool has_not_null;
793  char *attname;
794  Oid atttypid;
795  int32 atttypmod;
797  int attdim;
798 
799  /*
800  * allocate a new tuple descriptor
801  */
802  natts = list_length(schema);
803  desc = CreateTemplateTupleDesc(natts, false);
804  has_not_null = false;
805 
806  attnum = 0;
807 
808  foreach(l, schema)
809  {
810  ColumnDef *entry = lfirst(l);
811  AclResult aclresult;
812  Form_pg_attribute att;
813 
814  /*
815  * for each entry in the list, get the name and type information from
816  * the list and have TupleDescInitEntry fill in the attribute
817  * information we need.
818  */
819  attnum++;
820 
821  attname = entry->colname;
822  typenameTypeIdAndMod(NULL, entry->typeName, &atttypid, &atttypmod);
823 
824  aclresult = pg_type_aclcheck(atttypid, GetUserId(), ACL_USAGE);
825  if (aclresult != ACLCHECK_OK)
826  aclcheck_error_type(aclresult, atttypid);
827 
828  attcollation = GetColumnDefCollation(NULL, entry, atttypid);
829  attdim = list_length(entry->typeName->arrayBounds);
830 
831  if (entry->typeName->setof)
832  ereport(ERROR,
833  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
834  errmsg("column \"%s\" cannot be declared SETOF",
835  attname)));
836 
837  TupleDescInitEntry(desc, attnum, attname,
838  atttypid, atttypmod, attdim);
839  att = TupleDescAttr(desc, attnum - 1);
840 
841  /* Override TupleDescInitEntry's settings as requested */
842  TupleDescInitEntryCollation(desc, attnum, attcollation);
843  if (entry->storage)
844  att->attstorage = entry->storage;
845 
846  /* Fill in additional stuff not handled by TupleDescInitEntry */
847  att->attnotnull = entry->is_not_null;
848  has_not_null |= entry->is_not_null;
849  att->attislocal = entry->is_local;
850  att->attinhcount = entry->inhcount;
851  }
852 
853  if (has_not_null)
854  {
855  TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
856 
857  constr->has_not_null = true;
858  constr->defval = NULL;
859  constr->missing = NULL;
860  constr->num_defval = 0;
861  constr->check = NULL;
862  constr->num_check = 0;
863  desc->constr = constr;
864  }
865  else
866  {
867  desc->constr = NULL;
868  }
869 
870  return desc;
871 }
char storage
Definition: parsenodes.h:654
bool is_local
Definition: parsenodes.h:650
Oid GetUserId(void)
Definition: miscinit.c:379
ConstrCheck * check
Definition: tupdesc.h:42
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
MissingPtr missing
Definition: tupdesc.h:43
int errcode(int sqlerrcode)
Definition: elog.c:575
bool is_not_null
Definition: parsenodes.h:651
unsigned int Oid
Definition: postgres_ext.h:31
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition: aclchk.c:3659
signed int int32
Definition: c.h:313
AttrDefault * defval
Definition: tupdesc.h:41
#define ERROR
Definition: elog.h:43
NameData attname
Definition: pg_attribute.h:40
bool setof
Definition: parsenodes.h:212
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:761
Oid attcollation
Definition: pg_attribute.h:161
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:197
#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:600
Oid atttypid
Definition: pg_attribute.h:49
#define ereport(elevel, rest)
Definition: elog.h:122
bool has_not_null
Definition: tupdesc.h:46
Oid GetColumnDefCollation(ParseState *pstate, ColumnDef *coldef, Oid typeOid)
Definition: parse_type.c:521
void * palloc0(Size size)
Definition: mcxt.c:955
AclResult
Definition: acl.h:178
void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName, Oid *typeid_p, int32 *typmod_p)
Definition: parse_type.c:293
int16 attnum
Definition: pg_attribute.h:79
uint16 num_defval
Definition: tupdesc.h:44
#define lfirst(lc)
Definition: pg_list.h:106
TupleConstr * constr
Definition: tupdesc.h:87
static int list_length(const List *l)
Definition: pg_list.h:89
TypeName * typeName
Definition: parsenodes.h:648
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:45
List * arrayBounds
Definition: parsenodes.h:216
int errmsg(const char *fmt,...)
Definition: elog.c:797
int inhcount
Definition: parsenodes.h:649
uint16 num_check
Definition: tupdesc.h:45
char * colname
Definition: parsenodes.h:647
AclResult pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4736
int16 AttrNumber
Definition: attnum.h:21

◆ BuildDescFromLists()

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

Definition at line 885 of file tupdesc.c.

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

Referenced by ExecInitFunctionScan(), and ExecInitTableFuncScan().

886 {
887  int natts;
889  ListCell *l1;
890  ListCell *l2;
891  ListCell *l3;
892  ListCell *l4;
893  TupleDesc desc;
894 
895  natts = list_length(names);
896  Assert(natts == list_length(types));
897  Assert(natts == list_length(typmods));
898  Assert(natts == list_length(collations));
899 
900  /*
901  * allocate a new tuple descriptor
902  */
903  desc = CreateTemplateTupleDesc(natts, false);
904 
905  attnum = 0;
906 
907  l2 = list_head(types);
908  l3 = list_head(typmods);
909  l4 = list_head(collations);
910  foreach(l1, names)
911  {
912  char *attname = strVal(lfirst(l1));
913  Oid atttypid;
914  int32 atttypmod;
916 
917  atttypid = lfirst_oid(l2);
918  l2 = lnext(l2);
919  atttypmod = lfirst_int(l3);
920  l3 = lnext(l3);
921  attcollation = lfirst_oid(l4);
922  l4 = lnext(l4);
923 
924  attnum++;
925 
926  TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
927  TupleDescInitEntryCollation(desc, attnum, attcollation);
928  }
929 
930  return desc;
931 }
#define strVal(v)
Definition: value.h:54
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:313
NameData attname
Definition: pg_attribute.h:40
#define lfirst_int(lc)
Definition: pg_list.h:107
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:761
Oid attcollation
Definition: pg_attribute.h:161
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:600
Oid atttypid
Definition: pg_attribute.h:49
#define lnext(lc)
Definition: pg_list.h:105
int16 attnum
Definition: pg_attribute.h:79
#define Assert(condition)
Definition: c.h:699
#define lfirst(lc)
Definition: pg_list.h:106
static int list_length(const List *l)
Definition: pg_list.h:89
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:45
int16 AttrNumber
Definition: attnum.h:21
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ CreateTemplateTupleDesc()

TupleDesc CreateTemplateTupleDesc ( int  natts,
bool  hasoid 
)

Definition at line 45 of file tupdesc.c.

References AssertArg, tupleDesc::constr, FormData_pg_attribute, tupleDesc::natts, offsetof, palloc(), tupleDesc::tdhasoid, tupleDesc::tdrefcount, tupleDesc::tdtypeid, and tupleDesc::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(), GetPGVariableResultDesc(), gistrescan(), IdentifySystem(), init_sexpr(), initGinState(), libpqrcv_processTuples(), load_relcache_init_file(), materializeQueryResult(), 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_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().

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 tupleDesc, 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->tdhasoid = hasoid;
77  desc->tdrefcount = -1; /* assume not reference-counted */
78 
79  return desc;
80 }
Oid tdtypeid
Definition: tupdesc.h:83
bool tdhasoid
Definition: tupdesc.h:85
int natts
Definition: tupdesc.h:82
int32 tdtypmod
Definition: tupdesc.h:84
#define AssertArg(condition)
Definition: c.h:701
FormData_pg_attribute
Definition: pg_attribute.h:181
struct tupleDesc * TupleDesc
TupleConstr * constr
Definition: tupdesc.h:87
void * palloc(Size size)
Definition: mcxt.c:924
int tdrefcount
Definition: tupdesc.h:86
#define offsetof(type, field)
Definition: c.h:622

◆ CreateTupleDesc()

TupleDesc CreateTupleDesc ( int  natts,
bool  hasoid,
Form_pg_attribute attrs 
)

Definition at line 91 of file tupdesc.c.

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

Referenced by InsertOneTuple().

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

◆ CreateTupleDescCopy()

TupleDesc CreateTupleDescCopy ( TupleDesc  tupdesc)

Definition at line 112 of file tupdesc.c.

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

Referenced by assign_record_type_typmod(), BuildTupleHashTable(), check_default_allows_bound(), check_sql_fn_retval(), connectby_text(), connectby_text_serial(), CopyCachedPlan(), crosstab(), crosstab_hash(), database_to_xmlschema_internal(), DefineIndex(), deflist_to_tuplestore(), do_autovacuum(), each_worker(), each_worker_jsonb(), elements_worker(), elements_worker_jsonb(), ExecEvalWholeRowVar(), ExecInitForeignScan(), ExecInitFunctionScan(), ExecPrepareTuplestoreResult(), FetchPreparedStatementResultDesc(), fmgr_sql(), 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_record_worker(), populate_recordset_worker(), RelationBuildLocalRelation(), RelationNameGetTupleDesc(), RevalidateCachedQuery(), schema_to_xmlschema_internal(), spi_dest_startup(), storeRow(), update_cached_tupdesc(), UtilityTupleDescriptor(), and xpath_table().

113 {
114  TupleDesc desc;
115  int i;
116 
117  desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid);
118 
119  /* Flat-copy the attribute array */
120  memcpy(TupleDescAttr(desc, 0),
121  TupleDescAttr(tupdesc, 0),
122  desc->natts * sizeof(FormData_pg_attribute));
123 
124  /*
125  * Since we're not copying constraints and defaults, clear fields
126  * associated with them.
127  */
128  for (i = 0; i < desc->natts; i++)
129  {
130  Form_pg_attribute att = TupleDescAttr(desc, i);
131 
132  att->attnotnull = false;
133  att->atthasdef = false;
134  att->atthasmissing = false;
135  att->attidentity = '\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 }
Oid tdtypeid
Definition: tupdesc.h:83
bool tdhasoid
Definition: tupdesc.h:85
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
int natts
Definition: tupdesc.h:82
int32 tdtypmod
Definition: tupdesc.h:84
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:197
FormData_pg_attribute
Definition: pg_attribute.h:181
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:45
int i

◆ CreateTupleDescCopyConstr()

TupleDesc CreateTupleDescCopyConstr ( TupleDesc  tupdesc)

Definition at line 151 of file tupdesc.c.

References attrDefault::adbin, attrMissing::ammissing, attrMissing::ammissingPresent, constrCheck::ccbin, constrCheck::ccname, constrCheck::ccnoinherit, constrCheck::ccvalid, tupleConstr::check, tupleDesc::constr, CreateTemplateTupleDesc(), datumCopy(), tupleConstr::defval, FormData_pg_attribute, tupleConstr::has_not_null, i, tupleConstr::missing, tupleDesc::natts, tupleConstr::num_check, tupleConstr::num_defval, palloc(), palloc0(), pstrdup(), tupleDesc::tdhasoid, tupleDesc::tdtypeid, tupleDesc::tdtypmod, and TupleDescAttr.

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

152 {
153  TupleDesc desc;
154  TupleConstr *constr = tupdesc->constr;
155  int i;
156 
157  desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid);
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;
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].ammissingPresent)
189  {
190  Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
191 
192  cpy->missing[i].ammissing = datumCopy(constr->missing[i].ammissing,
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 }
Oid tdtypeid
Definition: tupdesc.h:83
char * ccname
Definition: tupdesc.h:32
bool tdhasoid
Definition: tupdesc.h:85
bool ccnoinherit
Definition: tupdesc.h:35
ConstrCheck * check
Definition: tupdesc.h:42
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
char * pstrdup(const char *in)
Definition: mcxt.c:1161
char * ccbin
Definition: tupdesc.h:33
MissingPtr missing
Definition: tupdesc.h:43
int natts
Definition: tupdesc.h:82
bool ammissingPresent
int32 tdtypmod
Definition: tupdesc.h:84
AttrDefault * defval
Definition: tupdesc.h:41
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:197
char * adbin
Definition: tupdesc.h:25
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition: datum.c:128
bool has_not_null
Definition: tupdesc.h:46
void * palloc0(Size size)
Definition: mcxt.c:955
FormData_pg_attribute
Definition: pg_attribute.h:181
uint16 num_defval
Definition: tupdesc.h:44
TupleConstr * constr
Definition: tupdesc.h:87
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:45
void * palloc(Size size)
Definition: mcxt.c:924
bool ccvalid
Definition: tupdesc.h:34
int i
uint16 num_check
Definition: tupdesc.h:45

◆ DecrTupleDescRefCount()

void DecrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 391 of file tupdesc.c.

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

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

392 {
393  Assert(tupdesc->tdrefcount > 0);
394 
396  if (--tupdesc->tdrefcount == 0)
397  FreeTupleDesc(tupdesc);
398 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:140
void ResourceOwnerForgetTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition: resowner.c:1116
#define Assert(condition)
Definition: c.h:699
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:311
int tdrefcount
Definition: tupdesc.h:86

◆ equalTupleDescs()

bool equalTupleDescs ( TupleDesc  tupdesc1,
TupleDesc  tupdesc2 
)

Definition at line 409 of file tupdesc.c.

References attrDefault::adbin, attrDefault::adnum, attrMissing::ammissing, attrMissing::ammissingPresent, constrCheck::ccbin, constrCheck::ccname, constrCheck::ccnoinherit, constrCheck::ccvalid, tupleConstr::check, tupleDesc::constr, datumIsEqual(), tupleConstr::defval, tupleConstr::has_not_null, i, tupleConstr::missing, NameStr, tupleDesc::natts, tupleConstr::num_check, tupleConstr::num_defval, tupleDesc::tdhasoid, tupleDesc::tdtypeid, and TupleDescAttr.

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

410 {
411  int i,
412  j,
413  n;
414 
415  if (tupdesc1->natts != tupdesc2->natts)
416  return false;
417  if (tupdesc1->tdtypeid != tupdesc2->tdtypeid)
418  return false;
419  if (tupdesc1->tdhasoid != tupdesc2->tdhasoid)
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->attisdropped != attr2->attisdropped)
464  return false;
465  if (attr1->attislocal != attr2->attislocal)
466  return false;
467  if (attr1->attinhcount != attr2->attinhcount)
468  return false;
469  if (attr1->attcollation != attr2->attcollation)
470  return false;
471  /* attacl, attoptions and attfdwoptions are not even present... */
472  }
473 
474  if (tupdesc1->constr != NULL)
475  {
476  TupleConstr *constr1 = tupdesc1->constr;
477  TupleConstr *constr2 = tupdesc2->constr;
478 
479  if (constr2 == NULL)
480  return false;
481  if (constr1->has_not_null != constr2->has_not_null)
482  return false;
483  n = constr1->num_defval;
484  if (n != (int) constr2->num_defval)
485  return false;
486  for (i = 0; i < n; i++)
487  {
488  AttrDefault *defval1 = constr1->defval + i;
489  AttrDefault *defval2 = constr2->defval;
490 
491  /*
492  * We can't assume that the items are always read from the system
493  * catalogs in the same order; so use the adnum field to identify
494  * the matching item to compare.
495  */
496  for (j = 0; j < n; defval2++, j++)
497  {
498  if (defval1->adnum == defval2->adnum)
499  break;
500  }
501  if (j >= n)
502  return false;
503  if (strcmp(defval1->adbin, defval2->adbin) != 0)
504  return false;
505  }
506  if (constr1->missing)
507  {
508  if (!constr2->missing)
509  return false;
510  for (i = 0; i < tupdesc1->natts; i++)
511  {
512  AttrMissing *missval1 = constr1->missing + i;
513  AttrMissing *missval2 = constr2->missing + i;
514 
515  if (missval1->ammissingPresent != missval2->ammissingPresent)
516  return false;
517  if (missval1->ammissingPresent)
518  {
519  Form_pg_attribute missatt1 = TupleDescAttr(tupdesc1, i);
520 
521  if (!datumIsEqual(missval1->ammissing, missval2->ammissing,
522  missatt1->attbyval, missatt1->attlen))
523  return false;
524  }
525  }
526  }
527  else if (constr2->missing)
528  return false;
529  n = constr1->num_check;
530  if (n != (int) constr2->num_check)
531  return false;
532  for (i = 0; i < n; i++)
533  {
534  ConstrCheck *check1 = constr1->check + i;
535  ConstrCheck *check2 = constr2->check;
536 
537  /*
538  * Similarly, don't assume that the checks are always read in the
539  * same order; match them up by name and contents. (The name
540  * *should* be unique, but...)
541  */
542  for (j = 0; j < n; check2++, j++)
543  {
544  if (strcmp(check1->ccname, check2->ccname) == 0 &&
545  strcmp(check1->ccbin, check2->ccbin) == 0 &&
546  check1->ccvalid == check2->ccvalid &&
547  check1->ccnoinherit == check2->ccnoinherit)
548  break;
549  }
550  if (j >= n)
551  return false;
552  }
553  }
554  else if (tupdesc2->constr != NULL)
555  return false;
556  return true;
557 }
Oid tdtypeid
Definition: tupdesc.h:83
char * ccname
Definition: tupdesc.h:32
bool tdhasoid
Definition: tupdesc.h:85
bool ccnoinherit
Definition: tupdesc.h:35
ConstrCheck * check
Definition: tupdesc.h:42
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
char * ccbin
Definition: tupdesc.h:33
bool datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen)
Definition: datum.c:219
MissingPtr missing
Definition: tupdesc.h:43
int natts
Definition: tupdesc.h:82
bool ammissingPresent
AttrDefault * defval
Definition: tupdesc.h:41
AttrNumber adnum
Definition: tupdesc.h:24
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:197
char * adbin
Definition: tupdesc.h:25
bool has_not_null
Definition: tupdesc.h:46
uint16 num_defval
Definition: tupdesc.h:44
TupleConstr * constr
Definition: tupdesc.h:87
bool ccvalid
Definition: tupdesc.h:34
int i
#define NameStr(name)
Definition: c.h:576
uint16 num_check
Definition: tupdesc.h:45

◆ FreeTupleDesc()

void FreeTupleDesc ( TupleDesc  tupdesc)

Definition at line 311 of file tupdesc.c.

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

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

312 {
313  int i;
314 
315  /*
316  * Possibly this should assert tdrefcount == 0, to disallow explicit
317  * freeing of un-refcounted tupdescs?
318  */
319  Assert(tupdesc->tdrefcount <= 0);
320 
321  if (tupdesc->constr)
322  {
323  if (tupdesc->constr->num_defval > 0)
324  {
325  AttrDefault *attrdef = tupdesc->constr->defval;
326 
327  for (i = tupdesc->constr->num_defval - 1; i >= 0; i--)
328  {
329  if (attrdef[i].adbin)
330  pfree(attrdef[i].adbin);
331  }
332  pfree(attrdef);
333  }
334  if (tupdesc->constr->missing)
335  {
336  AttrMissing *attrmiss = tupdesc->constr->missing;
337 
338  for (i = tupdesc->natts - 1; i >= 0; i--)
339  {
340  if (attrmiss[i].ammissingPresent
341  && !TupleDescAttr(tupdesc, i)->attbyval)
342  pfree(DatumGetPointer(attrmiss[i].ammissing));
343  }
344  pfree(attrmiss);
345  }
346  if (tupdesc->constr->num_check > 0)
347  {
348  ConstrCheck *check = tupdesc->constr->check;
349 
350  for (i = tupdesc->constr->num_check - 1; i >= 0; i--)
351  {
352  if (check[i].ccname)
353  pfree(check[i].ccname);
354  if (check[i].ccbin)
355  pfree(check[i].ccbin);
356  }
357  pfree(check);
358  }
359  pfree(tupdesc->constr);
360  }
361 
362  pfree(tupdesc);
363 }
ConstrCheck * check
Definition: tupdesc.h:42
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
MissingPtr missing
Definition: tupdesc.h:43
int natts
Definition: tupdesc.h:82
bool attbyval
Definition: pg_attribute.h:108
void pfree(void *pointer)
Definition: mcxt.c:1031
AttrDefault * defval
Definition: tupdesc.h:41
uint16 num_defval
Definition: tupdesc.h:44
#define Assert(condition)
Definition: c.h:699
TupleConstr * constr
Definition: tupdesc.h:87
#define DatumGetPointer(X)
Definition: postgres.h:532
int tdrefcount
Definition: tupdesc.h:86
int i
uint16 num_check
Definition: tupdesc.h:45

◆ hashTupleDesc()

uint32 hashTupleDesc ( TupleDesc  desc)

Definition at line 570 of file tupdesc.c.

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

Referenced by record_type_typmod_hash(), and shared_record_table_hash().

571 {
572  uint32 s;
573  int i;
574 
575  s = hash_combine(0, hash_uint32(desc->natts));
576  s = hash_combine(s, hash_uint32(desc->tdtypeid));
577  s = hash_combine(s, hash_uint32(desc->tdhasoid));
578  for (i = 0; i < desc->natts; ++i)
579  s = hash_combine(s, hash_uint32(TupleDescAttr(desc, i)->atttypid));
580 
581  return s;
582 }
static uint32 hash_combine(uint32 a, uint32 b)
Definition: hashutils.h:17
Oid tdtypeid
Definition: tupdesc.h:83
bool tdhasoid
Definition: tupdesc.h:85
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
int natts
Definition: tupdesc.h:82
unsigned int uint32
Definition: c.h:325
Oid atttypid
Definition: pg_attribute.h:49
Datum hash_uint32(uint32 k)
Definition: hashfunc.c:853
int i

◆ IncrTupleDescRefCount()

void IncrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 373 of file tupdesc.c.

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

Referenced by cache_record_field_properties().

374 {
375  Assert(tupdesc->tdrefcount >= 0);
376 
378  tupdesc->tdrefcount++;
380 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:140
void ResourceOwnerRememberTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition: resowner.c:1107
void ResourceOwnerEnlargeTupleDescs(ResourceOwner owner)
Definition: resowner.c:1096
#define Assert(condition)
Definition: c.h:699
int tdrefcount
Definition: tupdesc.h:86

◆ TupleDescCopy()

void TupleDescCopy ( TupleDesc  dst,
TupleDesc  src 
)

Definition at line 233 of file tupdesc.c.

References tupleDesc::constr, i, tupleDesc::natts, tupleDesc::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  }
253  dst->constr = NULL;
254 
255  /*
256  * Also, assume the destination is not to be ref-counted. (Copying the
257  * source's refcount would be wrong in any case.)
258  */
259  dst->tdrefcount = -1;
260 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
#define TupleDescSize(src)
Definition: tupdesc.h:104
int natts
Definition: tupdesc.h:82
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:197
TupleConstr * constr
Definition: tupdesc.h:87
int tdrefcount
Definition: tupdesc.h:86
int i

◆ TupleDescCopyEntry()

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

Definition at line 270 of file tupdesc.c.

References AssertArg, ATTRIBUTE_FIXED_PART_SIZE, PointerIsValid, and TupleDescAttr.

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

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

◆ TupleDescInitBuiltinEntry()

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

Definition at line 672 of file tupdesc.c.

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

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

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

◆ TupleDescInitEntry()

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

Definition at line 600 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(), GetPGVariableResultDesc(), gistrescan(), init_sexpr(), initGinState(), libpqrcv_processTuples(), materializeQueryResult(), 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_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().

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

◆ TupleDescInitEntryCollation()

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

Definition at line 761 of file tupdesc.c.

References AssertArg, PointerIsValid, and TupleDescAttr.

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

764 {
765  /*
766  * sanity checks
767  */
768  AssertArg(PointerIsValid(desc));
769  AssertArg(attributeNumber >= 1);
770  AssertArg(attributeNumber <= desc->natts);
771 
772  TupleDescAttr(desc, attributeNumber - 1)->attcollation = collationid;
773 }
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
#define AssertArg(condition)
Definition: c.h:701
#define PointerIsValid(pointer)
Definition: c.h:593