|
|
@ -7,7 +7,8 @@ |
|
|
|
* |
|
|
|
* |
|
|
|
* |
|
|
|
* |
|
|
|
* IDENTIFICATION |
|
|
|
* IDENTIFICATION |
|
|
|
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.70 1998/12/15 12:45:40 vadim Exp $ |
|
|
|
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.71 1999/02/02 03:44:08 momjian Exp $ |
|
|
|
|
|
|
|
* |
|
|
|
* |
|
|
|
* |
|
|
|
* INTERFACE ROUTINES |
|
|
|
* INTERFACE ROUTINES |
|
|
|
* heap_create() - Create an uncataloged heap relation |
|
|
|
* heap_create() - Create an uncataloged heap relation |
|
|
@ -26,6 +27,7 @@ |
|
|
|
*------------------------------------------------------------------------- |
|
|
|
*------------------------------------------------------------------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
#include "postgres.h" |
|
|
|
#include "postgres.h" |
|
|
|
|
|
|
|
#include "miscadmin.h" |
|
|
|
|
|
|
|
|
|
|
|
#include "access/heapam.h" |
|
|
|
#include "access/heapam.h" |
|
|
|
#include "catalog/catalog.h" |
|
|
|
#include "catalog/catalog.h" |
|
|
@ -41,7 +43,6 @@ |
|
|
|
#include "catalog/pg_type.h" |
|
|
|
#include "catalog/pg_type.h" |
|
|
|
#include "commands/trigger.h" |
|
|
|
#include "commands/trigger.h" |
|
|
|
#include "fmgr.h" |
|
|
|
#include "fmgr.h" |
|
|
|
#include "miscadmin.h" |
|
|
|
|
|
|
|
#include "nodes/plannodes.h" |
|
|
|
#include "nodes/plannodes.h" |
|
|
|
#include "optimizer/tlist.h" |
|
|
|
#include "optimizer/tlist.h" |
|
|
|
#include "parser/parse_expr.h" |
|
|
|
#include "parser/parse_expr.h" |
|
|
@ -53,11 +54,13 @@ |
|
|
|
#include "storage/lmgr.h" |
|
|
|
#include "storage/lmgr.h" |
|
|
|
#include "storage/smgr.h" |
|
|
|
#include "storage/smgr.h" |
|
|
|
#include "tcop/tcopprot.h" |
|
|
|
#include "tcop/tcopprot.h" |
|
|
|
|
|
|
|
#include "utils/catcache.h" |
|
|
|
#include "utils/builtins.h" |
|
|
|
#include "utils/builtins.h" |
|
|
|
#include "utils/mcxt.h" |
|
|
|
#include "utils/mcxt.h" |
|
|
|
#include "utils/relcache.h" |
|
|
|
#include "utils/relcache.h" |
|
|
|
#include "utils/syscache.h" |
|
|
|
#include "utils/syscache.h" |
|
|
|
#include "utils/tqual.h" |
|
|
|
#include "utils/tqual.h" |
|
|
|
|
|
|
|
#include "utils/temprel.h" |
|
|
|
|
|
|
|
|
|
|
|
#ifndef HAVE_MEMMOVE |
|
|
|
#ifndef HAVE_MEMMOVE |
|
|
|
#include <regex/utils.h> |
|
|
|
#include <regex/utils.h> |
|
|
@ -65,18 +68,17 @@ |
|
|
|
#include <string.h> |
|
|
|
#include <string.h> |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
static void AddPgRelationTuple(Relation pg_class_desc, |
|
|
|
static void AddNewRelationTuple(Relation pg_class_desc, |
|
|
|
Relation new_rel_desc, Oid new_rel_oid, unsigned natts, |
|
|
|
Relation new_rel_desc, Oid new_rel_oid, unsigned natts, |
|
|
|
char relkind); |
|
|
|
char relkind, char *temp_relname); |
|
|
|
static void AddToTempRelList(Relation r); |
|
|
|
static void AddToNoNameRelList(Relation r); |
|
|
|
static void DeletePgAttributeTuples(Relation rel); |
|
|
|
static void DeleteAttributeTuples(Relation rel); |
|
|
|
static void DeletePgRelationTuple(Relation rel); |
|
|
|
static void DeleteRelationTuple(Relation rel); |
|
|
|
static void DeletePgTypeTuple(Relation rel); |
|
|
|
static void DeleteTypeTuple(Relation rel); |
|
|
|
static int RelationAlreadyExists(Relation pg_class_desc, char *relname); |
|
|
|
|
|
|
|
static void RelationRemoveIndexes(Relation relation); |
|
|
|
static void RelationRemoveIndexes(Relation relation); |
|
|
|
static void RelationRemoveInheritance(Relation relation); |
|
|
|
static void RelationRemoveInheritance(Relation relation); |
|
|
|
static void RemoveFromTempRelList(Relation r); |
|
|
|
static void RemoveFromNoNameRelList(Relation r); |
|
|
|
static void addNewRelationType(char *typeName, Oid new_rel_oid); |
|
|
|
static void AddNewRelationType(char *typeName, Oid new_rel_oid); |
|
|
|
static void StoreConstraints(Relation rel); |
|
|
|
static void StoreConstraints(Relation rel); |
|
|
|
static void RemoveConstraints(Relation rel); |
|
|
|
static void RemoveConstraints(Relation rel); |
|
|
|
|
|
|
|
|
|
|
@ -167,35 +169,34 @@ static TempRelList *tempRels = NULL; |
|
|
|
* |
|
|
|
* |
|
|
|
* |
|
|
|
* |
|
|
|
* if heap_create is called with "" as the name, then heap_create will create |
|
|
|
* if heap_create is called with "" as the name, then heap_create will create |
|
|
|
* a temporary name "temp_$RELOID" for the relation |
|
|
|
* a temporary name "pg_noname.$PID.$SEQUENCE" for the relation |
|
|
|
* ---------------------------------------------------------------- |
|
|
|
* ---------------------------------------------------------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Relation |
|
|
|
Relation |
|
|
|
heap_create(char *name, |
|
|
|
heap_create(char *relname, |
|
|
|
TupleDesc tupDesc) |
|
|
|
TupleDesc tupDesc, |
|
|
|
|
|
|
|
bool isnoname, |
|
|
|
|
|
|
|
bool istemp) |
|
|
|
{ |
|
|
|
{ |
|
|
|
unsigned i; |
|
|
|
unsigned i; |
|
|
|
Oid relid; |
|
|
|
Oid relid; |
|
|
|
Relation rel; |
|
|
|
Relation rel; |
|
|
|
int len; |
|
|
|
int len; |
|
|
|
bool nailme = false; |
|
|
|
bool nailme = false; |
|
|
|
char *relname = name; |
|
|
|
|
|
|
|
char tempname[NAMEDATALEN]; |
|
|
|
|
|
|
|
int isTemp = 0; |
|
|
|
|
|
|
|
int natts = tupDesc->natts; |
|
|
|
int natts = tupDesc->natts; |
|
|
|
|
|
|
|
static unsigned int uniqueId = 0; |
|
|
|
/* Form_pg_attribute *att = tupDesc->attrs; */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern GlobalMemory CacheCxt; |
|
|
|
extern GlobalMemory CacheCxt; |
|
|
|
MemoryContext oldcxt; |
|
|
|
MemoryContext oldcxt; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
|
* sanity checks |
|
|
|
* sanity checks |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
AssertArg(natts > 0); |
|
|
|
AssertArg(natts > 0); |
|
|
|
|
|
|
|
|
|
|
|
if (IsSystemRelationName(relname) && IsNormalProcessingMode()) |
|
|
|
if (relname && IsSystemRelationName(relname) && IsNormalProcessingMode()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
elog(ERROR, |
|
|
|
elog(ERROR, |
|
|
|
"Illegal class name: %s -- pg_ is reserved for system catalogs", |
|
|
|
"Illegal class name: %s -- pg_ is reserved for system catalogs", |
|
|
@ -218,22 +219,22 @@ heap_create(char *name, |
|
|
|
* descriptor follows. |
|
|
|
* descriptor follows. |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
if (!strcmp(RelationRelationName, relname)) |
|
|
|
if (relname && !strcmp(RelationRelationName, relname)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
relid = RelOid_pg_class; |
|
|
|
relid = RelOid_pg_class; |
|
|
|
nailme = true; |
|
|
|
nailme = true; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (!strcmp(AttributeRelationName, relname)) |
|
|
|
else if (relname && !strcmp(AttributeRelationName, relname)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
relid = RelOid_pg_attribute; |
|
|
|
relid = RelOid_pg_attribute; |
|
|
|
nailme = true; |
|
|
|
nailme = true; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (!strcmp(ProcedureRelationName, relname)) |
|
|
|
else if (relname && !strcmp(ProcedureRelationName, relname)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
relid = RelOid_pg_proc; |
|
|
|
relid = RelOid_pg_proc; |
|
|
|
nailme = true; |
|
|
|
nailme = true; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (!strcmp(TypeRelationName, relname)) |
|
|
|
else if (relname && !strcmp(TypeRelationName, relname)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
relid = RelOid_pg_type; |
|
|
|
relid = RelOid_pg_type; |
|
|
|
nailme = true; |
|
|
|
nailme = true; |
|
|
@ -241,14 +242,21 @@ heap_create(char *name, |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
relid = newoid(); |
|
|
|
relid = newoid(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (name[0] == '\0') |
|
|
|
if (isnoname) |
|
|
|
{ |
|
|
|
{ |
|
|
|
snprintf(tempname, NAMEDATALEN, "temp_%d", relid); |
|
|
|
Assert(!relname); |
|
|
|
Assert(strlen(tempname) < NAMEDATALEN); |
|
|
|
relname = palloc(NAMEDATALEN); |
|
|
|
relname = tempname; |
|
|
|
snprintf(relname, NAMEDATALEN, "pg_noname.%d.%u", |
|
|
|
isTemp = 1; |
|
|
|
(int) MyProcPid, uniqueId++); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (istemp) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
/* replace relname of caller */ |
|
|
|
|
|
|
|
snprintf(relname, NAMEDATALEN, "pg_temp.%d.%u", |
|
|
|
|
|
|
|
(int) MyProcPid, uniqueId++); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
@ -262,16 +270,11 @@ heap_create(char *name, |
|
|
|
rel = (Relation) palloc(len); |
|
|
|
rel = (Relation) palloc(len); |
|
|
|
MemSet((char *) rel, 0, len); |
|
|
|
MemSet((char *) rel, 0, len); |
|
|
|
|
|
|
|
|
|
|
|
/* ----------
|
|
|
|
/*
|
|
|
|
create a new tuple descriptor from the one passed in |
|
|
|
* create a new tuple descriptor from the one passed in |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
rel->rd_att = CreateTupleDescCopyConstr(tupDesc); |
|
|
|
rel->rd_att = CreateTupleDescCopyConstr(tupDesc); |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
|
|
|
|
* initialize the fields of our new relation descriptor |
|
|
|
|
|
|
|
* ---------------- |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
|
* nail the reldesc if this is a bootstrap create reln and |
|
|
|
* nail the reldesc if this is a bootstrap create reln and |
|
|
|
* we may need it in the cache later on in the bootstrap |
|
|
|
* we may need it in the cache later on in the bootstrap |
|
|
@ -285,8 +288,11 @@ heap_create(char *name, |
|
|
|
|
|
|
|
|
|
|
|
rel->rd_rel = (Form_pg_class) palloc(sizeof *rel->rd_rel); |
|
|
|
rel->rd_rel = (Form_pg_class) palloc(sizeof *rel->rd_rel); |
|
|
|
|
|
|
|
|
|
|
|
MemSet((char *) rel->rd_rel, 0, |
|
|
|
/* ----------------
|
|
|
|
sizeof *rel->rd_rel); |
|
|
|
* initialize the fields of our new relation descriptor |
|
|
|
|
|
|
|
* ---------------- |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
MemSet((char *) rel->rd_rel, 0, sizeof *rel->rd_rel); |
|
|
|
namestrcpy(&(rel->rd_rel->relname), relname); |
|
|
|
namestrcpy(&(rel->rd_rel->relname), relname); |
|
|
|
rel->rd_rel->relkind = RELKIND_UNCATALOGED; |
|
|
|
rel->rd_rel->relkind = RELKIND_UNCATALOGED; |
|
|
|
rel->rd_rel->relnatts = natts; |
|
|
|
rel->rd_rel->relnatts = natts; |
|
|
@ -305,31 +311,30 @@ heap_create(char *name, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
|
* remember if this is a temp relation |
|
|
|
* remember if this is a noname relation |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
rel->rd_isnoname = isnoname; |
|
|
|
rel->rd_istemp = isTemp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
|
* have the storage manager create the relation. |
|
|
|
* have the storage manager create the relation. |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
rel->rd_tmpunlinked = TRUE; /* change once table is created */ |
|
|
|
rel->rd_nonameunlinked = TRUE; /* change once table is created */ |
|
|
|
rel->rd_fd = (File) smgrcreate(DEFAULT_SMGR, rel); |
|
|
|
rel->rd_fd = (File) smgrcreate(DEFAULT_SMGR, rel); |
|
|
|
rel->rd_tmpunlinked = FALSE; |
|
|
|
rel->rd_nonameunlinked = FALSE; |
|
|
|
|
|
|
|
|
|
|
|
RelationRegisterRelation(rel); |
|
|
|
RelationRegisterRelation(rel); |
|
|
|
|
|
|
|
|
|
|
|
MemoryContextSwitchTo(oldcxt); |
|
|
|
MemoryContextSwitchTo(oldcxt); |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* add all temporary relations to the tempRels list so they can be |
|
|
|
* add all noname relations to the tempRels list so they can be |
|
|
|
* properly disposed of at the end of transaction |
|
|
|
* properly disposed of at the end of transaction |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
if (isTemp) |
|
|
|
if (isnoname) |
|
|
|
AddToTempRelList(rel); |
|
|
|
AddToNoNameRelList(rel); |
|
|
|
|
|
|
|
|
|
|
|
return rel; |
|
|
|
return rel; |
|
|
|
} |
|
|
|
} |
|
|
@ -343,7 +348,7 @@ heap_create(char *name, |
|
|
|
* 1) CheckAttributeNames() is used to make certain the tuple |
|
|
|
* 1) CheckAttributeNames() is used to make certain the tuple |
|
|
|
* descriptor contains a valid set of attribute names |
|
|
|
* descriptor contains a valid set of attribute names |
|
|
|
* |
|
|
|
* |
|
|
|
* 2) pg_class is opened and RelationAlreadyExists() |
|
|
|
* 2) pg_class is opened and RelationFindRelid() |
|
|
|
* preforms a scan to ensure that no relation with the |
|
|
|
* preforms a scan to ensure that no relation with the |
|
|
|
* same name already exists. |
|
|
|
* same name already exists. |
|
|
|
* |
|
|
|
* |
|
|
@ -356,7 +361,7 @@ heap_create(char *name, |
|
|
|
* 5) AddNewAttributeTuples() is called to register the |
|
|
|
* 5) AddNewAttributeTuples() is called to register the |
|
|
|
* new relation's schema in pg_attribute. |
|
|
|
* new relation's schema in pg_attribute. |
|
|
|
* |
|
|
|
* |
|
|
|
* 6) AddPgRelationTuple() is called to register the |
|
|
|
* 6) AddNewRelationTuple() is called to register the |
|
|
|
* relation itself in the catalogs. |
|
|
|
* relation itself in the catalogs. |
|
|
|
* |
|
|
|
* |
|
|
|
* 7) StoreConstraints is called () - vadim 08/22/97 |
|
|
|
* 7) StoreConstraints is called () - vadim 08/22/97 |
|
|
@ -456,35 +461,39 @@ CheckAttributeNames(TupleDesc tupdesc) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* --------------------------------
|
|
|
|
/* --------------------------------
|
|
|
|
* RelationAlreadyExists |
|
|
|
* RelnameFindRelid |
|
|
|
* |
|
|
|
* |
|
|
|
* this preforms a scan of pg_class to ensure that |
|
|
|
* this preforms a scan of pg_class to ensure that |
|
|
|
* no relation with the same name already exists. The caller |
|
|
|
* no relation with the same name already exists. |
|
|
|
* has to open pg_class and pass an open descriptor. |
|
|
|
|
|
|
|
* -------------------------------- |
|
|
|
* -------------------------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static int |
|
|
|
Oid |
|
|
|
RelationAlreadyExists(Relation pg_class_desc, char *relname) |
|
|
|
RelnameFindRelid(char *relname) |
|
|
|
{ |
|
|
|
{ |
|
|
|
ScanKeyData key; |
|
|
|
HeapTuple tuple; |
|
|
|
HeapScanDesc pg_class_scan; |
|
|
|
Oid relid; |
|
|
|
HeapTuple tup; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* If this is not bootstrap (initdb) time, use the catalog index on |
|
|
|
* If this is not bootstrap (initdb) time, use the catalog index on |
|
|
|
* pg_class. |
|
|
|
* pg_class. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
if (!IsBootstrapProcessingMode()) |
|
|
|
if (!IsBootstrapProcessingMode()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
tup = SearchSysCacheTuple(RELNAME, |
|
|
|
tuple = SearchSysCacheTuple(RELNAME, |
|
|
|
PointerGetDatum(relname), |
|
|
|
PointerGetDatum(relname), |
|
|
|
0, 0, 0); |
|
|
|
0, 0, 0); |
|
|
|
if (HeapTupleIsValid(tup)) |
|
|
|
if (HeapTupleIsValid(tuple)) |
|
|
|
return true; |
|
|
|
relid = tuple->t_data->t_oid; |
|
|
|
else |
|
|
|
else |
|
|
|
return false; |
|
|
|
relid = InvalidOid; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Relation pg_class_desc; |
|
|
|
|
|
|
|
ScanKeyData key; |
|
|
|
|
|
|
|
HeapScanDesc pg_class_scan; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pg_class_desc = heap_openr(RelationRelationName); |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
|
* At bootstrap time, we have to do this the hard way. Form the |
|
|
|
* At bootstrap time, we have to do this the hard way. Form the |
|
|
@ -512,15 +521,18 @@ RelationAlreadyExists(Relation pg_class_desc, char *relname) |
|
|
|
* didn't find an existing relation. |
|
|
|
* didn't find an existing relation. |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
tup = heap_getnext(pg_class_scan, 0); |
|
|
|
tuple = heap_getnext(pg_class_scan, 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (HeapTupleIsValid(tuple)) |
|
|
|
|
|
|
|
relid = tuple->t_data->t_oid; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
relid = InvalidOid; |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
|
|
|
|
* end the scan and return existance of relation. |
|
|
|
|
|
|
|
* ---------------- |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
heap_endscan(pg_class_scan); |
|
|
|
heap_endscan(pg_class_scan); |
|
|
|
|
|
|
|
|
|
|
|
return HeapTupleIsValid(tup); |
|
|
|
heap_close(pg_class_desc); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return relid; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* --------------------------------
|
|
|
|
/* --------------------------------
|
|
|
@ -583,6 +595,7 @@ AddNewAttributeTuples(Oid new_rel_oid, |
|
|
|
(char *) *dpp); |
|
|
|
(char *) *dpp); |
|
|
|
|
|
|
|
|
|
|
|
heap_insert(rel, tup); |
|
|
|
heap_insert(rel, tup); |
|
|
|
|
|
|
|
|
|
|
|
if (hasindex) |
|
|
|
if (hasindex) |
|
|
|
CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup); |
|
|
|
CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup); |
|
|
|
|
|
|
|
|
|
|
@ -623,18 +636,19 @@ AddNewAttributeTuples(Oid new_rel_oid, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* --------------------------------
|
|
|
|
/* --------------------------------
|
|
|
|
* AddPgRelationTuple |
|
|
|
* AddNewRelationTuple |
|
|
|
* |
|
|
|
* |
|
|
|
* this registers the new relation in the catalogs by |
|
|
|
* this registers the new relation in the catalogs by |
|
|
|
* adding a tuple to pg_class. |
|
|
|
* adding a tuple to pg_class. |
|
|
|
* -------------------------------- |
|
|
|
* -------------------------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static void |
|
|
|
static void |
|
|
|
AddPgRelationTuple(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, |
|
|
|
unsigned natts, |
|
|
|
unsigned natts, |
|
|
|
char relkind) |
|
|
|
char relkind, |
|
|
|
|
|
|
|
char *temp_relname) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Form_pg_class new_rel_reltup; |
|
|
|
Form_pg_class new_rel_reltup; |
|
|
|
HeapTuple tup; |
|
|
|
HeapTuple tup; |
|
|
@ -679,9 +693,11 @@ AddPgRelationTuple(Relation pg_class_desc, |
|
|
|
|
|
|
|
|
|
|
|
heap_insert(pg_class_desc, tup); |
|
|
|
heap_insert(pg_class_desc, tup); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (temp_relname) |
|
|
|
|
|
|
|
create_temp_relation(temp_relname, tup); |
|
|
|
|
|
|
|
|
|
|
|
if (!isBootstrap) |
|
|
|
if (!isBootstrap) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* First, open the catalog indices and insert index tuples for the |
|
|
|
* First, open the catalog indices and insert index tuples for the |
|
|
|
* new relation. |
|
|
|
* new relation. |
|
|
@ -690,7 +706,6 @@ AddPgRelationTuple(Relation pg_class_desc, |
|
|
|
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs); |
|
|
|
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs); |
|
|
|
CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class_desc, tup); |
|
|
|
CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class_desc, tup); |
|
|
|
CatalogCloseIndices(Num_pg_class_indices, idescs); |
|
|
|
CatalogCloseIndices(Num_pg_class_indices, idescs); |
|
|
|
|
|
|
|
|
|
|
|
/* now restore processing mode */ |
|
|
|
/* now restore processing mode */ |
|
|
|
SetProcessingMode(NormalProcessing); |
|
|
|
SetProcessingMode(NormalProcessing); |
|
|
|
} |
|
|
|
} |
|
|
@ -700,13 +715,13 @@ AddPgRelationTuple(Relation pg_class_desc, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* --------------------------------
|
|
|
|
/* --------------------------------
|
|
|
|
* addNewRelationType - |
|
|
|
* AddNewRelationType - |
|
|
|
* |
|
|
|
* |
|
|
|
* define a complex type corresponding to the new relation |
|
|
|
* define a complex type corresponding to the new relation |
|
|
|
* -------------------------------- |
|
|
|
* -------------------------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
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; |
|
|
|
|
|
|
|
|
|
|
@ -745,36 +760,53 @@ addNewRelationType(char *typeName, Oid new_rel_oid) |
|
|
|
Oid |
|
|
|
Oid |
|
|
|
heap_create_with_catalog(char *relname, |
|
|
|
heap_create_with_catalog(char *relname, |
|
|
|
TupleDesc tupdesc, |
|
|
|
TupleDesc tupdesc, |
|
|
|
char relkind) |
|
|
|
char relkind, |
|
|
|
|
|
|
|
bool istemp) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Relation pg_class_desc; |
|
|
|
Relation pg_class_desc; |
|
|
|
Relation new_rel_desc; |
|
|
|
Relation new_rel_desc; |
|
|
|
Oid new_rel_oid; |
|
|
|
Oid new_rel_oid; |
|
|
|
|
|
|
|
|
|
|
|
int natts = tupdesc->natts; |
|
|
|
int natts = tupdesc->natts; |
|
|
|
|
|
|
|
char *temp_relname = NULL; |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
|
* sanity checks |
|
|
|
* sanity checks |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
AssertState(IsNormalProcessingMode() || IsBootstrapProcessingMode()); |
|
|
|
Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode()); |
|
|
|
if (natts == 0 || natts > MaxHeapAttributeNumber) |
|
|
|
if (natts == 0 || natts > MaxHeapAttributeNumber) |
|
|
|
elog(ERROR, "amcreate: from 1 to %d attributes must be specified", |
|
|
|
elog(ERROR, "amcreate: from 1 to %d attributes must be specified", |
|
|
|
MaxHeapAttributeNumber); |
|
|
|
MaxHeapAttributeNumber); |
|
|
|
|
|
|
|
|
|
|
|
CheckAttributeNames(tupdesc); |
|
|
|
CheckAttributeNames(tupdesc); |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* temp tables can mask non-temp tables */ |
|
|
|
* open pg_class and see that the relation doesn't |
|
|
|
if ((!istemp && RelnameFindRelid(relname)) || |
|
|
|
* already exist. |
|
|
|
(istemp && get_temp_rel_by_name(relname) != NULL)) |
|
|
|
* ---------------- |
|
|
|
elog(ERROR, "%s relation already exists", relname); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* invalidate cache so non-temp table is masked by temp */ |
|
|
|
|
|
|
|
if (istemp) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Oid relid = RelnameFindRelid(relname); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (relid != InvalidOid) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* This is heavy-handed, but appears necessary bjm 1999/02/01 |
|
|
|
|
|
|
|
* SystemCacheRelationFlushed(relid) is not enough either. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
pg_class_desc = heap_openr(RelationRelationName); |
|
|
|
RelationForgetRelation(relid); |
|
|
|
|
|
|
|
ResetSystemCache(); |
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (RelationAlreadyExists(pg_class_desc, relname)) |
|
|
|
/* save user relation name because heap_create changes it */ |
|
|
|
|
|
|
|
if (istemp) |
|
|
|
{ |
|
|
|
{ |
|
|
|
heap_close(pg_class_desc); |
|
|
|
temp_relname = pstrdup(relname); /* save original value */ |
|
|
|
elog(ERROR, "%s relation already exists", relname); |
|
|
|
relname = palloc(NAMEDATALEN); |
|
|
|
|
|
|
|
strcpy(relname, temp_relname); /* heap_create will change this */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
@ -784,9 +816,11 @@ heap_create_with_catalog(char *relname, |
|
|
|
* |
|
|
|
* |
|
|
|
* Note: The call to heap_create() does all the "real" work |
|
|
|
* Note: The call to heap_create() does all the "real" work |
|
|
|
* of creating the disk file for the relation. |
|
|
|
* of creating the disk file for the relation. |
|
|
|
|
|
|
|
* This changes relname for noname and temp tables. |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
new_rel_desc = heap_create(relname, tupdesc); |
|
|
|
new_rel_desc = heap_create(relname, tupdesc, false, istemp); |
|
|
|
|
|
|
|
|
|
|
|
new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid; |
|
|
|
new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid; |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
@ -794,7 +828,7 @@ heap_create_with_catalog(char *relname, |
|
|
|
* we add a new system type corresponding to the new relation. |
|
|
|
* we add a new system type corresponding to the new relation. |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
addNewRelationType(relname, new_rel_oid); |
|
|
|
AddNewRelationType(relname, new_rel_oid); |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
|
* now add tuples to pg_attribute for the attributes in |
|
|
|
* now add tuples to pg_attribute for the attributes in |
|
|
@ -807,14 +841,23 @@ heap_create_with_catalog(char *relname, |
|
|
|
* now update the information in pg_class. |
|
|
|
* now update the information in pg_class. |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
AddPgRelationTuple(pg_class_desc, |
|
|
|
pg_class_desc = heap_openr(RelationRelationName); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AddNewRelationTuple(pg_class_desc, |
|
|
|
new_rel_desc, |
|
|
|
new_rel_desc, |
|
|
|
new_rel_oid, |
|
|
|
new_rel_oid, |
|
|
|
natts, |
|
|
|
natts, |
|
|
|
relkind); |
|
|
|
relkind, |
|
|
|
|
|
|
|
temp_relname); |
|
|
|
|
|
|
|
|
|
|
|
StoreConstraints(new_rel_desc); |
|
|
|
StoreConstraints(new_rel_desc); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (istemp) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
pfree(relname); |
|
|
|
|
|
|
|
pfree(temp_relname); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
|
* ok, the relation has been cataloged, so close our relations |
|
|
|
* ok, the relation has been cataloged, so close our relations |
|
|
|
* and return the oid of the newly created relation. |
|
|
|
* and return the oid of the newly created relation. |
|
|
@ -990,12 +1033,12 @@ RelationRemoveIndexes(Relation relation) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* --------------------------------
|
|
|
|
/* --------------------------------
|
|
|
|
* DeletePgRelationTuple |
|
|
|
* DeleteRelationTuple |
|
|
|
* |
|
|
|
* |
|
|
|
* -------------------------------- |
|
|
|
* -------------------------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static void |
|
|
|
static void |
|
|
|
DeletePgRelationTuple(Relation rel) |
|
|
|
DeleteRelationTuple(Relation rel) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Relation pg_class_desc; |
|
|
|
Relation pg_class_desc; |
|
|
|
HeapTuple tup; |
|
|
|
HeapTuple tup; |
|
|
@ -1012,7 +1055,7 @@ DeletePgRelationTuple(Relation rel) |
|
|
|
if (!HeapTupleIsValid(tup)) |
|
|
|
if (!HeapTupleIsValid(tup)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
heap_close(pg_class_desc); |
|
|
|
heap_close(pg_class_desc); |
|
|
|
elog(ERROR, "DeletePgRelationTuple: %s relation nonexistent", |
|
|
|
elog(ERROR, "DeleteRelationTuple: %s relation nonexistent", |
|
|
|
&rel->rd_rel->relname); |
|
|
|
&rel->rd_rel->relname); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1027,12 +1070,12 @@ DeletePgRelationTuple(Relation rel) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* --------------------------------
|
|
|
|
/* --------------------------------
|
|
|
|
* DeletePgAttributeTuples |
|
|
|
* DeleteAttributeTuples |
|
|
|
* |
|
|
|
* |
|
|
|
* -------------------------------- |
|
|
|
* -------------------------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static void |
|
|
|
static void |
|
|
|
DeletePgAttributeTuples(Relation rel) |
|
|
|
DeleteAttributeTuples(Relation rel) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Relation pg_attribute_desc; |
|
|
|
Relation pg_attribute_desc; |
|
|
|
HeapTuple tup; |
|
|
|
HeapTuple tup; |
|
|
@ -1073,7 +1116,7 @@ DeletePgAttributeTuples(Relation rel) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* --------------------------------
|
|
|
|
/* --------------------------------
|
|
|
|
* DeletePgTypeTuple |
|
|
|
* DeleteTypeTuple |
|
|
|
* |
|
|
|
* |
|
|
|
* If the user attempts to destroy a relation and there |
|
|
|
* If the user attempts to destroy a relation and there |
|
|
|
* exists attributes in other relations of type |
|
|
|
* exists attributes in other relations of type |
|
|
@ -1082,7 +1125,7 @@ DeletePgAttributeTuples(Relation rel) |
|
|
|
* -------------------------------- |
|
|
|
* -------------------------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static void |
|
|
|
static void |
|
|
|
DeletePgTypeTuple(Relation rel) |
|
|
|
DeleteTypeTuple(Relation rel) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Relation pg_type_desc; |
|
|
|
Relation pg_type_desc; |
|
|
|
HeapScanDesc pg_type_scan; |
|
|
|
HeapScanDesc pg_type_scan; |
|
|
@ -1127,7 +1170,7 @@ DeletePgTypeTuple(Relation rel) |
|
|
|
{ |
|
|
|
{ |
|
|
|
heap_endscan(pg_type_scan); |
|
|
|
heap_endscan(pg_type_scan); |
|
|
|
heap_close(pg_type_desc); |
|
|
|
heap_close(pg_type_desc); |
|
|
|
elog(ERROR, "DeletePgTypeTuple: %s type nonexistent", |
|
|
|
elog(ERROR, "DeleteTypeTuple: %s type nonexistent", |
|
|
|
&rel->rd_rel->relname); |
|
|
|
&rel->rd_rel->relname); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1171,7 +1214,7 @@ DeletePgTypeTuple(Relation rel) |
|
|
|
heap_endscan(pg_attribute_scan); |
|
|
|
heap_endscan(pg_attribute_scan); |
|
|
|
heap_close(pg_attribute_desc); |
|
|
|
heap_close(pg_attribute_desc); |
|
|
|
|
|
|
|
|
|
|
|
elog(ERROR, "DeletePgTypeTuple: att of type %s exists in relation %d", |
|
|
|
elog(ERROR, "DeleteTypeTuple: att of type %s exists in relation %d", |
|
|
|
&rel->rd_rel->relname, relid); |
|
|
|
&rel->rd_rel->relname, relid); |
|
|
|
} |
|
|
|
} |
|
|
|
heap_endscan(pg_attribute_scan); |
|
|
|
heap_endscan(pg_attribute_scan); |
|
|
@ -1199,6 +1242,7 @@ heap_destroy_with_catalog(char *relname) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Relation rel; |
|
|
|
Relation rel; |
|
|
|
Oid rid; |
|
|
|
Oid rid; |
|
|
|
|
|
|
|
bool istemp = (get_temp_rel_by_name(relname) != NULL); |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
|
* first open the relation. if the relation does exist, |
|
|
|
* first open the relation. if the relation does exist, |
|
|
@ -1216,7 +1260,8 @@ heap_destroy_with_catalog(char *relname) |
|
|
|
* prevent deletion of system relations |
|
|
|
* prevent deletion of system relations |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
if (IsSystemRelationName(RelationGetRelationName(rel)->data)) |
|
|
|
/* allow temp of pg_class? Guess so. */ |
|
|
|
|
|
|
|
if (!istemp && IsSystemRelationName(RelationGetRelationName(rel)->data)) |
|
|
|
elog(ERROR, "amdestroy: cannot destroy %s relation", |
|
|
|
elog(ERROR, "amdestroy: cannot destroy %s relation", |
|
|
|
&rel->rd_rel->relname); |
|
|
|
&rel->rd_rel->relname); |
|
|
|
|
|
|
|
|
|
|
@ -1248,7 +1293,10 @@ heap_destroy_with_catalog(char *relname) |
|
|
|
* delete attribute tuples |
|
|
|
* delete attribute tuples |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
DeletePgAttributeTuples(rel); |
|
|
|
DeleteAttributeTuples(rel); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (istemp) |
|
|
|
|
|
|
|
remove_temp_relation(rid); |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
|
* delete type tuple. here we want to see the effects |
|
|
|
* delete type tuple. here we want to see the effects |
|
|
@ -1256,14 +1304,15 @@ heap_destroy_with_catalog(char *relname) |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
setheapoverride(true); |
|
|
|
setheapoverride(true); |
|
|
|
DeletePgTypeTuple(rel); |
|
|
|
DeleteTypeTuple(rel); |
|
|
|
setheapoverride(false); |
|
|
|
setheapoverride(false); |
|
|
|
|
|
|
|
|
|
|
|
/* ----------------
|
|
|
|
/* ----------------
|
|
|
|
* delete relation tuple |
|
|
|
* delete relation tuple |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
DeletePgRelationTuple(rel); |
|
|
|
/* must delete fake tuple in cache */ |
|
|
|
|
|
|
|
DeleteRelationTuple(rel); |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* release dirty buffers of this relation |
|
|
|
* release dirty buffers of this relation |
|
|
@ -1283,16 +1332,15 @@ heap_destroy_with_catalog(char *relname) |
|
|
|
* unlink the relation and finish up. |
|
|
|
* unlink the relation and finish up. |
|
|
|
* ---------------- |
|
|
|
* ---------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
if (!(rel->rd_istemp) || !(rel->rd_tmpunlinked)) |
|
|
|
if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked)) |
|
|
|
smgrunlink(DEFAULT_SMGR, rel); |
|
|
|
smgrunlink(DEFAULT_SMGR, rel); |
|
|
|
|
|
|
|
|
|
|
|
rel->rd_tmpunlinked = TRUE; |
|
|
|
rel->rd_nonameunlinked = TRUE; |
|
|
|
|
|
|
|
|
|
|
|
UnlockRelation(rel, AccessExclusiveLock); |
|
|
|
UnlockRelation(rel, AccessExclusiveLock); |
|
|
|
|
|
|
|
|
|
|
|
heap_close(rel); |
|
|
|
heap_close(rel); |
|
|
|
|
|
|
|
|
|
|
|
/* ok - flush the relation from the relcache */ |
|
|
|
|
|
|
|
RelationForgetRelation(rid); |
|
|
|
RelationForgetRelation(rid); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1306,11 +1354,11 @@ void |
|
|
|
heap_destroy(Relation rel) |
|
|
|
heap_destroy(Relation rel) |
|
|
|
{ |
|
|
|
{ |
|
|
|
ReleaseRelationBuffers(rel); |
|
|
|
ReleaseRelationBuffers(rel); |
|
|
|
if (!(rel->rd_istemp) || !(rel->rd_tmpunlinked)) |
|
|
|
if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked)) |
|
|
|
smgrunlink(DEFAULT_SMGR, rel); |
|
|
|
smgrunlink(DEFAULT_SMGR, rel); |
|
|
|
rel->rd_tmpunlinked = TRUE; |
|
|
|
rel->rd_nonameunlinked = TRUE; |
|
|
|
heap_close(rel); |
|
|
|
heap_close(rel); |
|
|
|
RemoveFromTempRelList(rel); |
|
|
|
RemoveFromNoNameRelList(rel); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1336,7 +1384,7 @@ heap_destroy(Relation rel) |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void |
|
|
|
void |
|
|
|
InitTempRelList(void) |
|
|
|
InitNoNameRelList(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (tempRels) |
|
|
|
if (tempRels) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -1356,10 +1404,10 @@ InitTempRelList(void) |
|
|
|
|
|
|
|
|
|
|
|
MODIFIES the global variable tempRels |
|
|
|
MODIFIES the global variable tempRels |
|
|
|
we don't really remove it, just mark it as NULL |
|
|
|
we don't really remove it, just mark it as NULL |
|
|
|
and DestroyTempRels will look for NULLs |
|
|
|
and DestroyNoNameRels will look for NULLs |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static void |
|
|
|
static void |
|
|
|
RemoveFromTempRelList(Relation r) |
|
|
|
RemoveFromNoNameRelList(Relation r) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
@ -1382,7 +1430,7 @@ RemoveFromTempRelList(Relation r) |
|
|
|
MODIFIES the global variable tempRels |
|
|
|
MODIFIES the global variable tempRels |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static void |
|
|
|
static void |
|
|
|
AddToTempRelList(Relation r) |
|
|
|
AddToNoNameRelList(Relation r) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!tempRels) |
|
|
|
if (!tempRels) |
|
|
|
return; |
|
|
|
return; |
|
|
@ -1401,7 +1449,7 @@ AddToTempRelList(Relation r) |
|
|
|
go through the tempRels list and destroy each of the relations |
|
|
|
go through the tempRels list and destroy each of the relations |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void |
|
|
|
void |
|
|
|
DestroyTempRels(void) |
|
|
|
DestroyNoNameRels(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
Relation rel; |
|
|
|
Relation rel; |
|
|
|