PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
tupdesc.h File Reference
#include "access/attnum.h"
#include "catalog/pg_attribute.h"
#include "nodes/pg_list.h"
Include dependency graph for tupdesc.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  attrDefault
 
struct  constrCheck
 
struct  tupleConstr
 
struct  tupleDesc
 

Macros

#define PinTupleDesc(tupdesc)
 
#define ReleaseTupleDesc(tupdesc)
 

Typedefs

typedef struct attrDefault AttrDefault
 
typedef struct constrCheck ConstrCheck
 
typedef struct tupleConstr TupleConstr
 
typedef struct tupleDescTupleDesc
 

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)
 

Macro Definition Documentation

#define PinTupleDesc (   tupdesc)
Value:
do { \
if ((tupdesc)->tdrefcount >= 0) \
} while (0)
void IncrTupleDescRefCount(TupleDesc tupdesc)
Definition: tupdesc.c:316

Definition at line 101 of file tupdesc.h.

Referenced by ExecSetSlotDescriptor().

Typedef Documentation

Function Documentation

TupleDesc BuildDescForRelation ( List schema)

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

676 {
677  int natts;
678  AttrNumber attnum;
679  ListCell *l;
680  TupleDesc desc;
681  bool has_not_null;
682  char *attname;
683  Oid atttypid;
684  int32 atttypmod;
685  Oid attcollation;
686  int attdim;
687 
688  /*
689  * allocate a new tuple descriptor
690  */
691  natts = list_length(schema);
692  desc = CreateTemplateTupleDesc(natts, false);
693  has_not_null = false;
694 
695  attnum = 0;
696 
697  foreach(l, schema)
698  {
699  ColumnDef *entry = lfirst(l);
700  AclResult aclresult;
701 
702  /*
703  * for each entry in the list, get the name and type information from
704  * the list and have TupleDescInitEntry fill in the attribute
705  * information we need.
706  */
707  attnum++;
708 
709  attname = entry->colname;
710  typenameTypeIdAndMod(NULL, entry->typeName, &atttypid, &atttypmod);
711 
712  aclresult = pg_type_aclcheck(atttypid, GetUserId(), ACL_USAGE);
713  if (aclresult != ACLCHECK_OK)
714  aclcheck_error_type(aclresult, atttypid);
715 
716  attcollation = GetColumnDefCollation(NULL, entry, atttypid);
717  attdim = list_length(entry->typeName->arrayBounds);
718 
719  if (entry->typeName->setof)
720  ereport(ERROR,
721  (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
722  errmsg("column \"%s\" cannot be declared SETOF",
723  attname)));
724 
725  TupleDescInitEntry(desc, attnum, attname,
726  atttypid, atttypmod, attdim);
727 
728  /* Override TupleDescInitEntry's settings as requested */
729  TupleDescInitEntryCollation(desc, attnum, attcollation);
730  if (entry->storage)
731  desc->attrs[attnum - 1]->attstorage = entry->storage;
732 
733  /* Fill in additional stuff not handled by TupleDescInitEntry */
734  desc->attrs[attnum - 1]->attnotnull = entry->is_not_null;
735  has_not_null |= entry->is_not_null;
736  desc->attrs[attnum - 1]->attislocal = entry->is_local;
737  desc->attrs[attnum - 1]->attinhcount = entry->inhcount;
738  }
739 
740  if (has_not_null)
741  {
742  TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
743 
744  constr->has_not_null = true;
745  constr->defval = NULL;
746  constr->num_defval = 0;
747  constr->check = NULL;
748  constr->num_check = 0;
749  desc->constr = constr;
750  }
751  else
752  {
753  desc->constr = NULL;
754  }
755 
756  return desc;
757 }
char storage
Definition: parsenodes.h:637
bool is_local
Definition: parsenodes.h:634
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:635
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:202
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:650
#define ACL_USAGE
Definition: parsenodes.h:73
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:493
#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:632
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:41
List * arrayBounds
Definition: parsenodes.h:206
int errmsg(const char *fmt,...)
Definition: elog.c:797
int inhcount
Definition: parsenodes.h:633
uint16 num_check
Definition: tupdesc.h:42
char * colname
Definition: parsenodes.h:631
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 771 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().

772 {
773  int natts;
774  AttrNumber attnum;
775  ListCell *l1;
776  ListCell *l2;
777  ListCell *l3;
778  ListCell *l4;
779  TupleDesc desc;
780 
781  natts = list_length(names);
782  Assert(natts == list_length(types));
783  Assert(natts == list_length(typmods));
784  Assert(natts == list_length(collations));
785 
786  /*
787  * allocate a new tuple descriptor
788  */
789  desc = CreateTemplateTupleDesc(natts, false);
790 
791  attnum = 0;
792 
793  l2 = list_head(types);
794  l3 = list_head(typmods);
795  l4 = list_head(collations);
796  foreach(l1, names)
797  {
798  char *attname = strVal(lfirst(l1));
799  Oid atttypid;
800  int32 atttypmod;
801  Oid attcollation;
802 
803  atttypid = lfirst_oid(l2);
804  l2 = lnext(l2);
805  atttypmod = lfirst_int(l3);
806  l3 = lnext(l3);
807  attcollation = lfirst_oid(l4);
808  l4 = lnext(l4);
809 
810  attnum++;
811 
812  TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);
813  TupleDescInitEntryCollation(desc, attnum, attcollation);
814  }
815 
816  return desc;
817 }
#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:650
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:493
#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:184
#define RECORDOID
Definition: pg_type.h:676
struct tupleDesc * TupleDesc
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:176
#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:676
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_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  }
154 
155  desc->tdtypeid = tupdesc->tdtypeid;
156  desc->tdtypmod = tupdesc->tdtypmod;
157 
158  return desc;
159 }
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:176
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:41
int i
TupleDesc CreateTupleDescCopyConstr ( TupleDesc  tupdesc)

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

168 {
169  TupleDesc desc;
170  TupleConstr *constr = tupdesc->constr;
171  int i;
172 
173  desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid);
174 
175  for (i = 0; i < desc->natts; i++)
176  {
177  memcpy(desc->attrs[i], tupdesc->attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
178  }
179 
180  if (constr)
181  {
182  TupleConstr *cpy = (TupleConstr *) palloc0(sizeof(TupleConstr));
183 
184  cpy->has_not_null = constr->has_not_null;
185 
186  if ((cpy->num_defval = constr->num_defval) > 0)
187  {
188  cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault));
189  memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault));
190  for (i = cpy->num_defval - 1; i >= 0; i--)
191  {
192  if (constr->defval[i].adbin)
193  cpy->defval[i].adbin = pstrdup(constr->defval[i].adbin);
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  if (constr->check[i].ccname)
204  cpy->check[i].ccname = pstrdup(constr->check[i].ccname);
205  if (constr->check[i].ccbin)
206  cpy->check[i].ccbin = pstrdup(constr->check[i].ccbin);
207  cpy->check[i].ccvalid = constr->check[i].ccvalid;
208  cpy->check[i].ccnoinherit = constr->check[i].ccnoinherit;
209  }
210  }
211 
212  desc->constr = cpy;
213  }
214 
215  desc->tdtypeid = tupdesc->tdtypeid;
216  desc->tdtypmod = tupdesc->tdtypmod;
217 
218  return desc;
219 }
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:176
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 334 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().

335 {
336  Assert(tupdesc->tdrefcount > 0);
337 
339  if (--tupdesc->tdrefcount == 0)
340  FreeTupleDesc(tupdesc);
341 }
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:266
int tdrefcount
Definition: tupdesc.h:80
bool equalTupleDescs ( TupleDesc  tupdesc1,
TupleDesc  tupdesc2 
)

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

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

267 {
268  int i;
269 
270  /*
271  * Possibly this should assert tdrefcount == 0, to disallow explicit
272  * freeing of un-refcounted tupdescs?
273  */
274  Assert(tupdesc->tdrefcount <= 0);
275 
276  if (tupdesc->constr)
277  {
278  if (tupdesc->constr->num_defval > 0)
279  {
280  AttrDefault *attrdef = tupdesc->constr->defval;
281 
282  for (i = tupdesc->constr->num_defval - 1; i >= 0; i--)
283  {
284  if (attrdef[i].adbin)
285  pfree(attrdef[i].adbin);
286  }
287  pfree(attrdef);
288  }
289  if (tupdesc->constr->num_check > 0)
290  {
291  ConstrCheck *check = tupdesc->constr->check;
292 
293  for (i = tupdesc->constr->num_check - 1; i >= 0; i--)
294  {
295  if (check[i].ccname)
296  pfree(check[i].ccname);
297  if (check[i].ccbin)
298  pfree(check[i].ccbin);
299  }
300  pfree(check);
301  }
302  pfree(tupdesc->constr);
303  }
304 
305  pfree(tupdesc);
306 }
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 316 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().

317 {
318  Assert(tupdesc->tdrefcount >= 0);
319 
321  tupdesc->tdrefcount++;
323 }
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 229 of file tupdesc.c.

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

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

231 {
232  /*
233  * sanity checks
234  */
237  AssertArg(srcAttno >= 1);
238  AssertArg(srcAttno <= src->natts);
239  AssertArg(dstAttno >= 1);
240  AssertArg(dstAttno <= dst->natts);
241 
242  memcpy(dst->attrs[dstAttno - 1], src->attrs[srcAttno - 1],
244 
245  /*
246  * Aside from updating the attno, we'd better reset attcacheoff.
247  *
248  * XXX Actually, to be entirely safe we'd need to reset the attcacheoff of
249  * all following columns in dst as well. Current usage scenarios don't
250  * require that though, because all following columns will get initialized
251  * by other uses of this function or TupleDescInitEntry. So we cheat a
252  * bit to avoid a useless O(N^2) penalty.
253  */
254  dst->attrs[dstAttno - 1]->attnum = dstAttno;
255  dst->attrs[dstAttno - 1]->attcacheoff = -1;
256 
257  /* since we're not copying constraints or defaults, clear these */
258  dst->attrs[dstAttno - 1]->attnotnull = false;
259  dst->attrs[dstAttno - 1]->atthasdef = false;
260 }
Form_pg_attribute * attrs
Definition: tupdesc.h:74
int natts
Definition: tupdesc.h:73
#define ATTRIBUTE_FIXED_PART_SIZE
Definition: pg_attribute.h:176
#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 563 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().

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

499 {
500  HeapTuple tuple;
501  Form_pg_type typeForm;
502  Form_pg_attribute att;
503 
504  /*
505  * sanity checks
506  */
507  AssertArg(PointerIsValid(desc));
508  AssertArg(attributeNumber >= 1);
509  AssertArg(attributeNumber <= desc->natts);
510 
511  /*
512  * initialize the attribute fields
513  */
514  att = desc->attrs[attributeNumber - 1];
515 
516  att->attrelid = 0; /* dummy value */
517 
518  /*
519  * Note: attributeName can be NULL, because the planner doesn't always
520  * fill in valid resname values in targetlists, particularly for resjunk
521  * attributes. Also, do nothing if caller wants to re-use the old attname.
522  */
523  if (attributeName == NULL)
524  MemSet(NameStr(att->attname), 0, NAMEDATALEN);
525  else if (attributeName != NameStr(att->attname))
526  namestrcpy(&(att->attname), attributeName);
527 
528  att->attstattarget = -1;
529  att->attcacheoff = -1;
530  att->atttypmod = typmod;
531 
532  att->attnum = attributeNumber;
533  att->attndims = attdim;
534 
535  att->attnotnull = false;
536  att->atthasdef = false;
537  att->attisdropped = false;
538  att->attislocal = true;
539  att->attinhcount = 0;
540  /* attacl, attoptions and attfdwoptions are not present in tupledescs */
541 
542  tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(oidtypeid));
543  if (!HeapTupleIsValid(tuple))
544  elog(ERROR, "cache lookup failed for type %u", oidtypeid);
545  typeForm = (Form_pg_type) GETSTRUCT(tuple);
546 
547  att->atttypid = oidtypeid;
548  att->attlen = typeForm->typlen;
549  att->attbyval = typeForm->typbyval;
550  att->attalign = typeForm->typalign;
551  att->attstorage = typeForm->typstorage;
552  att->attcollation = typeForm->typcollation;
553 
554  ReleaseSysCache(tuple);
555 }
#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:152
#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:184
#define AssertArg(condition)
Definition: c.h:677
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1116
#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 650 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().

653 {
654  /*
655  * sanity checks
656  */
657  AssertArg(PointerIsValid(desc));
658  AssertArg(attributeNumber >= 1);
659  AssertArg(attributeNumber <= desc->natts);
660 
661  desc->attrs[attributeNumber - 1]->attcollation = collationid;
662 }
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