mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Rearrange order of operations in heap_create_with_catalog so that if
two transactions create the same table name concurrently, the one that fails will complain about unique index pg_class_relname_index, rather than about pg_type_typname_index which'll confuse most people. Free side benefit: pg_class.reltype is correctly linked to the pg_type entry now. It's been zero in all but the preloaded pg_class entries since who knows when.
This commit is contained in:
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.158 2001/01/24 19:42:51 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.159 2001/02/12 20:07:21 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -68,15 +68,15 @@
|
|||||||
|
|
||||||
|
|
||||||
static void AddNewRelationTuple(Relation pg_class_desc,
|
static void AddNewRelationTuple(Relation pg_class_desc,
|
||||||
Relation new_rel_desc, Oid new_rel_oid,
|
Relation new_rel_desc, Oid new_rel_oid, Oid new_type_oid,
|
||||||
int natts,
|
int natts, char relkind, char *temp_relname);
|
||||||
char relkind, char *temp_relname);
|
|
||||||
static void DeleteAttributeTuples(Relation rel);
|
static void DeleteAttributeTuples(Relation rel);
|
||||||
static void DeleteRelationTuple(Relation rel);
|
static void DeleteRelationTuple(Relation rel);
|
||||||
static void DeleteTypeTuple(Relation rel);
|
static void DeleteTypeTuple(Relation rel);
|
||||||
static void RelationRemoveIndexes(Relation relation);
|
static void RelationRemoveIndexes(Relation relation);
|
||||||
static void RelationRemoveInheritance(Relation relation);
|
static void RelationRemoveInheritance(Relation relation);
|
||||||
static void AddNewRelationType(char *typeName, Oid new_rel_oid);
|
static void AddNewRelationType(char *typeName, Oid new_rel_oid,
|
||||||
|
Oid new_type_oid);
|
||||||
static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
|
static void StoreAttrDefault(Relation rel, AttrNumber attnum, char *adbin,
|
||||||
bool updatePgAttribute);
|
bool updatePgAttribute);
|
||||||
static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
|
static void StoreRelCheck(Relation rel, char *ccname, char *ccbin);
|
||||||
@ -317,6 +317,7 @@ heap_create(char *relname,
|
|||||||
strcpy(RelationGetPhysicalRelationName(rel), relname);
|
strcpy(RelationGetPhysicalRelationName(rel), relname);
|
||||||
rel->rd_rel->relkind = RELKIND_UNCATALOGED;
|
rel->rd_rel->relkind = RELKIND_UNCATALOGED;
|
||||||
rel->rd_rel->relnatts = natts;
|
rel->rd_rel->relnatts = natts;
|
||||||
|
rel->rd_rel->reltype = InvalidOid;
|
||||||
if (tupDesc->constr)
|
if (tupDesc->constr)
|
||||||
rel->rd_rel->relchecks = tupDesc->constr->num_check;
|
rel->rd_rel->relchecks = tupDesc->constr->num_check;
|
||||||
|
|
||||||
@ -325,12 +326,6 @@ heap_create(char *relname,
|
|||||||
|
|
||||||
RelationGetRelid(rel) = relid;
|
RelationGetRelid(rel) = relid;
|
||||||
|
|
||||||
if (nailme)
|
|
||||||
{
|
|
||||||
/* for system relations, set the reltype field here */
|
|
||||||
rel->rd_rel->reltype = relid;
|
|
||||||
}
|
|
||||||
|
|
||||||
rel->rd_node.tblNode = tblNode;
|
rel->rd_node.tblNode = tblNode;
|
||||||
rel->rd_node.relNode = relid;
|
rel->rd_node.relNode = relid;
|
||||||
rel->rd_rel->relfilenode = relid;
|
rel->rd_rel->relfilenode = relid;
|
||||||
@ -373,18 +368,17 @@ heap_storage_create(Relation rel)
|
|||||||
* performs a scan to ensure that no relation with the
|
* performs a scan to ensure that no relation with the
|
||||||
* same name already exists.
|
* same name already exists.
|
||||||
*
|
*
|
||||||
* 3) heap_create_with_catalog() is called to create the new relation
|
* 3) heap_create() is called to create the new relation on disk.
|
||||||
* on disk.
|
|
||||||
*
|
*
|
||||||
* 4) TypeDefine() is called to define a new type corresponding
|
* 4) AddNewRelationTuple() is called to register the
|
||||||
|
* relation in pg_class.
|
||||||
|
*
|
||||||
|
* 5) TypeCreate() is called to define a new type corresponding
|
||||||
* to the new relation.
|
* to the new relation.
|
||||||
*
|
*
|
||||||
* 5) AddNewAttributeTuples() is called to register the
|
* 6) AddNewAttributeTuples() is called to register the
|
||||||
* new relation's schema in pg_attribute.
|
* new relation's schema in pg_attribute.
|
||||||
*
|
*
|
||||||
* 6) AddNewRelationTuple() is called to register the
|
|
||||||
* relation itself in the catalogs.
|
|
||||||
*
|
|
||||||
* 7) StoreConstraints is called () - vadim 08/22/97
|
* 7) StoreConstraints is called () - vadim 08/22/97
|
||||||
*
|
*
|
||||||
* 8) the relations are closed and the new relation's oid
|
* 8) the relations are closed and the new relation's oid
|
||||||
@ -656,6 +650,7 @@ static void
|
|||||||
AddNewRelationTuple(Relation pg_class_desc,
|
AddNewRelationTuple(Relation pg_class_desc,
|
||||||
Relation new_rel_desc,
|
Relation new_rel_desc,
|
||||||
Oid new_rel_oid,
|
Oid new_rel_oid,
|
||||||
|
Oid new_type_oid,
|
||||||
int natts,
|
int natts,
|
||||||
char relkind,
|
char relkind,
|
||||||
char *temp_relname)
|
char *temp_relname)
|
||||||
@ -665,7 +660,7 @@ AddNewRelationTuple(Relation pg_class_desc,
|
|||||||
Relation idescs[Num_pg_class_indices];
|
Relation idescs[Num_pg_class_indices];
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* first we munge some of the information in our
|
* first we update some of the information in our
|
||||||
* uncataloged relation's relation descriptor.
|
* uncataloged relation's relation descriptor.
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
@ -694,6 +689,7 @@ AddNewRelationTuple(Relation pg_class_desc,
|
|||||||
new_rel_reltup->reltuples = 1000;
|
new_rel_reltup->reltuples = 1000;
|
||||||
|
|
||||||
new_rel_reltup->relowner = GetUserId();
|
new_rel_reltup->relowner = GetUserId();
|
||||||
|
new_rel_reltup->reltype = new_type_oid;
|
||||||
new_rel_reltup->relkind = relkind;
|
new_rel_reltup->relkind = relkind;
|
||||||
new_rel_reltup->relnatts = natts;
|
new_rel_reltup->relnatts = natts;
|
||||||
|
|
||||||
@ -705,6 +701,8 @@ AddNewRelationTuple(Relation pg_class_desc,
|
|||||||
tup = heap_addheader(Natts_pg_class_fixed,
|
tup = heap_addheader(Natts_pg_class_fixed,
|
||||||
CLASS_TUPLE_SIZE,
|
CLASS_TUPLE_SIZE,
|
||||||
(char *) new_rel_reltup);
|
(char *) new_rel_reltup);
|
||||||
|
|
||||||
|
/* force tuple to have the desired OID */
|
||||||
tup->t_data->t_oid = new_rel_oid;
|
tup->t_data->t_oid = new_rel_oid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -738,10 +736,8 @@ AddNewRelationTuple(Relation pg_class_desc,
|
|||||||
* --------------------------------
|
* --------------------------------
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
AddNewRelationType(char *typeName, Oid new_rel_oid)
|
AddNewRelationType(char *typeName, Oid new_rel_oid, Oid new_type_oid)
|
||||||
{
|
{
|
||||||
Oid new_type_oid;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The sizes are set to oid size because it makes implementing sets
|
* The sizes are set to oid size because it makes implementing sets
|
||||||
* MUCH easier, and no one (we hope) uses these fields to figure out
|
* MUCH easier, and no one (we hope) uses these fields to figure out
|
||||||
@ -750,9 +746,11 @@ AddNewRelationType(char *typeName, Oid new_rel_oid)
|
|||||||
* actually get is the oid of a tuple in the pg_proc catalog, so the
|
* actually get is the oid of a tuple in the pg_proc catalog, so the
|
||||||
* size of the "set" is the size of an oid. Similarly, byval being
|
* size of the "set" is the size of an oid. Similarly, byval being
|
||||||
* true makes sets much easier, and it isn't used by anything else.
|
* true makes sets much easier, and it isn't used by anything else.
|
||||||
* Note the assumption that OIDs are the same size as int4s.
|
*
|
||||||
|
* XXX Note the assumption that OIDs are the same size as int4s.
|
||||||
*/
|
*/
|
||||||
new_type_oid = TypeCreate(typeName, /* type name */
|
TypeCreate(typeName, /* type name */
|
||||||
|
new_type_oid, /* preassigned oid for type */
|
||||||
new_rel_oid, /* relation oid */
|
new_rel_oid, /* relation oid */
|
||||||
sizeof(Oid), /* internal size */
|
sizeof(Oid), /* internal size */
|
||||||
sizeof(Oid), /* external size */
|
sizeof(Oid), /* external size */
|
||||||
@ -762,9 +760,9 @@ AddNewRelationType(char *typeName, Oid new_rel_oid)
|
|||||||
"int4out", /* output procedure */
|
"int4out", /* output procedure */
|
||||||
"int4in", /* receive procedure */
|
"int4in", /* receive procedure */
|
||||||
"int4out", /* send procedure */
|
"int4out", /* send procedure */
|
||||||
NULL, /* array element type - irrelevent */
|
NULL, /* array element type - irrelevant */
|
||||||
"-", /* default type value */
|
"-", /* default type value */
|
||||||
(bool) 1, /* passed by value */
|
true, /* passed by value */
|
||||||
'i', /* default alignment */
|
'i', /* default alignment */
|
||||||
'p'); /* Not TOASTable */
|
'p'); /* Not TOASTable */
|
||||||
}
|
}
|
||||||
@ -785,6 +783,7 @@ heap_create_with_catalog(char *relname,
|
|||||||
Relation pg_class_desc;
|
Relation pg_class_desc;
|
||||||
Relation new_rel_desc;
|
Relation new_rel_desc;
|
||||||
Oid new_rel_oid;
|
Oid new_rel_oid;
|
||||||
|
Oid new_type_oid;
|
||||||
int natts = tupdesc->natts;
|
int natts = tupdesc->natts;
|
||||||
char *temp_relname = NULL;
|
char *temp_relname = NULL;
|
||||||
|
|
||||||
@ -814,18 +813,10 @@ heap_create_with_catalog(char *relname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* RelnameFindRelid couldn't detect simultaneous
|
* Tell heap_create not to create a physical file; we'll do that
|
||||||
* creation. Uniqueness will be really checked by unique
|
* below after all our catalog updates are done. (This isn't really
|
||||||
* indexes of system tables but we couldn't check it here.
|
* necessary anymore, but we may as well avoid the cycles of creating
|
||||||
* We have to postpone creating the disk file for this
|
* and deleting the file in case we fail.)
|
||||||
* relation.
|
|
||||||
* Another boolean parameter "storage_create" was added
|
|
||||||
* to heap_create() function. If the parameter is false
|
|
||||||
* heap_create() only registers an uncataloged relation
|
|
||||||
* to relation cache and heap_storage_create() should be
|
|
||||||
* called later.
|
|
||||||
* We could pull its relation oid from the newly formed
|
|
||||||
* relation descriptor.
|
|
||||||
*
|
*
|
||||||
* Note: The call to heap_create() changes relname for
|
* Note: The call to heap_create() changes relname for
|
||||||
* temp tables; it becomes the true physical relname.
|
* temp tables; it becomes the true physical relname.
|
||||||
@ -836,24 +827,18 @@ heap_create_with_catalog(char *relname,
|
|||||||
new_rel_desc = heap_create(relname, tupdesc, istemp, false,
|
new_rel_desc = heap_create(relname, tupdesc, istemp, false,
|
||||||
allow_system_table_mods);
|
allow_system_table_mods);
|
||||||
|
|
||||||
|
/* Fetch the relation OID assigned by heap_create */
|
||||||
new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
|
new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;
|
||||||
|
|
||||||
/* ----------------
|
/* Assign an OID for the relation's tuple type */
|
||||||
* since defining a relation also defines a complex type,
|
new_type_oid = newoid();
|
||||||
* we add a new system type corresponding to the new relation.
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
AddNewRelationType(relname, new_rel_oid);
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* now add tuples to pg_attribute for the attributes in
|
* now create an entry in pg_class for the relation.
|
||||||
* our new relation.
|
*
|
||||||
* ----------------
|
* NOTE: we could get a unique-index failure here, in case someone else
|
||||||
*/
|
* is creating the same relation name in parallel but hadn't committed
|
||||||
AddNewAttributeTuples(new_rel_oid, tupdesc);
|
* yet when we checked for a duplicate name above.
|
||||||
|
|
||||||
/* ----------------
|
|
||||||
* now update the information in pg_class.
|
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
|
pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
@ -861,10 +846,28 @@ heap_create_with_catalog(char *relname,
|
|||||||
AddNewRelationTuple(pg_class_desc,
|
AddNewRelationTuple(pg_class_desc,
|
||||||
new_rel_desc,
|
new_rel_desc,
|
||||||
new_rel_oid,
|
new_rel_oid,
|
||||||
|
new_type_oid,
|
||||||
natts,
|
natts,
|
||||||
relkind,
|
relkind,
|
||||||
temp_relname);
|
temp_relname);
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* since defining a relation also defines a complex type,
|
||||||
|
* we add a new system type corresponding to the new relation.
|
||||||
|
*
|
||||||
|
* NOTE: we could get a unique-index failure here, in case the same name
|
||||||
|
* has already been used for a type.
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
AddNewRelationType(relname, new_rel_oid, new_type_oid);
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* now add tuples to pg_attribute for the attributes in
|
||||||
|
* our new relation.
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
AddNewAttributeTuples(new_rel_oid, tupdesc);
|
||||||
|
|
||||||
StoreConstraints(new_rel_desc);
|
StoreConstraints(new_rel_desc);
|
||||||
|
|
||||||
if (istemp)
|
if (istemp)
|
||||||
@ -912,7 +915,6 @@ heap_create_with_catalog(char *relname,
|
|||||||
* attribute catalog (needed?). (Anything else?)
|
* attribute catalog (needed?). (Anything else?)
|
||||||
*
|
*
|
||||||
* get proper relation from relation catalog (if not arg)
|
* get proper relation from relation catalog (if not arg)
|
||||||
* check if relation is vital (strcmp()/reltype?)
|
|
||||||
* scan attribute catalog deleting attributes of reldesc
|
* scan attribute catalog deleting attributes of reldesc
|
||||||
* (necessary?)
|
* (necessary?)
|
||||||
* delete relation from relation catalog
|
* delete relation from relation catalog
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.58 2001/01/24 19:42:52 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.59 2001/02/12 20:07:21 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -46,18 +46,17 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
|
|||||||
HeapScanDesc scan;
|
HeapScanDesc scan;
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
Oid typoid;
|
Oid typoid;
|
||||||
|
ScanKeyData typeKey[1];
|
||||||
static ScanKeyData typeKey[1] = {
|
|
||||||
{0, Anum_pg_type_typname, F_NAMEEQ}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* initialize the scan key and begin a scan of pg_type
|
* initialize the scan key and begin a scan of pg_type
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
fmgr_info(F_NAMEEQ, &typeKey[0].sk_func);
|
ScanKeyEntryInitialize(typeKey,
|
||||||
typeKey[0].sk_nargs = typeKey[0].sk_func.fn_nargs;
|
0,
|
||||||
typeKey[0].sk_argument = PointerGetDatum(typeName);
|
Anum_pg_type_typname,
|
||||||
|
F_NAMEEQ,
|
||||||
|
PointerGetDatum(typeName));
|
||||||
|
|
||||||
scan = heap_beginscan(pg_type_desc,
|
scan = heap_beginscan(pg_type_desc,
|
||||||
0,
|
0,
|
||||||
@ -269,10 +268,16 @@ TypeShellMake(char *typeName)
|
|||||||
* TypeCreate
|
* TypeCreate
|
||||||
*
|
*
|
||||||
* This does all the necessary work needed to define a new type.
|
* This does all the necessary work needed to define a new type.
|
||||||
|
*
|
||||||
|
* NOTE: if assignedTypeOid is not InvalidOid, then that OID is assigned to
|
||||||
|
* the new type (which, therefore, cannot already exist as a shell type).
|
||||||
|
* This hack is only intended for use in creating a relation's associated
|
||||||
|
* type, where we need to have created the relation tuple already.
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
Oid
|
Oid
|
||||||
TypeCreate(char *typeName,
|
TypeCreate(char *typeName,
|
||||||
|
Oid assignedTypeOid,
|
||||||
Oid relationOid, /* only for 'c'atalog typeTypes */
|
Oid relationOid, /* only for 'c'atalog typeTypes */
|
||||||
int16 internalSize,
|
int16 internalSize,
|
||||||
int16 externalSize,
|
int16 externalSize,
|
||||||
@ -292,35 +297,28 @@ TypeCreate(char *typeName,
|
|||||||
j;
|
j;
|
||||||
Relation pg_type_desc;
|
Relation pg_type_desc;
|
||||||
HeapScanDesc pg_type_scan;
|
HeapScanDesc pg_type_scan;
|
||||||
|
|
||||||
Oid typeObjectId;
|
Oid typeObjectId;
|
||||||
Oid elementObjectId = InvalidOid;
|
Oid elementObjectId = InvalidOid;
|
||||||
|
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
char nulls[Natts_pg_type];
|
char nulls[Natts_pg_type];
|
||||||
char replaces[Natts_pg_type];
|
char replaces[Natts_pg_type];
|
||||||
Datum values[Natts_pg_type];
|
Datum values[Natts_pg_type];
|
||||||
|
|
||||||
char *procname;
|
char *procname;
|
||||||
char *procs[4];
|
char *procs[4];
|
||||||
bool defined;
|
bool defined;
|
||||||
NameData name;
|
NameData name;
|
||||||
TupleDesc tupDesc;
|
TupleDesc tupDesc;
|
||||||
Oid argList[FUNC_MAX_ARGS];
|
Oid argList[FUNC_MAX_ARGS];
|
||||||
|
ScanKeyData typeKey[1];
|
||||||
static ScanKeyData typeKey[1] = {
|
|
||||||
{0, Anum_pg_type_typname, F_NAMEEQ}
|
|
||||||
};
|
|
||||||
|
|
||||||
fmgr_info(F_NAMEEQ, &typeKey[0].sk_func);
|
|
||||||
typeKey[0].sk_nargs = typeKey[0].sk_func.fn_nargs;
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* check that the type is not already defined.
|
* check that the type is not already defined. It might exist as
|
||||||
|
* a shell type, however (but only if assignedTypeOid is not given).
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
typeObjectId = TypeGet(typeName, &defined);
|
typeObjectId = TypeGet(typeName, &defined);
|
||||||
if (OidIsValid(typeObjectId) && defined)
|
if (OidIsValid(typeObjectId) &&
|
||||||
|
(defined || assignedTypeOid != InvalidOid))
|
||||||
elog(ERROR, "TypeCreate: type %s already defined", typeName);
|
elog(ERROR, "TypeCreate: type %s already defined", typeName);
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
@ -468,7 +466,12 @@ TypeCreate(char *typeName,
|
|||||||
*/
|
*/
|
||||||
pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
|
pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
typeKey[0].sk_argument = PointerGetDatum(typeName);
|
ScanKeyEntryInitialize(typeKey,
|
||||||
|
0,
|
||||||
|
Anum_pg_type_typname,
|
||||||
|
F_NAMEEQ,
|
||||||
|
PointerGetDatum(typeName));
|
||||||
|
|
||||||
pg_type_scan = heap_beginscan(pg_type_desc,
|
pg_type_scan = heap_beginscan(pg_type_desc,
|
||||||
0,
|
0,
|
||||||
SnapshotSelf, /* cache? */
|
SnapshotSelf, /* cache? */
|
||||||
@ -484,6 +487,10 @@ TypeCreate(char *typeName,
|
|||||||
tup = heap_getnext(pg_type_scan, 0);
|
tup = heap_getnext(pg_type_scan, 0);
|
||||||
if (HeapTupleIsValid(tup))
|
if (HeapTupleIsValid(tup))
|
||||||
{
|
{
|
||||||
|
/* should not happen given prior test? */
|
||||||
|
if (assignedTypeOid != InvalidOid)
|
||||||
|
elog(ERROR, "TypeCreate: type %s already defined", typeName);
|
||||||
|
|
||||||
tup = heap_modifytuple(tup,
|
tup = heap_modifytuple(tup,
|
||||||
pg_type_desc,
|
pg_type_desc,
|
||||||
values,
|
values,
|
||||||
@ -502,6 +509,9 @@ TypeCreate(char *typeName,
|
|||||||
values,
|
values,
|
||||||
nulls);
|
nulls);
|
||||||
|
|
||||||
|
/* preassign tuple Oid, if one was given */
|
||||||
|
tup->t_data->t_oid = assignedTypeOid;
|
||||||
|
|
||||||
heap_insert(pg_type_desc, tup);
|
heap_insert(pg_type_desc, tup);
|
||||||
|
|
||||||
typeObjectId = tup->t_data->t_oid;
|
typeObjectId = tup->t_data->t_oid;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.51 2001/01/24 19:42:52 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.52 2001/02/12 20:07:21 tgl Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The "DefineFoo" routines take the parse tree and pick out the
|
* The "DefineFoo" routines take the parse tree and pick out the
|
||||||
@ -640,6 +640,7 @@ DefineType(char *typeName, List *parameters)
|
|||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
TypeCreate(typeName, /* type name */
|
TypeCreate(typeName, /* type name */
|
||||||
|
InvalidOid, /* preassigned type oid (not done here) */
|
||||||
InvalidOid, /* relation oid (n/a here) */
|
InvalidOid, /* relation oid (n/a here) */
|
||||||
internalLength, /* internal size */
|
internalLength, /* internal size */
|
||||||
externalLength, /* external size */
|
externalLength, /* external size */
|
||||||
@ -652,7 +653,7 @@ DefineType(char *typeName, List *parameters)
|
|||||||
elemName, /* element type name */
|
elemName, /* element type name */
|
||||||
defaultValue, /* default type value */
|
defaultValue, /* default type value */
|
||||||
byValue, /* passed by value */
|
byValue, /* passed by value */
|
||||||
alignment,
|
alignment, /* required alignment */
|
||||||
storage); /* TOAST strategy */
|
storage); /* TOAST strategy */
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
@ -663,6 +664,7 @@ DefineType(char *typeName, List *parameters)
|
|||||||
shadow_type = makeArrayTypeName(typeName);
|
shadow_type = makeArrayTypeName(typeName);
|
||||||
|
|
||||||
TypeCreate(shadow_type, /* type name */
|
TypeCreate(shadow_type, /* type name */
|
||||||
|
InvalidOid, /* preassigned type oid (not done here) */
|
||||||
InvalidOid, /* relation oid (n/a here) */
|
InvalidOid, /* relation oid (n/a here) */
|
||||||
-1, /* internal size */
|
-1, /* internal size */
|
||||||
-1, /* external size */
|
-1, /* external size */
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pg_type.h,v 1.100 2001/01/24 19:43:22 momjian Exp $
|
* $Id: pg_type.h,v 1.101 2001/02/12 20:07:20 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* the genbki.sh script reads this file and generates .bki
|
||||||
@ -420,6 +420,7 @@ DESCR("numeric(precision, decimal), arbitrary precision number");
|
|||||||
extern Oid TypeGet(char *typeName, bool *defined);
|
extern Oid TypeGet(char *typeName, bool *defined);
|
||||||
extern Oid TypeShellMake(char *typeName);
|
extern Oid TypeShellMake(char *typeName);
|
||||||
extern Oid TypeCreate(char *typeName,
|
extern Oid TypeCreate(char *typeName,
|
||||||
|
Oid assignedTypeOid,
|
||||||
Oid relationOid,
|
Oid relationOid,
|
||||||
int16 internalSize,
|
int16 internalSize,
|
||||||
int16 externalSize,
|
int16 externalSize,
|
||||||
@ -431,7 +432,8 @@ extern Oid TypeCreate(char *typeName,
|
|||||||
char *sendProcedure,
|
char *sendProcedure,
|
||||||
char *elementTypeName,
|
char *elementTypeName,
|
||||||
char *defaultTypeValue,
|
char *defaultTypeValue,
|
||||||
bool passedByValue, char alignment,
|
bool passedByValue,
|
||||||
|
char alignment,
|
||||||
char storage);
|
char storage);
|
||||||
extern void TypeRename(const char *oldTypeName, const char *newTypeName);
|
extern void TypeRename(const char *oldTypeName, const char *newTypeName);
|
||||||
extern char *makeArrayTypeName(char *typeName);
|
extern char *makeArrayTypeName(char *typeName);
|
||||||
|
Reference in New Issue
Block a user