aboutsummaryrefslogtreecommitdiff
path: root/src/backend/catalog/heap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/catalog/heap.c')
-rw-r--r--src/backend/catalog/heap.c130
1 files changed, 79 insertions, 51 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index ad0dca13e1b..bb5b263ee63 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.343 2008/11/09 21:24:32 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.344 2008/11/14 01:57:41 alvherre Exp $
*
*
* INTERFACE ROUTINES
@@ -478,6 +478,60 @@ CheckAttributeType(const char *attname, Oid atttypid)
}
}
+/*
+ * InsertPgAttributeTuple
+ * Construct and insert a new tuple in pg_attribute.
+ *
+ * Caller has already opened and locked pg_attribute. new_attribute is the
+ * attribute to insert.
+ *
+ * indstate is the index state for CatalogIndexInsert. It can be passed as
+ * NULL, in which case we'll fetch the necessary info. (Don't do this when
+ * inserting multiple attributes, because it's a tad more expensive.)
+ */
+void
+InsertPgAttributeTuple(Relation pg_attribute_rel,
+ Form_pg_attribute new_attribute,
+ CatalogIndexState indstate)
+{
+ Datum values[Natts_pg_attribute];
+ bool nulls[Natts_pg_attribute];
+ HeapTuple tup;
+
+ /* This is a tad tedious, but way cleaner than what we used to do... */
+ memset(values, 0, sizeof(values));
+ memset(nulls, false, sizeof(nulls));
+
+ values[Anum_pg_attribute_attrelid - 1] = ObjectIdGetDatum(new_attribute->attrelid);
+ values[Anum_pg_attribute_attname - 1] = NameGetDatum(&new_attribute->attname);
+ values[Anum_pg_attribute_atttypid - 1] = ObjectIdGetDatum(new_attribute->atttypid);
+ values[Anum_pg_attribute_attstattarget - 1] = Int32GetDatum(new_attribute->attstattarget);
+ values[Anum_pg_attribute_attlen - 1] = Int16GetDatum(new_attribute->attlen);
+ values[Anum_pg_attribute_attnum - 1] = Int16GetDatum(new_attribute->attnum);
+ values[Anum_pg_attribute_attndims - 1] = Int32GetDatum(new_attribute->attndims);
+ values[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(new_attribute->attcacheoff);
+ values[Anum_pg_attribute_atttypmod - 1] = Int32GetDatum(new_attribute->atttypmod);
+ values[Anum_pg_attribute_attbyval - 1] = BoolGetDatum(new_attribute->attbyval);
+ values[Anum_pg_attribute_attstorage - 1] = CharGetDatum(new_attribute->attstorage);
+ values[Anum_pg_attribute_attalign - 1] = CharGetDatum(new_attribute->attalign);
+ values[Anum_pg_attribute_attnotnull - 1] = BoolGetDatum(new_attribute->attnotnull);
+ values[Anum_pg_attribute_atthasdef - 1] = BoolGetDatum(new_attribute->atthasdef);
+ values[Anum_pg_attribute_attisdropped - 1] = BoolGetDatum(new_attribute->attisdropped);
+ values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(new_attribute->attislocal);
+ values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(new_attribute->attinhcount);
+
+ tup = heap_form_tuple(RelationGetDescr(pg_attribute_rel), values, nulls);
+
+ /* finally insert the new tuple, update the indexes, and clean up */
+ simple_heap_insert(pg_attribute_rel, tup);
+
+ if (indstate != NULL)
+ CatalogIndexInsert(indstate, tup);
+ else
+ CatalogUpdateIndexes(pg_attribute_rel, tup);
+
+ heap_freetuple(tup);
+}
/* --------------------------------
* AddNewAttributeTuples
*
@@ -492,9 +546,8 @@ AddNewAttributeTuples(Oid new_rel_oid,
bool oidislocal,
int oidinhcount)
{
- const Form_pg_attribute *dpp;
+ Form_pg_attribute attr;
int i;
- HeapTuple tup;
Relation rel;
CatalogIndexState indstate;
int natts = tupdesc->natts;
@@ -512,35 +565,25 @@ AddNewAttributeTuples(Oid new_rel_oid,
* First we add the user attributes. This is also a convenient place to
* add dependencies on their datatypes.
*/
- dpp = tupdesc->attrs;
for (i = 0; i < natts; i++)
{
+ attr = tupdesc->attrs[i];
/* Fill in the correct relation OID */
- (*dpp)->attrelid = new_rel_oid;
+ attr->attrelid = new_rel_oid;
/* Make sure these are OK, too */
- (*dpp)->attstattarget = -1;
- (*dpp)->attcacheoff = -1;
-
- tup = heap_addheader(Natts_pg_attribute,
- false,
- ATTRIBUTE_TUPLE_SIZE,
- (void *) *dpp);
-
- simple_heap_insert(rel, tup);
-
- CatalogIndexInsert(indstate, tup);
+ attr->attstattarget = -1;
+ attr->attcacheoff = -1;
- heap_freetuple(tup);
+ InsertPgAttributeTuple(rel, attr, indstate);
+ /* Add dependency info */
myself.classId = RelationRelationId;
myself.objectId = new_rel_oid;
myself.objectSubId = i + 1;
referenced.classId = TypeRelationId;
- referenced.objectId = (*dpp)->atttypid;
+ referenced.objectId = attr->atttypid;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
-
- dpp++;
}
/*
@@ -550,43 +593,28 @@ AddNewAttributeTuples(Oid new_rel_oid,
*/
if (relkind != RELKIND_VIEW && relkind != RELKIND_COMPOSITE_TYPE)
{
- dpp = SysAtt;
- for (i = 0; i < (int) lengthof(SysAtt); i++, dpp++)
+ for (i = 0; i < (int) lengthof(SysAtt); i++)
{
- if (tupdesc->tdhasoid ||
- (*dpp)->attnum != ObjectIdAttributeNumber)
- {
- Form_pg_attribute attStruct;
-
- tup = heap_addheader(Natts_pg_attribute,
- false,
- ATTRIBUTE_TUPLE_SIZE,
- (void *) *dpp);
- attStruct = (Form_pg_attribute) GETSTRUCT(tup);
-
- /* Fill in the correct relation OID in the copied tuple */
- attStruct->attrelid = new_rel_oid;
+ FormData_pg_attribute attStruct;
- /* Fill in correct inheritance info for the OID column */
- if (attStruct->attnum == ObjectIdAttributeNumber)
- {
- attStruct->attislocal = oidislocal;
- attStruct->attinhcount = oidinhcount;
- }
-
- /*
- * Unneeded since they should be OK in the constant data
- * anyway
- */
- /* attStruct->attstattarget = 0; */
- /* attStruct->attcacheoff = -1; */
+ /* skip OID where appropriate */
+ if (!tupdesc->tdhasoid &&
+ SysAtt[i]->attnum == ObjectIdAttributeNumber)
+ continue;
- simple_heap_insert(rel, tup);
+ memcpy(&attStruct, (char *) SysAtt[i], sizeof(FormData_pg_attribute));
- CatalogIndexInsert(indstate, tup);
+ /* Fill in the correct relation OID in the copied tuple */
+ attStruct.attrelid = new_rel_oid;
- heap_freetuple(tup);
+ /* Fill in correct inheritance info for the OID column */
+ if (attStruct.attnum == ObjectIdAttributeNumber)
+ {
+ attStruct.attislocal = oidislocal;
+ attStruct.attinhcount = oidinhcount;
}
+
+ InsertPgAttributeTuple(rel, &attStruct, indstate);
}
}