PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
tupdesc.c File Reference
#include "postgres.h"
#include "access/htup_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/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 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)
 
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

TupleDesc BuildDescForRelation ( List schema)

Definition at line 681 of file tupdesc.c.

References ACL_USAGE, aclcheck_error_type(), ACLCHECK_OK, TypeName::arrayBounds, tupleDesc::attrs, 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(), tupleDesc::natts, NULL, tupleConstr::num_check, tupleConstr::num_defval, palloc0(), pg_type_aclcheck(), TypeName::setof, ColumnDef::storage, TupleDescInitEntry(), TupleDescInitEntryCollation(), ColumnDef::typeName, and typenameTypeIdAndMod().

Referenced by DefineRelation(), and DefineVirtualRelation().

682 {
683  int natts;
684  AttrNumber attnum;
685  ListCell *l;
686  TupleDesc desc;
687  bool has_not_null;
688  char *attname;
689  Oid atttypid;
690  int32 atttypmod;
691  Oid attcollation;
692  int attdim;
693 
694  /*
695  * allocate a new tuple descriptor
696  */
697  natts = list_length(schema);
698  desc = CreateTemplateTupleDesc(natts, false);
699  has_not_null = false;
700 
701  attnum = 0;
702 
703  foreach(l, schema)
704  {
705  ColumnDef *entry = lfirst(l);
706  AclResult aclresult;
707 
708  /*
709  * for each entry in the list, get the name and type information from
710  * the list and have TupleDescInitEntry fill in the attribute
711  * information we need.
712  */
713  attnum++;
714 
715  attname = entry->colname;
716  typenameTypeIdAndMod(NULL, entry->typeName, &atttypid, &atttypmod);
717 
718  aclresult = pg_type_aclcheck(atttypid, GetUserId(), ACL_USAGE);
719  if (aclresult != ACLCHECK_OK)
720  aclcheck_error_type(aclresult, atttypid);
721 
722  attcollation = GetColumnDefCollation(NULL, entry, atttypid);
723  attdim = list_length(entry->typeName->arrayBounds);
724 
725  if (entry->typeName->setof)
726  ereport(ERROR,
727  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
728  errmsg("column \"%s\" cannot be declared SETOF",
729  attname)));
730 
731  TupleDescInitEntry(desc, attnum, attname,
732  atttypid, atttypmod, attdim);
733 
734  /* Override TupleDescInitEntry's settings as requested */
735  TupleDescInitEntryCollation(desc, attnum, attcollation);
736  if (entry->storage)
737  desc->attrs[attnum - 1]->attstorage = entry->storage;
738 
739  /* Fill in additional stuff not handled by TupleDescInitEntry */
740  desc->attrs[attnum - 1]->attnotnull = entry->is_not_null;
741  has_not_null |= entry->is_not_null;
742  desc->attrs[attnum - 1]->attislocal = entry->is_local;
743  desc->attrs[attnum - 1]->attinhcount = entry->inhcount;
744  }
745 
746  if (has_not_null)
747  {
748  TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
749 
750  constr->has_not_null = true;
751  constr->defval = NULL;
752  constr->num_defval = 0;
753  constr->check = NULL;
754  constr->num_check = 0;
755  desc->constr = constr;
756  }
757  else
758  {
759  desc->constr = NULL;
760  }
761 
762  return desc;
763 }
char storage
Definition: parsenodes.h:647
bool is_local
Definition: parsenodes.h:643
Oid GetUserId(void)
Definition: miscinit.c:283
ConstrCheck * check
Definition: tupdesc.h:40
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int errcode(int sqlerrcode)
Definition: elog.c:575
bool is_not_null
Definition: parsenodes.h:644
unsigned int Oid
Definition: postgres_ext.h:31
void aclcheck_error_type(AclResult aclerr, Oid typeOid)
Definition: aclchk.c:3457
signed int int32
Definition: c.h:256
AttrDefault * defval
Definition: tupdesc.h:39
#define ERROR
Definition: elog.h:43
bool setof
Definition: parsenodes.h:211
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:656
#define ACL_USAGE
Definition: parsenodes.h:80
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:497
#define ereport(elevel, rest)
Definition: elog.h:122
bool has_not_null
Definition: tupdesc.h:43
Oid GetColumnDefCollation(ParseState *pstate, ColumnDef *coldef, Oid typeOid)
Definition: parse_type.c:521
void * palloc0(Size size)
Definition: mcxt.c:878
AclResult
Definition: acl.h:170
void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName, Oid *typeid_p, int32 *typmod_p)
Definition: parse_type.c:293
uint16 num_defval
Definition: tupdesc.h:41
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
TupleConstr * constr
Definition: tupdesc.h:76
static int list_length(const List *l)
Definition: pg_list.h:89
TypeName * typeName
Definition: parsenodes.h:641
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:41
List * arrayBounds
Definition: parsenodes.h:215
int errmsg(const char *fmt,...)
Definition: elog.c:797
int inhcount
Definition: parsenodes.h:642
uint16 num_check
Definition: tupdesc.h:42
char * colname
Definition: parsenodes.h:640
AclResult pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4534
int16 AttrNumber
Definition: attnum.h:21
TupleDesc BuildDescFromLists ( List names,
List types,
List typmods,
List collations 
)

Definition at line 777 of file tupdesc.c.

References Assert, CreateTemplateTupleDesc(), lfirst, lfirst_int, lfirst_oid, list_head(), list_length(), lnext, tupleDesc::natts, strVal, TupleDescInitEntry(), and TupleDescInitEntryCollation().

Referenced by ExecInitFunctionScan(), and ExecInitTableFuncScan().

778 {
779  int natts;
780  AttrNumber attnum;
781  ListCell *l1;
782  ListCell *l2;
783  ListCell *l3;
784  ListCell *l4;
785  TupleDesc desc;
786 
787  natts = list_length(names);
788  Assert(natts == list_length(types));
789  Assert(natts == list_length(typmods));
790  Assert(natts == list_length(collations));
791 
792  /*
793  * allocate a new tuple descriptor
794  */
795  desc = CreateTemplateTupleDesc(natts, false);
796 
797  attnum = 0;
798 
799  l2 = list_head(types);
800  l3 = list_head(typmods);
801  l4 = list_head(collations);
802  foreach(l1, names)
803  {
804  char *attname = strVal(lfirst(l1));
805  Oid atttypid;
806  int32 atttypmod;
807  Oid attcollation;
808 
809  atttypid = lfirst_oid(l2);
810  l2 = lnext(l2);
811  atttypmod = lfirst_int(l3);
812  l3 = lnext(l3);
813  attcollation = lfirst_oid(l4);
814  l4 = lnext(l4);
815 
816  attnum++;
817 
818  TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
819  TupleDescInitEntryCollation(desc, attnum, attcollation);
820  }
821 
822  return desc;
823 }
#define strVal(v)
Definition: value.h:54
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:256
#define lfirst_int(lc)
Definition: pg_list.h:107
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:656
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:497
#define lnext(lc)
Definition: pg_list.h:105
#define Assert(condition)
Definition: c.h:675
#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:41
int16 AttrNumber
Definition: attnum.h:21
#define lfirst_oid(lc)
Definition: pg_list.h:108
TupleDesc CreateTemplateTupleDesc ( int  natts,
bool  hasoid 
)

Definition at line 41 of file tupdesc.c.

References AssertArg, ATTRIBUTE_FIXED_PART_SIZE, tupleDesc::attrs, tupleDesc::constr, i, MAXALIGN, tupleDesc::natts, NULL, palloc(), RECORDOID, 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(), 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(), 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(), ts_setup_firstcall(), tsvector_unnest(), tt_setup_firstcall(), and TypeGetTupleDesc().

42 {
43  TupleDesc desc;
44  char *stg;
45  int attroffset;
46 
47  /*
48  * sanity checks
49  */
50  AssertArg(natts >= 0);
51 
52  /*
53  * Allocate enough memory for the tuple descriptor, including the
54  * attribute rows, and set up the attribute row pointers.
55  *
56  * Note: we assume that sizeof(struct tupleDesc) is a multiple of the
57  * struct pointer alignment requirement, and hence we don't need to insert
58  * alignment padding between the struct and the array of attribute row
59  * pointers.
60  *
61  * Note: Only the fixed part of pg_attribute rows is included in tuple
62  * descriptors, so we only need ATTRIBUTE_FIXED_PART_SIZE space per attr.
63  * That might need alignment padding, however.
64  */
65  attroffset = sizeof(struct tupleDesc) + natts * sizeof(Form_pg_attribute);
66  attroffset = MAXALIGN(attroffset);
67  stg = palloc(attroffset + natts * MAXALIGN(ATTRIBUTE_FIXED_PART_SIZE));
68  desc = (TupleDesc) stg;
69 
70  if (natts > 0)
71  {
73  int i;
74 
75  attrs = (Form_pg_attribute *) (stg + sizeof(struct tupleDesc));
76  desc->attrs = attrs;
77  stg += attroffset;
78  for (i = 0; i < natts; i++)
79  {
80  attrs[i] = (Form_pg_attribute) stg;
82  }
83  }
84  else
85  desc->attrs = NULL;
86 
87  /*
88  * Initialize other fields of the tupdesc.
89  */
90  desc->natts = natts;
91  desc->constr = NULL;
92  desc->tdtypeid = RECORDOID;
93  desc->tdtypmod = -1;
94  desc->tdhasoid = hasoid;
95  desc->tdrefcount = -1; /* assume not reference-counted */
96 
97  return desc;
98 }
Oid tdtypeid
Definition: tupdesc.h:77
bool tdhasoid
Definition: tupdesc.h:79
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
int32 tdtypmod
Definition: tupdesc.h:78
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define RECORDOID
Definition: pg_type.h:680
struct tupleDesc * TupleDesc
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:179
#define AssertArg(condition)
Definition: c.h:677
#define NULL
Definition: c.h:229
TupleConstr * constr
Definition: tupdesc.h:76
#define MAXALIGN(LEN)
Definition: c.h:588
void * palloc(Size size)
Definition: mcxt.c:849
int tdrefcount
Definition: tupdesc.h:80
int i
TupleDesc CreateTupleDesc ( int  natts,
bool  hasoid,
Form_pg_attribute attrs 
)

Definition at line 112 of file tupdesc.c.

References AssertArg, tupleDesc::attrs, tupleDesc::constr, tupleDesc::natts, NULL, palloc(), RECORDOID, tupleDesc::tdhasoid, tupleDesc::tdrefcount, tupleDesc::tdtypeid, and tupleDesc::tdtypmod.

Referenced by InsertOneTuple(), and TupleQueueHandleControlMessage().

113 {
114  TupleDesc desc;
115 
116  /*
117  * sanity checks
118  */
119  AssertArg(natts >= 0);
120 
121  desc = (TupleDesc) palloc(sizeof(struct tupleDesc));
122  desc->attrs = attrs;
123  desc->natts = natts;
124  desc->constr = NULL;
125  desc->tdtypeid = RECORDOID;
126  desc->tdtypmod = -1;
127  desc->tdhasoid = hasoid;
128  desc->tdrefcount = -1; /* assume not reference-counted */
129 
130  return desc;
131 }
Oid tdtypeid
Definition: tupdesc.h:77
bool tdhasoid
Definition: tupdesc.h:79
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
int32 tdtypmod
Definition: tupdesc.h:78
#define RECORDOID
Definition: pg_type.h:680
struct tupleDesc * TupleDesc
#define AssertArg(condition)
Definition: c.h:677
#define NULL
Definition: c.h:229
TupleConstr * constr
Definition: tupdesc.h:76
void * palloc(Size size)
Definition: mcxt.c:849
int tdrefcount
Definition: tupdesc.h:80
TupleDesc CreateTupleDescCopy ( TupleDesc  tupdesc)

Definition at line 141 of file tupdesc.c.

References ATTRIBUTE_FIXED_PART_SIZE, tupleDesc::attrs, CreateTemplateTupleDesc(), i, tupleDesc::natts, tupleDesc::tdhasoid, tupleDesc::tdtypeid, and tupleDesc::tdtypmod.

Referenced by assign_record_type_typmod(), ATGetQueueEntry(), build_row_from_class(), 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(), exec_move_row(), exec_stmt_return(), ExecEvalWholeRowVar(), ExecInitFunctionScan(), ExecPrepareTuplestoreResult(), FetchPreparedStatementResultDesc(), fmgr_sql(), init_sexpr(), LookupTupleHashEntry(), materializeResult(), PersistHoldablePortal(), pg_config(), plperl_return_next(), plpgsql_exec_function(), pltcl_func_handler(), PLy_spi_execute_fetch_result(), populate_composite(), populate_recordset_worker(), RelationBuildLocalRelation(), RelationNameGetTupleDesc(), RevalidateCachedQuery(), schema_to_xmlschema_internal(), spi_dest_startup(), storeRow(), TQExamineRecord(), TQRemapRecord(), UtilityTupleDescriptor(), and xpath_table().

142 {
143  TupleDesc desc;
144  int i;
145 
146  desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid);
147 
148  for (i = 0; i < desc->natts; i++)
149  {
150  memcpy(desc->attrs[i], tupdesc->attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
151  desc->attrs[i]->attnotnull = false;
152  desc->attrs[i]->atthasdef = false;
153  desc->attrs[i]->attidentity = '\0';
154  }
155 
156  desc->tdtypeid = tupdesc->tdtypeid;
157  desc->tdtypmod = tupdesc->tdtypmod;
158 
159  return desc;
160 }
Oid tdtypeid
Definition: tupdesc.h:77
bool tdhasoid
Definition: tupdesc.h:79
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
int32 tdtypmod
Definition: tupdesc.h:78
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:179
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:41
int i
TupleDesc CreateTupleDescCopyConstr ( TupleDesc  tupdesc)

Definition at line 168 of file tupdesc.c.

References attrDefault::adbin, ATTRIBUTE_FIXED_PART_SIZE, tupleDesc::attrs, constrCheck::ccbin, constrCheck::ccname, constrCheck::ccnoinherit, constrCheck::ccvalid, tupleConstr::check, tupleDesc::constr, CreateTemplateTupleDesc(), tupleConstr::defval, tupleConstr::has_not_null, i, tupleDesc::natts, tupleConstr::num_check, tupleConstr::num_defval, palloc(), palloc0(), pstrdup(), tupleDesc::tdhasoid, tupleDesc::tdtypeid, and tupleDesc::tdtypmod.

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

169 {
170  TupleDesc desc;
171  TupleConstr *constr = tupdesc->constr;
172  int i;
173 
174  desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid);
175 
176  for (i = 0; i < desc->natts; i++)
177  {
178  memcpy(desc->attrs[i], tupdesc->attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
179  }
180 
181  if (constr)
182  {
183  TupleConstr *cpy = (TupleConstr *) palloc0(sizeof(TupleConstr));
184 
185  cpy->has_not_null = constr->has_not_null;
186 
187  if ((cpy->num_defval = constr->num_defval) > 0)
188  {
189  cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault));
190  memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault));
191  for (i = cpy->num_defval - 1; i >= 0; i--)
192  {
193  if (constr->defval[i].adbin)
194  cpy->defval[i].adbin = pstrdup(constr->defval[i].adbin);
195  }
196  }
197 
198  if ((cpy->num_check = constr->num_check) > 0)
199  {
200  cpy->check = (ConstrCheck *) palloc(cpy->num_check * sizeof(ConstrCheck));
201  memcpy(cpy->check, constr->check, cpy->num_check * sizeof(ConstrCheck));
202  for (i = cpy->num_check - 1; i >= 0; i--)
203  {
204  if (constr->check[i].ccname)
205  cpy->check[i].ccname = pstrdup(constr->check[i].ccname);
206  if (constr->check[i].ccbin)
207  cpy->check[i].ccbin = pstrdup(constr->check[i].ccbin);
208  cpy->check[i].ccvalid = constr->check[i].ccvalid;
209  cpy->check[i].ccnoinherit = constr->check[i].ccnoinherit;
210  }
211  }
212 
213  desc->constr = cpy;
214  }
215 
216  desc->tdtypeid = tupdesc->tdtypeid;
217  desc->tdtypmod = tupdesc->tdtypmod;
218 
219  return desc;
220 }
Oid tdtypeid
Definition: tupdesc.h:77
char * ccname
Definition: tupdesc.h:30
bool tdhasoid
Definition: tupdesc.h:79
bool ccnoinherit
Definition: tupdesc.h:33
ConstrCheck * check
Definition: tupdesc.h:40
char * pstrdup(const char *in)
Definition: mcxt.c:1077
char * ccbin
Definition: tupdesc.h:31
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
int32 tdtypmod
Definition: tupdesc.h:78
AttrDefault * defval
Definition: tupdesc.h:39
char * adbin
Definition: tupdesc.h:25
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:179
bool has_not_null
Definition: tupdesc.h:43
void * palloc0(Size size)
Definition: mcxt.c:878
uint16 num_defval
Definition: tupdesc.h:41
TupleConstr * constr
Definition: tupdesc.h:76
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:41
void * palloc(Size size)
Definition: mcxt.c:849
bool ccvalid
Definition: tupdesc.h:32
int i
uint16 num_check
Definition: tupdesc.h:42
void DecrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 336 of file tupdesc.c.

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

Referenced by ATExecAddOf(), cache_record_field_properties(), ExecInitExprRec(), ResourceOwnerReleaseInternal(), TQExamineRecord(), TQRemapRecord(), and transformOfType().

337 {
338  Assert(tupdesc->tdrefcount > 0);
339 
341  if (--tupdesc->tdrefcount == 0)
342  FreeTupleDesc(tupdesc);
343 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
void ResourceOwnerForgetTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition: resowner.c:1117
#define Assert(condition)
Definition: c.h:675
void FreeTupleDesc(TupleDesc tupdesc)
Definition: tupdesc.c:268
int tdrefcount
Definition: tupdesc.h:80
bool equalTupleDescs ( TupleDesc  tupdesc1,
TupleDesc  tupdesc2 
)

Definition at line 354 of file tupdesc.c.

References attrDefault::adbin, attrDefault::adnum, tupleDesc::attrs, constrCheck::ccbin, constrCheck::ccname, constrCheck::ccnoinherit, constrCheck::ccvalid, tupleConstr::check, tupleDesc::constr, tupleConstr::defval, tupleConstr::has_not_null, i, NameStr, tupleDesc::natts, NULL, tupleConstr::num_check, tupleConstr::num_defval, tupleDesc::tdhasoid, and tupleDesc::tdtypeid.

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

355 {
356  int i,
357  j,
358  n;
359 
360  if (tupdesc1->natts != tupdesc2->natts)
361  return false;
362  if (tupdesc1->tdtypeid != tupdesc2->tdtypeid)
363  return false;
364  if (tupdesc1->tdhasoid != tupdesc2->tdhasoid)
365  return false;
366 
367  for (i = 0; i < tupdesc1->natts; i++)
368  {
369  Form_pg_attribute attr1 = tupdesc1->attrs[i];
370  Form_pg_attribute attr2 = tupdesc2->attrs[i];
371 
372  /*
373  * We do not need to check every single field here: we can disregard
374  * attrelid and attnum (which were used to place the row in the attrs
375  * array in the first place). It might look like we could dispense
376  * with checking attlen/attbyval/attalign, since these are derived
377  * from atttypid; but in the case of dropped columns we must check
378  * them (since atttypid will be zero for all dropped columns) and in
379  * general it seems safer to check them always.
380  *
381  * attcacheoff must NOT be checked since it's possibly not set in both
382  * copies.
383  */
384  if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0)
385  return false;
386  if (attr1->atttypid != attr2->atttypid)
387  return false;
388  if (attr1->attstattarget != attr2->attstattarget)
389  return false;
390  if (attr1->attlen != attr2->attlen)
391  return false;
392  if (attr1->attndims != attr2->attndims)
393  return false;
394  if (attr1->atttypmod != attr2->atttypmod)
395  return false;
396  if (attr1->attbyval != attr2->attbyval)
397  return false;
398  if (attr1->attstorage != attr2->attstorage)
399  return false;
400  if (attr1->attalign != attr2->attalign)
401  return false;
402  if (attr1->attnotnull != attr2->attnotnull)
403  return false;
404  if (attr1->atthasdef != attr2->atthasdef)
405  return false;
406  if (attr1->attidentity != attr2->attidentity)
407  return false;
408  if (attr1->attisdropped != attr2->attisdropped)
409  return false;
410  if (attr1->attislocal != attr2->attislocal)
411  return false;
412  if (attr1->attinhcount != attr2->attinhcount)
413  return false;
414  if (attr1->attcollation != attr2->attcollation)
415  return false;
416  /* attacl, attoptions and attfdwoptions are not even present... */
417  }
418 
419  if (tupdesc1->constr != NULL)
420  {
421  TupleConstr *constr1 = tupdesc1->constr;
422  TupleConstr *constr2 = tupdesc2->constr;
423 
424  if (constr2 == NULL)
425  return false;
426  if (constr1->has_not_null != constr2->has_not_null)
427  return false;
428  n = constr1->num_defval;
429  if (n != (int) constr2->num_defval)
430  return false;
431  for (i = 0; i < n; i++)
432  {
433  AttrDefault *defval1 = constr1->defval + i;
434  AttrDefault *defval2 = constr2->defval;
435 
436  /*
437  * We can't assume that the items are always read from the system
438  * catalogs in the same order; so use the adnum field to identify
439  * the matching item to compare.
440  */
441  for (j = 0; j < n; defval2++, j++)
442  {
443  if (defval1->adnum == defval2->adnum)
444  break;
445  }
446  if (j >= n)
447  return false;
448  if (strcmp(defval1->adbin, defval2->adbin) != 0)
449  return false;
450  }
451  n = constr1->num_check;
452  if (n != (int) constr2->num_check)
453  return false;
454  for (i = 0; i < n; i++)
455  {
456  ConstrCheck *check1 = constr1->check + i;
457  ConstrCheck *check2 = constr2->check;
458 
459  /*
460  * Similarly, don't assume that the checks are always read in the
461  * same order; match them up by name and contents. (The name
462  * *should* be unique, but...)
463  */
464  for (j = 0; j < n; check2++, j++)
465  {
466  if (strcmp(check1->ccname, check2->ccname) == 0 &&
467  strcmp(check1->ccbin, check2->ccbin) == 0 &&
468  check1->ccvalid == check2->ccvalid &&
469  check1->ccnoinherit == check2->ccnoinherit)
470  break;
471  }
472  if (j >= n)
473  return false;
474  }
475  }
476  else if (tupdesc2->constr != NULL)
477  return false;
478  return true;
479 }
Oid tdtypeid
Definition: tupdesc.h:77
char * ccname
Definition: tupdesc.h:30
bool tdhasoid
Definition: tupdesc.h:79
bool ccnoinherit
Definition: tupdesc.h:33
ConstrCheck * check
Definition: tupdesc.h:40
char * ccbin
Definition: tupdesc.h:31
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
AttrDefault * defval
Definition: tupdesc.h:39
AttrNumber adnum
Definition: tupdesc.h:24
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
char * adbin
Definition: tupdesc.h:25
bool has_not_null
Definition: tupdesc.h:43
uint16 num_defval
Definition: tupdesc.h:41
#define NULL
Definition: c.h:229
TupleConstr * constr
Definition: tupdesc.h:76
bool ccvalid
Definition: tupdesc.h:32
int i
#define NameStr(name)
Definition: c.h:499
uint16 num_check
Definition: tupdesc.h:42
void FreeTupleDesc ( TupleDesc  tupdesc)

Definition at line 268 of file tupdesc.c.

References Assert, tupleConstr::check, tupleDesc::constr, tupleConstr::defval, i, tupleConstr::num_check, tupleConstr::num_defval, pfree(), and tupleDesc::tdrefcount.

Referenced by AtEOXact_RelationCache(), DecrTupleDescRefCount(), exec_move_row(), exec_stmt_block(), ExecMakeTableFunctionResult(), ExecPrepareTuplestoreResult(), ordered_set_startup(), PLy_result_dealloc(), populate_composite(), RelationDestroyRelation(), RevalidateCachedQuery(), TQExamineRecord(), TQRemapRecord(), TypeCacheRelCallback(), and walrcv_clear_result().

269 {
270  int i;
271 
272  /*
273  * Possibly this should assert tdrefcount == 0, to disallow explicit
274  * freeing of un-refcounted tupdescs?
275  */
276  Assert(tupdesc->tdrefcount <= 0);
277 
278  if (tupdesc->constr)
279  {
280  if (tupdesc->constr->num_defval > 0)
281  {
282  AttrDefault *attrdef = tupdesc->constr->defval;
283 
284  for (i = tupdesc->constr->num_defval - 1; i >= 0; i--)
285  {
286  if (attrdef[i].adbin)
287  pfree(attrdef[i].adbin);
288  }
289  pfree(attrdef);
290  }
291  if (tupdesc->constr->num_check > 0)
292  {
293  ConstrCheck *check = tupdesc->constr->check;
294 
295  for (i = tupdesc->constr->num_check - 1; i >= 0; i--)
296  {
297  if (check[i].ccname)
298  pfree(check[i].ccname);
299  if (check[i].ccbin)
300  pfree(check[i].ccbin);
301  }
302  pfree(check);
303  }
304  pfree(tupdesc->constr);
305  }
306 
307  pfree(tupdesc);
308 }
ConstrCheck * check
Definition: tupdesc.h:40
void pfree(void *pointer)
Definition: mcxt.c:950
AttrDefault * defval
Definition: tupdesc.h:39
uint16 num_defval
Definition: tupdesc.h:41
#define Assert(condition)
Definition: c.h:675
TupleConstr * constr
Definition: tupdesc.h:76
int tdrefcount
Definition: tupdesc.h:80
int i
uint16 num_check
Definition: tupdesc.h:42
void IncrTupleDescRefCount ( TupleDesc  tupdesc)

Definition at line 318 of file tupdesc.c.

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

Referenced by cache_record_field_properties(), lookup_rowtype_tupdesc(), and lookup_rowtype_tupdesc_noerror().

319 {
320  Assert(tupdesc->tdrefcount >= 0);
321 
323  tupdesc->tdrefcount++;
325 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
void ResourceOwnerRememberTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
Definition: resowner.c:1108
void ResourceOwnerEnlargeTupleDescs(ResourceOwner owner)
Definition: resowner.c:1097
#define Assert(condition)
Definition: c.h:675
int tdrefcount
Definition: tupdesc.h:80
void TupleDescCopyEntry ( TupleDesc  dst,
AttrNumber  dstAttno,
TupleDesc  src,
AttrNumber  srcAttno 
)

Definition at line 230 of file tupdesc.c.

References AssertArg, ATTRIBUTE_FIXED_PART_SIZE, tupleDesc::attrs, tupleDesc::natts, and PointerIsValid.

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

232 {
233  /*
234  * sanity checks
235  */
238  AssertArg(srcAttno >= 1);
239  AssertArg(srcAttno <= src->natts);
240  AssertArg(dstAttno >= 1);
241  AssertArg(dstAttno <= dst->natts);
242 
243  memcpy(dst->attrs[dstAttno - 1], src->attrs[srcAttno - 1],
245 
246  /*
247  * Aside from updating the attno, we'd better reset attcacheoff.
248  *
249  * XXX Actually, to be entirely safe we'd need to reset the attcacheoff of
250  * all following columns in dst as well. Current usage scenarios don't
251  * require that though, because all following columns will get initialized
252  * by other uses of this function or TupleDescInitEntry. So we cheat a
253  * bit to avoid a useless O(N^2) penalty.
254  */
255  dst->attrs[dstAttno - 1]->attnum = dstAttno;
256  dst->attrs[dstAttno - 1]->attcacheoff = -1;
257 
258  /* since we're not copying constraints or defaults, clear these */
259  dst->attrs[dstAttno - 1]->attnotnull = false;
260  dst->attrs[dstAttno - 1]->atthasdef = false;
261  dst->attrs[dstAttno - 1]->attidentity = '\0';
262 }
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:179
#define AssertArg(condition)
Definition: c.h:677
#define PointerIsValid(pointer)
Definition: c.h:526
void TupleDescInitBuiltinEntry ( TupleDesc  desc,
AttrNumber  attributeNumber,
const char *  attributeName,
Oid  oidtypeid,
int32  typmod,
int  attdim 
)

Definition at line 568 of file tupdesc.c.

References Assert, AssertArg, tupleDesc::attrs, BOOLOID, DEFAULT_COLLATION_OID, INT4OID, INT8OID, InvalidOid, namestrcpy(), tupleDesc::natts, NULL, PointerIsValid, TEXTARRAYOID, and TEXTOID.

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

574 {
575  Form_pg_attribute att;
576 
577  /* sanity checks */
578  AssertArg(PointerIsValid(desc));
579  AssertArg(attributeNumber >= 1);
580  AssertArg(attributeNumber <= desc->natts);
581 
582  /* initialize the attribute fields */
583  att = desc->attrs[attributeNumber - 1];
584  att->attrelid = 0; /* dummy value */
585 
586  /* unlike TupleDescInitEntry, we require an attribute name */
587  Assert(attributeName != NULL);
588  namestrcpy(&(att->attname), attributeName);
589 
590  att->attstattarget = -1;
591  att->attcacheoff = -1;
592  att->atttypmod = typmod;
593 
594  att->attnum = attributeNumber;
595  att->attndims = attdim;
596 
597  att->attnotnull = false;
598  att->atthasdef = false;
599  att->attidentity = '\0';
600  att->attisdropped = false;
601  att->attislocal = true;
602  att->attinhcount = 0;
603  /* attacl, attoptions and attfdwoptions are not present in tupledescs */
604 
605  att->atttypid = oidtypeid;
606 
607  /*
608  * Our goal here is to support just enough types to let basic builtin
609  * commands work without catalog access - e.g. so that we can do certain
610  * things even in processes that are not connected to a database.
611  */
612  switch (oidtypeid)
613  {
614  case TEXTOID:
615  case TEXTARRAYOID:
616  att->attlen = -1;
617  att->attbyval = false;
618  att->attalign = 'i';
619  att->attstorage = 'x';
620  att->attcollation = DEFAULT_COLLATION_OID;
621  break;
622 
623  case BOOLOID:
624  att->attlen = 1;
625  att->attbyval = true;
626  att->attalign = 'c';
627  att->attstorage = 'p';
628  att->attcollation = InvalidOid;
629  break;
630 
631  case INT4OID:
632  att->attlen = 4;
633  att->attbyval = true;
634  att->attalign = 'i';
635  att->attstorage = 'p';
636  att->attcollation = InvalidOid;
637  break;
638 
639  case INT8OID:
640  att->attlen = 8;
641  att->attbyval = FLOAT8PASSBYVAL;
642  att->attalign = 'd';
643  att->attstorage = 'p';
644  att->attcollation = InvalidOid;
645  break;
646  }
647 }
#define TEXTOID
Definition: pg_type.h:324
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define INT4OID
Definition: pg_type.h:316
int namestrcpy(Name name, const char *str)
Definition: name.c:217
int natts
Definition: tupdesc.h:73
#define TEXTARRAYOID
Definition: pg_type.h:470
#define DEFAULT_COLLATION_OID
Definition: pg_collation.h:75
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define AssertArg(condition)
Definition: c.h:677
#define InvalidOid
Definition: postgres_ext.h:36
#define INT8OID
Definition: pg_type.h:304
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define BOOLOID
Definition: pg_type.h:288
#define PointerIsValid(pointer)
Definition: c.h:526
void TupleDescInitEntry ( TupleDesc  desc,
AttrNumber  attributeNumber,
const char *  attributeName,
Oid  oidtypeid,
int32  typmod,
int  attdim 
)

Definition at line 497 of file tupdesc.c.

References AssertArg, tupleDesc::attrs, elog, ERROR, GETSTRUCT, HeapTupleIsValid, MemSet, NAMEDATALEN, NameStr, namestrcpy(), tupleDesc::natts, NULL, ObjectIdGetDatum, PointerIsValid, ReleaseSysCache(), SearchSysCache1, 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(), 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(), ts_setup_firstcall(), tsvector_unnest(), tt_setup_firstcall(), and TypeGetTupleDesc().

503 {
504  HeapTuple tuple;
505  Form_pg_type typeForm;
506  Form_pg_attribute att;
507 
508  /*
509  * sanity checks
510  */
511  AssertArg(PointerIsValid(desc));
512  AssertArg(attributeNumber >= 1);
513  AssertArg(attributeNumber <= desc->natts);
514 
515  /*
516  * initialize the attribute fields
517  */
518  att = desc->attrs[attributeNumber - 1];
519 
520  att->attrelid = 0; /* dummy value */
521 
522  /*
523  * Note: attributeName can be NULL, because the planner doesn't always
524  * fill in valid resname values in targetlists, particularly for resjunk
525  * attributes. Also, do nothing if caller wants to re-use the old attname.
526  */
527  if (attributeName == NULL)
528  MemSet(NameStr(att->attname), 0, NAMEDATALEN);
529  else if (attributeName != NameStr(att->attname))
530  namestrcpy(&(att->attname), attributeName);
531 
532  att->attstattarget = -1;
533  att->attcacheoff = -1;
534  att->atttypmod = typmod;
535 
536  att->attnum = attributeNumber;
537  att->attndims = attdim;
538 
539  att->attnotnull = false;
540  att->atthasdef = false;
541  att->attidentity = '\0';
542  att->attisdropped = false;
543  att->attislocal = true;
544  att->attinhcount = 0;
545  /* attacl, attoptions and attfdwoptions are not present in tupledescs */
546 
547  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(oidtypeid));
548  if (!HeapTupleIsValid(tuple))
549  elog(ERROR, "cache lookup failed for type %u", oidtypeid);
550  typeForm = (Form_pg_type) GETSTRUCT(tuple);
551 
552  att->atttypid = oidtypeid;
553  att->attlen = typeForm->typlen;
554  att->attbyval = typeForm->typbyval;
555  att->attalign = typeForm->typalign;
556  att->attstorage = typeForm->typstorage;
557  att->attcollation = typeForm->typcollation;
558 
559  ReleaseSysCache(tuple);
560 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
Form_pg_attribute * attrs
Definition: tupdesc.h:74
#define MemSet(start, val, len)
Definition: c.h:857
FormData_pg_type * Form_pg_type
Definition: pg_type.h:233
int namestrcpy(Name name, const char *str)
Definition: name.c:217
int natts
Definition: tupdesc.h:73
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
#define NAMEDATALEN
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define AssertArg(condition)
Definition: c.h:677
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define NameStr(name)
Definition: c.h:499
#define elog
Definition: elog.h:219
#define PointerIsValid(pointer)
Definition: c.h:526
void TupleDescInitEntryCollation ( TupleDesc  desc,
AttrNumber  attributeNumber,
Oid  collationid 
)

Definition at line 656 of file tupdesc.c.

References AssertArg, tupleDesc::attrs, tupleDesc::natts, and PointerIsValid.

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

659 {
660  /*
661  * sanity checks
662  */
663  AssertArg(PointerIsValid(desc));
664  AssertArg(attributeNumber >= 1);
665  AssertArg(attributeNumber <= desc->natts);
666 
667  desc->attrs[attributeNumber - 1]->attcollation = collationid;
668 }
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
#define AssertArg(condition)
Definition: c.h:677
#define PointerIsValid(pointer)
Definition: c.h:526