*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.123 2008/11/02 01:45:26 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.124 2008/11/14 01:57:41 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
result->t_len = len;
return result;
}
-
-
-/* ----------------
- * heap_addheader
- *
- * This routine forms a HeapTuple by copying the given structure (tuple
- * data) and adding a generic header. Note that the tuple data is
- * presumed to contain no null fields and no varlena fields.
- *
- * This routine is really only useful for certain system tables that are
- * known to be fixed-width and null-free. Currently it is only used for
- * pg_attribute tuples.
- * ----------------
- */
-HeapTuple
-heap_addheader(int natts, /* max domain index */
- bool withoid, /* reserve space for oid */
- Size structlen, /* its length */
- void *structure) /* pointer to the struct */
-{
- HeapTuple tuple;
- HeapTupleHeader td;
- Size len;
- int hoff;
-
- AssertArg(natts > 0);
-
- /* header needs no null bitmap */
- hoff = offsetof(HeapTupleHeaderData, t_bits);
- if (withoid)
- hoff += sizeof(Oid);
- hoff = MAXALIGN(hoff);
- len = hoff + structlen;
-
- tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
- tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
-
- tuple->t_len = len;
- ItemPointerSetInvalid(&(tuple->t_self));
- tuple->t_tableOid = InvalidOid;
-
- /* we don't bother to fill the Datum fields */
-
- HeapTupleHeaderSetNatts(td, natts);
- td->t_hoff = hoff;
-
- if (withoid) /* else leave infomask = 0 */
- td->t_infomask = HEAP_HASOID;
-
- memcpy((char *) td + hoff, structure, structlen);
-
- return tuple;
-}
*
*
* 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
}
}
+/*
+ * 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
*
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;
* 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++;
}
/*
*/
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);
}
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.308 2008/11/13 17:42:10 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.309 2008/11/14 01:57:41 alvherre Exp $
*
*
* INTERFACE ROUTINES
Relation pg_attribute;
CatalogIndexState indstate;
TupleDesc indexTupDesc;
- HeapTuple new_tuple;
int i;
/*
Assert(indexTupDesc->attrs[i]->attnum == i + 1);
Assert(indexTupDesc->attrs[i]->attcacheoff == -1);
- new_tuple = heap_addheader(Natts_pg_attribute,
- false,
- ATTRIBUTE_TUPLE_SIZE,
- (void *) indexTupDesc->attrs[i]);
-
- simple_heap_insert(pg_attribute, new_tuple);
-
- CatalogIndexInsert(indstate, new_tuple);
-
- heap_freetuple(new_tuple);
+ InsertPgAttributeTuple(pg_attribute, indexTupDesc->attrs[i], indstate);
}
CatalogCloseIndexes(indstate);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.269 2008/11/02 01:45:27 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.270 2008/11/14 01:57:41 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
Relation pgclass,
attrdesc;
HeapTuple reltup;
- HeapTuple attributeTuple;
- Form_pg_attribute attribute;
- FormData_pg_attribute attributeD;
+ FormData_pg_attribute attribute;
int i;
int minattnum,
maxatts;
/* make sure datatype is legal for a column */
CheckAttributeType(colDef->colname, typeOid);
- attributeTuple = heap_addheader(Natts_pg_attribute,
- false,
- ATTRIBUTE_TUPLE_SIZE,
- (void *) &attributeD);
-
- attribute = (Form_pg_attribute) GETSTRUCT(attributeTuple);
-
- attribute->attrelid = myrelid;
- namestrcpy(&(attribute->attname), colDef->colname);
- attribute->atttypid = typeOid;
- attribute->attstattarget = -1;
- attribute->attlen = tform->typlen;
- attribute->attcacheoff = -1;
- attribute->atttypmod = typmod;
- attribute->attnum = i;
- attribute->attbyval = tform->typbyval;
- attribute->attndims = list_length(colDef->typename->arrayBounds);
- attribute->attstorage = tform->typstorage;
- attribute->attalign = tform->typalign;
- attribute->attnotnull = colDef->is_not_null;
- attribute->atthasdef = false;
- attribute->attisdropped = false;
- attribute->attislocal = colDef->is_local;
- attribute->attinhcount = colDef->inhcount;
+ attribute.attrelid = myrelid;
+ namestrcpy(&(attribute.attname), colDef->colname);
+ attribute.atttypid = typeOid;
+ attribute.attstattarget = -1;
+ attribute.attlen = tform->typlen;
+ attribute.attcacheoff = -1;
+ attribute.atttypmod = typmod;
+ attribute.attnum = i;
+ attribute.attbyval = tform->typbyval;
+ attribute.attndims = list_length(colDef->typename->arrayBounds);
+ attribute.attstorage = tform->typstorage;
+ attribute.attalign = tform->typalign;
+ attribute.attnotnull = colDef->is_not_null;
+ attribute.atthasdef = false;
+ attribute.attisdropped = false;
+ attribute.attislocal = colDef->is_local;
+ attribute.attinhcount = colDef->inhcount;
ReleaseSysCache(typeTuple);
- simple_heap_insert(attrdesc, attributeTuple);
-
- /* Update indexes on pg_attribute */
- CatalogUpdateIndexes(attrdesc, attributeTuple);
+ InsertPgAttributeTuple(attrdesc, &attribute, NULL);
heap_close(attrdesc, RowExclusiveLock);
RawColumnDefault *rawEnt;
rawEnt = (RawColumnDefault *) palloc(sizeof(RawColumnDefault));
- rawEnt->attnum = attribute->attnum;
+ rawEnt->attnum = attribute.attnum;
rawEnt->raw_default = copyObject(colDef->raw_default);
/*
* returned by AddRelationNewConstraints, so that the right thing happens
* when a datatype's default applies.
*/
- defval = (Expr *) build_column_default(rel, attribute->attnum);
+ defval = (Expr *) build_column_default(rel, attribute.attnum);
if (!defval && GetDomainConstraints(typeOid) != NIL)
{
NewColumnValue *newval;
newval = (NewColumnValue *) palloc0(sizeof(NewColumnValue));
- newval->attnum = attribute->attnum;
+ newval->attnum = attribute.attnum;
newval->expr = defval;
tab->newvals = lappend(tab->newvals, newval);
/*
* Add needed dependency entries for the new column.
*/
- add_column_datatype_dependency(myrelid, i, attribute->atttypid);
+ add_column_datatype_dependency(myrelid, i, attribute.atttypid);
}
/*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/htup.h,v 1.103 2008/11/02 01:45:28 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/htup.h,v 1.104 2008/11/14 01:57:42 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup);
extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup);
extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup);
-extern HeapTuple heap_addheader(int natts, bool withoid,
- Size structlen, void *structure);
#endif /* HTUP_H */
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.88 2008/05/09 23:32:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.89 2008/11/14 01:57:42 alvherre Exp $
*
*-------------------------------------------------------------------------
*/
#define HEAP_H
#include "parser/parse_node.h"
+#include "catalog/indexing.h"
typedef struct RawColumnDefault
extern List *heap_truncate_find_FKs(List *relationIds);
+extern void InsertPgAttributeTuple(Relation pg_attribute_rel,
+ Form_pg_attribute new_attribute,
+ CatalogIndexState indstate);
+
extern void InsertPgClassTuple(Relation pg_class_desc,
Relation new_rel_desc,
Oid new_rel_oid,