📄 tupdesc.c
字号:
/*------------------------------------------------------------------------- * * tupdesc.c * POSTGRES tuple descriptor support code * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.100 2003/09/25 06:57:56 petere Exp $ * * NOTES * some of the executor utility code such as "ExecTypeFromTL" should be * moved here. * *------------------------------------------------------------------------- */#include "postgres.h"#include "funcapi.h"#include "access/heapam.h"#include "catalog/namespace.h"#include "catalog/pg_type.h"#include "nodes/parsenodes.h"#include "parser/parse_type.h"#include "utils/builtins.h"#include "utils/lsyscache.h"#include "utils/syscache.h"/* ---------------------------------------------------------------- * CreateTemplateTupleDesc * * This function allocates and zeros a tuple descriptor structure. * ---------------------------------------------------------------- */TupleDescCreateTemplateTupleDesc(int natts, bool hasoid){ TupleDesc desc; /* * sanity checks */ AssertArg(natts >= 0); /* * allocate enough memory for the tuple descriptor and zero it as * TupleDescInitEntry assumes that the descriptor is filled with NULL * pointers. */ desc = (TupleDesc) palloc(sizeof(struct tupleDesc)); desc->natts = natts; desc->tdhasoid = hasoid; if (natts > 0) { uint32 size = natts * sizeof(Form_pg_attribute); desc->attrs = (Form_pg_attribute *) palloc0(size); } else desc->attrs = NULL; desc->constr = NULL; return desc;}/* ---------------------------------------------------------------- * CreateTupleDesc * * This function allocates a new TupleDesc pointing to a given * Form_pg_attribute array * ---------------------------------------------------------------- */TupleDescCreateTupleDesc(int natts, bool hasoid, Form_pg_attribute *attrs){ TupleDesc desc; /* * sanity checks */ AssertArg(natts >= 0); desc = (TupleDesc) palloc(sizeof(struct tupleDesc)); desc->attrs = attrs; desc->natts = natts; desc->constr = NULL; desc->tdhasoid = hasoid; return desc;}/* ---------------------------------------------------------------- * CreateTupleDescCopy * * This function creates a new TupleDesc by copying from an existing * TupleDesc * * !!! Constraints are not copied !!! * ---------------------------------------------------------------- */TupleDescCreateTupleDescCopy(TupleDesc tupdesc){ TupleDesc desc; int i, size; desc = (TupleDesc) palloc(sizeof(struct tupleDesc)); desc->natts = tupdesc->natts; if (desc->natts > 0) { size = desc->natts * sizeof(Form_pg_attribute); desc->attrs = (Form_pg_attribute *) palloc(size); for (i = 0; i < desc->natts; i++) { desc->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE); memcpy(desc->attrs[i], tupdesc->attrs[i], ATTRIBUTE_TUPLE_SIZE); desc->attrs[i]->attnotnull = false; desc->attrs[i]->atthasdef = false; } } else desc->attrs = NULL; desc->constr = NULL; desc->tdhasoid = tupdesc->tdhasoid; return desc;}/* ---------------------------------------------------------------- * CreateTupleDescCopyConstr * * This function creates a new TupleDesc by copying from an existing * TupleDesc (with Constraints) * ---------------------------------------------------------------- */TupleDescCreateTupleDescCopyConstr(TupleDesc tupdesc){ TupleDesc desc; TupleConstr *constr = tupdesc->constr; int i, size; desc = (TupleDesc) palloc(sizeof(struct tupleDesc)); desc->natts = tupdesc->natts; if (desc->natts > 0) { size = desc->natts * sizeof(Form_pg_attribute); desc->attrs = (Form_pg_attribute *) palloc(size); for (i = 0; i < desc->natts; i++) { desc->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE); memcpy(desc->attrs[i], tupdesc->attrs[i], ATTRIBUTE_TUPLE_SIZE); } } else desc->attrs = NULL; if (constr) { TupleConstr *cpy = (TupleConstr *) palloc(sizeof(TupleConstr)); cpy->has_not_null = constr->has_not_null; if ((cpy->num_defval = constr->num_defval) > 0) { cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault)); memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault)); for (i = cpy->num_defval - 1; i >= 0; i--) { if (constr->defval[i].adbin) cpy->defval[i].adbin = pstrdup(constr->defval[i].adbin); } } if ((cpy->num_check = constr->num_check) > 0) { cpy->check = (ConstrCheck *) palloc(cpy->num_check * sizeof(ConstrCheck)); memcpy(cpy->check, constr->check, cpy->num_check * sizeof(ConstrCheck)); for (i = cpy->num_check - 1; i >= 0; i--) { if (constr->check[i].ccname) cpy->check[i].ccname = pstrdup(constr->check[i].ccname); if (constr->check[i].ccbin) cpy->check[i].ccbin = pstrdup(constr->check[i].ccbin); } } desc->constr = cpy; } else desc->constr = NULL; desc->tdhasoid = tupdesc->tdhasoid; return desc;}voidFreeTupleDesc(TupleDesc tupdesc){ int i; for (i = 0; i < tupdesc->natts; i++) pfree(tupdesc->attrs[i]); if (tupdesc->attrs) pfree(tupdesc->attrs); if (tupdesc->constr) { if (tupdesc->constr->num_defval > 0) { AttrDefault *attrdef = tupdesc->constr->defval; for (i = tupdesc->constr->num_defval - 1; i >= 0; i--) { if (attrdef[i].adbin) pfree(attrdef[i].adbin); } pfree(attrdef); } if (tupdesc->constr->num_check > 0) { ConstrCheck *check = tupdesc->constr->check; for (i = tupdesc->constr->num_check - 1; i >= 0; i--) { if (check[i].ccname) pfree(check[i].ccname); if (check[i].ccbin) pfree(check[i].ccbin); } pfree(check); } pfree(tupdesc->constr); } pfree(tupdesc);}/* * Compare two TupleDesc structures for logical equality */boolequalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2){ int i, j, n; if (tupdesc1->natts != tupdesc2->natts) return false; if (tupdesc1->tdhasoid != tupdesc2->tdhasoid) return false; for (i = 0; i < tupdesc1->natts; i++) { Form_pg_attribute attr1 = tupdesc1->attrs[i]; Form_pg_attribute attr2 = tupdesc2->attrs[i]; /* * We do not need to check every single field here: we can * disregard attrelid, attnum (it was used to place the row in the * attrs array) and everything derived from the column datatype. */ if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0) return false; if (attr1->atttypid != attr2->atttypid) return false; if (attr1->attstattarget != attr2->attstattarget) return false; if (attr1->atttypmod != attr2->atttypmod) return false; if (attr1->attstorage != attr2->attstorage) return false; if (attr1->attnotnull != attr2->attnotnull) return false; if (attr1->atthasdef != attr2->atthasdef) return false; if (attr1->attisdropped != attr2->attisdropped) return false; if (attr1->attislocal != attr2->attislocal) return false; if (attr1->attinhcount != attr2->attinhcount) return false; } if (tupdesc1->constr != NULL) { TupleConstr *constr1 = tupdesc1->constr; TupleConstr *constr2 = tupdesc2->constr; if (constr2 == NULL) return false; if (constr1->has_not_null != constr2->has_not_null) return false; n = constr1->num_defval; if (n != (int) constr2->num_defval) return false; for (i = 0; i < n; i++) { AttrDefault *defval1 = constr1->defval + i; AttrDefault *defval2 = constr2->defval; /* * We can't assume that the items are always read from the * system catalogs in the same order; so use the adnum field * to identify the matching item to compare. */ for (j = 0; j < n; defval2++, j++) { if (defval1->adnum == defval2->adnum) break; } if (j >= n) return false; if (strcmp(defval1->adbin, defval2->adbin) != 0) return false; } n = constr1->num_check; if (n != (int) constr2->num_check) return false; for (i = 0; i < n; i++) { ConstrCheck *check1 = constr1->check + i; ConstrCheck *check2 = constr2->check; /* * Similarly, don't assume that the checks are always read in * the same order; match them up by name and contents. (The * name *should* be unique, but...) */ for (j = 0; j < n; check2++, j++) { if (strcmp(check1->ccname, check2->ccname) == 0 && strcmp(check1->ccbin, check2->ccbin) == 0) break; } if (j >= n) return false; } } else if (tupdesc2->constr != NULL) return false; return true;}/* ---------------------------------------------------------------- * TupleDescInitEntry * * This function initializes a single attribute structure in * a preallocated tuple descriptor. * ---------------------------------------------------------------- */void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -