|
|
BSD 4.3
# include <pv.h>
# include <ingres.h>
# include <aux.h>
# include <catalog.h>
# include <func.h>
# include <sccs.h>
# include <errors.h>
SCCSID(@(#)destroy.c 8.3 2/8/85)
extern short tTdbu[];
extern int destroy();
extern int null_fn();
struct fn_def DstroyFn =
{
"DESTROY",
destroy,
null_fn,
null_fn,
NULL,
0,
tTdbu,
100,
'Z',
0
};
/*
** DESTROY RELATION
**
** The relations in pv are destroyed. This involves three steps:
** 1 - remove tuple from relation relation
** 2 - remove tuples from attribute relation
** 3 - unlink physical file
**
** If the relation is a secondary index, the entry is removed
** from the index relation, and the primary relation is set to
** be "not indexed" (unless there is another index on it).
**
** If the relation has an index, all its indexes are also
** destroyed.
**
** If any errors occured while destroying the relations,
** then the last error number is returned, otherwise
** 0 is returned.
**
** If any query modification was defined on the relation,
** the qrymod catalogues are updated.
**
** Trace Flags:
** 32
*/
destroy(pc, pv)
int pc;
PARM *pv;
{
register int i, ret;
register char *name;
opencatalog("relation", OR_WRITE);
opencatalog("attribute", OR_WRITE);
for (ret = 0; pc-- > 0; )
{
name = ((pv++)->pv_val).pv_str;
if (i = des(name))
ret = i;
}
return (ret);
}
des(name)
char *name;
{
register int i;
register char *relname;
struct tup_id tid;
char newrelname[MAXNAME + 3];
extern DESC Reldes, Attdes, Inddes, Treedes;
struct relation relt, relk;
relname = name;
# ifdef xZTR1
tTfp(32, -1, "destroy: %s\n", relname);
# endif
newrelname[MAXNAME + 2] = 0;
/* get the tuple from relation relation */
setkey(&Reldes, &relk, relname, RELID);
setkey(&Reldes, &relk, Usercode, RELOWNER);
if ((i = getequal(&Reldes, &relk, &relt, &tid)) != 0)
{
if (i < 0)
syserr("DESTROY: geteq(rel/%s) %d", relname, i);
return (nferror(RELNOEXIST, relname, 0)); /* nonexistant relation */
}
/* don't allow a system relation to be destroyed */
if (relt.relstat & S_CATALOG)
return (nferror(NODESTSYSREL, relname, 0)); /* attempt to destroy system catalog */
if ((i = delete(&Reldes, &tid)) != 0)
syserr("DESTROY: delete(rel) %d", i);
/*
** for concurrency reasons, flush the relation-relation page
** where the tuple was just deleted. This will prevent anyone
** from being able to "openr" the relation while it is being
** destroyed. It also allows recovery to finish the destroy
** it the system crashes during this destroy.
*/
if (i = flush_rel(&Reldes, FALSE))
syserr("destroy:flush rel %d", i);
purgetup(&Attdes, relt.relid, ATTRELID, relt.relowner, ATTOWNER, 0);
/*
** If this is a user relation, then additional processing
** might be needed to clean up indicies, protection constraints
** etc.
*/
if ((relt.relstat & S_CATALOG) == 0)
userdestroy(&relt);
if ((relt.relstat & S_VIEW) == 0)
{
ingresname(relname, Usercode, newrelname);
if (unlink(newrelname) < 0)
syserr("destroy: unlink(%.14s)", newrelname);
}
return (0);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.