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

775 {
776  int natts;
778  ListCell *l;
779  TupleDesc desc;
780  bool has_not_null;
781  char *attname;
782  Oid atttypid;
783  int32 atttypmod;
784  Oid attcollation;
785  int attdim;
786 
787  /*
788  * allocate a new tuple descriptor
789  */
790  natts = list_length(schema);
791  desc = CreateTemplateTupleDesc(natts);
792  has_not_null = false;
793 
794  attnum = 0;
795 
796  foreach(l, schema)
797  {
798  ColumnDef *entry = lfirst(l);
799  AclResult aclresult;
800  Form_pg_attribute att;
801 
802  /*
803  * for each entry in the list, get the name and type information from
804  * the list and have TupleDescInitEntry fill in the attribute
805  * information we need.
806  */
807  attnum++;
808 
809  attname = entry->colname;
810  typenameTypeIdAndMod(NULL, entry->typeName, &atttypid, &atttypmod);
811 
812  aclresult = pg_type_aclcheck(atttypid, GetUserId(), ACL_USAGE);
813  if (aclresult != ACLCHECK_OK)
814  aclcheck_error_type(aclresult, atttypid);
815 
816  attcollation = GetColumnDefCollation(NULL, entry, atttypid);
817  attdim = list_length(entry->typeName->arrayBounds);
818 
819  if (entry->typeName->setof)
820  ereport(ERROR,
821  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
822  errmsg("column \"%s\" cannot be declared SETOF",
823  attname)));
824 
825  TupleDescInitEntry(desc, attnum, attname,
826  atttypid, atttypmod, attdim);
827  att = TupleDescAttr(desc, attnum - 1);
828 
829  /* Override TupleDescInitEntry's settings as requested */
830  TupleDescInitEntryCollation(desc, attnum, attcollation);
831  if (entry->storage)
832  att->attstorage = entry->storage;
833 
834  /* Fill in additional stuff not handled by TupleDescInitEntry */
835  att->attnotnull = entry->is_not_null;
836  has_not_null |= entry->is_not_null;
837  att->attislocal = entry->is_local;
838  att->attinhcount = entry->inhcount;
839  }
840 
841  if (has_not_null)
842  {
843  TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
844 
845  constr->has_not_null = true;
846  constr->has_generated_stored = false;
847  constr->defval = NULL;
848  constr->missing = NULL;
849  constr->num_defval = 0;
850  constr->check = NULL;
851  constr->num_check = 0;
852  desc->constr = constr;
853  }
854  else
855  {
856  desc->constr = NULL;
857  }
858 
859  return desc;
860 }
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:3626
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:751
TupleConstr * constr
Definition: tupdesc.h:85
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:203
#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:580
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:4811
int16 AttrNumber
Definition: attnum.h:21

◆ BuildDescFromLists()

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

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

875 {
876  int natts;
878  ListCell *l1;
879  ListCell *l2;
880  ListCell *l3;
881  ListCell *l4;
882  TupleDesc desc;
883 
884  natts = list_length(names);
885  Assert(natts == list_length(types));
886  Assert(natts == list_length(typmods));
887  Assert(natts == list_length(collations));
888 
889  /*
890  * allocate a new tuple descriptor
891  */
892  desc = CreateTemplateTupleDesc(natts);
893 
894  attnum = 0;
895  forfour(l1, names, l2, types, l3, typmods, l4, collations)
896  {
897  char *attname = strVal(lfirst(l1));
898  Oid atttypid = lfirst_oid(l2);
899  int32 atttypmod = lfirst_int(l3);
900  Oid attcollation = lfirst_oid(l4);
901 
902  attnum++;
903 
904  TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
905  TupleDescInitEntryCollation(desc, attnum, attcollation);
906  }
907 
908  return desc;
909 }
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:751
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:580
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:187
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:195
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(), ExecPrepareTuplestoreResult(), FetchPreparedStatementResultDesc(), fmgr_sql(), get_record_type_from_query(), 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:203
FormData_pg_attribute
Definition: pg_attribute.h:187
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:203
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:187
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.
428  */
429  if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0)
430  return false;
431  if (attr1->atttypid != attr2->atttypid)
432  return false;
433  if (attr1->attstattarget != attr2->attstattarget)
434  return false;
435  if (attr1->attlen != attr2->attlen)
436  return false;
437  if (attr1->attndims != attr2->attndims)
438  return false;
439  if (attr1->atttypmod != attr2->atttypmod)
440  return false;
441  if (attr1->attbyval != attr2->attbyval)
442  return false;
443  if (attr1->attstorage != attr2->attstorage)
444  return false;
445  if (attr1->attalign != attr2->attalign)
446  return false;
447  if (attr1->attnotnull != attr2->attnotnull)
448  return false;
449  if (attr1->atthasdef != attr2->atthasdef)
450  return false;
451  if (attr1->attidentity != attr2->attidentity)
452  return false;
453  if (attr1->attgenerated != attr2->attgenerated)
454  return false;
455  if (attr1->attisdropped != attr2->attisdropped)
456  return false;
457  if (attr1->attislocal != attr2->attislocal)
458  return false;
459  if (attr1->attinhcount != attr2->attinhcount)
460  return false;
461  if (attr1->attcollation != attr2->attcollation)
462  return false;
463  /* attacl, attoptions and attfdwoptions are not even present... */
464  }
465 
466  if (tupdesc1->constr != NULL)
467  {
468  TupleConstr *constr1 = tupdesc1->constr;
469  TupleConstr *constr2 = tupdesc2->constr;
470 
471  if (constr2 == NULL)
472  return false;
473  if (constr1->has_not_null != constr2->has_not_null)
474  return false;
475  if (constr1->has_generated_stored != constr2->has_generated_stored)
476  return false;
477  n = constr1->num_defval;
478  if (n != (int) constr2->num_defval)
479  return false;
480  /* We assume here that both AttrDefault arrays are in adnum order */
481  for (i = 0; i < n; i++)
482  {
483  AttrDefault *defval1 = constr1->defval + i;
484  AttrDefault *defval2 = constr2->defval + i;
485 
486  if (defval1->adnum != defval2->adnum)
487  return false;
488  if (strcmp(defval1->adbin, defval2->adbin) != 0)
489  return false;
490  }
491  if (constr1->missing)
492  {
493  if (!constr2->missing)
494  return false;
495  for (i = 0; i < tupdesc1->natts; i++)
496  {
497  AttrMissing *missval1 = constr1->missing + i;
498  AttrMissing *missval2 = constr2->missing + i;
499 
500  if (missval1->am_present != missval2->am_present)
501  return false;
502  if (missval1->am_present)
503  {
504  Form_pg_attribute missatt1 = TupleDescAttr(tupdesc1, i);
505 
506  if (!datumIsEqual(missval1->am_value, missval2->am_value,
507  missatt1->attbyval, missatt1->attlen))
508  return false;
509  }
510  }
511  }
512  else if (constr2->missing)
513  return false;
514  n = constr1->num_check;
515  if (n != (int) constr2->num_check)
516  return false;
517 
518  /*
519  * Similarly, we rely here on the ConstrCheck entries being sorted by
520  * name. If there are duplicate names, the outcome of the comparison
521  * is uncertain, but that should not happen.
522  */
523  for (i = 0; i < n; i++)
524  {
525  ConstrCheck *check1 = constr1->check + i;
526  ConstrCheck *check2 = constr2->check + i;
527 
528  if (!(strcmp(check1->ccname, check2->ccname) == 0 &&
529  strcmp(check1->ccbin, check2->ccbin) == 0 &&
530  check1->ccvalid == check2->ccvalid &&
531  check1->ccnoinherit == check2->ccnoinherit))
532  return false;
533  }
534  }
535  else if (tupdesc2->constr != NULL)
536  return false;
537  return true;
538 }
#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:203
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(), ordered_set_startup(), PLy_result_dealloc(), 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 551 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().

552 {
553  uint32 s;
554  int i;
555 
556  s = hash_combine(0, hash_uint32(desc->natts));
557  s = hash_combine(s, hash_uint32(desc->tdtypeid));
558  for (i = 0; i < desc->natts; ++i)
559  s = hash_combine(s, hash_uint32(TupleDescAttr(desc, i)->atttypid));
560 
561  return s;
562 }
#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:203
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:203
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:195
#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 658 of file tupdesc.c.

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

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

664 {
665  Form_pg_attribute att;
666 
667  /* sanity checks */
668  AssertArg(PointerIsValid(desc));
669  AssertArg(attributeNumber >= 1);
670  AssertArg(attributeNumber <= desc->natts);
671 
672  /* initialize the attribute fields */
673  att = TupleDescAttr(desc, attributeNumber - 1);
674  att->attrelid = 0; /* dummy value */
675 
676  /* unlike TupleDescInitEntry, we require an attribute name */
677  Assert(attributeName != NULL);
678  namestrcpy(&(att->attname), attributeName);
679 
680  att->attstattarget = -1;
681  att->attcacheoff = -1;
682  att->atttypmod = typmod;
683 
684  att->attnum = attributeNumber;
685  att->attndims = attdim;
686 
687  att->attnotnull = false;
688  att->atthasdef = false;
689  att->atthasmissing = false;
690  att->attidentity = '\0';
691  att->attgenerated = '\0';
692  att->attisdropped = false;
693  att->attislocal = true;
694  att->attinhcount = 0;
695  /* attacl, attoptions and attfdwoptions are not present in tupledescs */
696 
697  att->atttypid = oidtypeid;
698 
699  /*
700  * Our goal here is to support just enough types to let basic builtin
701  * commands work without catalog access - e.g. so that we can do certain
702  * things even in processes that are not connected to a database.
703  */
704  switch (oidtypeid)
705  {
706  case TEXTOID:
707  case TEXTARRAYOID:
708  att->attlen = -1;
709  att->attbyval = false;
710  att->attalign = TYPALIGN_INT;
711  att->attstorage = TYPSTORAGE_EXTENDED;
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->attcollation = InvalidOid;
721  break;
722 
723  case INT4OID:
724  att->attlen = 4;
725  att->attbyval = true;
726  att->attalign = TYPALIGN_INT;
727  att->attstorage = TYPSTORAGE_PLAIN;
728  att->attcollation = InvalidOid;
729  break;
730 
731  case INT8OID:
732  att->attlen = 8;
733  att->attbyval = FLOAT8PASSBYVAL;
734  att->attalign = TYPALIGN_DOUBLE;
735  att->attstorage = TYPSTORAGE_PLAIN;
736  att->attcollation = InvalidOid;
737  break;
738 
739  default:
740  elog(ERROR, "unsupported type %u", oidtypeid);
741  }
742 }
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:203
#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 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 580 of file tupdesc.c.

References AssertArg, elog, ERROR, GetDefaultToastCompression(), GETSTRUCT, HeapTupleIsValid, InvalidCompressionMethod, IsStorageCompressible, 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().

586 {
587  HeapTuple tuple;
588  Form_pg_type typeForm;
589  Form_pg_attribute att;
590 
591  /*
592  * sanity checks
593  */
594  AssertArg(PointerIsValid(desc));
595  AssertArg(attributeNumber >= 1);
596  AssertArg(attributeNumber <= desc->natts);
597 
598  /*
599  * initialize the attribute fields
600  */
601  att = TupleDescAttr(desc, attributeNumber - 1);
602 
603  att->attrelid = 0; /* dummy value */
604 
605  /*
606  * Note: attributeName can be NULL, because the planner doesn't always
607  * fill in valid resname values in targetlists, particularly for resjunk
608  * attributes. Also, do nothing if caller wants to re-use the old attname.
609  */
610  if (attributeName == NULL)
611  MemSet(NameStr(att->attname), 0, NAMEDATALEN);
612  else if (attributeName != NameStr(att->attname))
613  namestrcpy(&(att->attname), attributeName);
614 
615  att->attstattarget = -1;
616  att->attcacheoff = -1;
617  att->atttypmod = typmod;
618 
619  att->attnum = attributeNumber;
620  att->attndims = attdim;
621 
622  att->attnotnull = false;
623  att->atthasdef = false;
624  att->atthasmissing = false;
625  att->attidentity = '\0';
626  att->attgenerated = '\0';
627  att->attisdropped = false;
628  att->attislocal = true;
629  att->attinhcount = 0;
630  /* attacl, attoptions and attfdwoptions are not present in tupledescs */
631 
632  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(oidtypeid));
633  if (!HeapTupleIsValid(tuple))
634  elog(ERROR, "cache lookup failed for type %u", oidtypeid);
635  typeForm = (Form_pg_type) GETSTRUCT(tuple);
636 
637  att->atttypid = oidtypeid;
638  att->attlen = typeForm->typlen;
639  att->attbyval = typeForm->typbyval;
640  att->attalign = typeForm->typalign;
641  att->attstorage = typeForm->typstorage;
642  att->attcollation = typeForm->typcollation;
643 
644  if (IsStorageCompressible(typeForm->typstorage))
645  att->attcompression = GetDefaultToastCompression();
646  else
647  att->attcompression = InvalidCompressionMethod;
648 
649  ReleaseSysCache(tuple);
650 }
#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
static char GetDefaultToastCompression(void)
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:203
#define AssertArg(condition)
Definition: c.h:806
#define IsStorageCompressible(storage)
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 751 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().

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