|
|
1.1 root 1: # include <pv.h>
2: # include <ingres.h>
3: # include <aux.h>
4: # include <catalog.h>
5: # include <func.h>
6: # include <sccs.h>
7: # include <errors.h>
8:
9: SCCSID(@(#)destroy.c 8.3 2/8/85)
10:
11: extern short tTdbu[];
12: extern int destroy();
13: extern int null_fn();
14:
15: struct fn_def DstroyFn =
16: {
17: "DESTROY",
18: destroy,
19: null_fn,
20: null_fn,
21: NULL,
22: 0,
23: tTdbu,
24: 100,
25: 'Z',
26: 0
27: };
28:
29:
30: /*
31: ** DESTROY RELATION
32: **
33: ** The relations in pv are destroyed. This involves three steps:
34: ** 1 - remove tuple from relation relation
35: ** 2 - remove tuples from attribute relation
36: ** 3 - unlink physical file
37: **
38: ** If the relation is a secondary index, the entry is removed
39: ** from the index relation, and the primary relation is set to
40: ** be "not indexed" (unless there is another index on it).
41: **
42: ** If the relation has an index, all its indexes are also
43: ** destroyed.
44: **
45: ** If any errors occured while destroying the relations,
46: ** then the last error number is returned, otherwise
47: ** 0 is returned.
48: **
49: ** If any query modification was defined on the relation,
50: ** the qrymod catalogues are updated.
51: **
52: ** Trace Flags:
53: ** 32
54: */
55:
56: destroy(pc, pv)
57: int pc;
58: PARM *pv;
59: {
60: register int i, ret;
61: register char *name;
62:
63: opencatalog("relation", OR_WRITE);
64: opencatalog("attribute", OR_WRITE);
65:
66: for (ret = 0; pc-- > 0; )
67: {
68: name = ((pv++)->pv_val).pv_str;
69: if (i = des(name))
70: ret = i;
71: }
72: return (ret);
73: }
74:
75:
76: des(name)
77: char *name;
78: {
79: register int i;
80: register char *relname;
81: struct tup_id tid;
82: char newrelname[MAXNAME + 3];
83: extern DESC Reldes, Attdes, Inddes, Treedes;
84: struct relation relt, relk;
85:
86: relname = name;
87: # ifdef xZTR1
88: tTfp(32, -1, "destroy: %s\n", relname);
89: # endif
90:
91: newrelname[MAXNAME + 2] = 0;
92:
93: /* get the tuple from relation relation */
94: setkey(&Reldes, &relk, relname, RELID);
95: setkey(&Reldes, &relk, Usercode, RELOWNER);
96: if ((i = getequal(&Reldes, &relk, &relt, &tid)) != 0)
97: {
98: if (i < 0)
99: syserr("DESTROY: geteq(rel/%s) %d", relname, i);
100: return (nferror(RELNOEXIST, relname, 0)); /* nonexistant relation */
101: }
102:
103: /* don't allow a system relation to be destroyed */
104: if (relt.relstat & S_CATALOG)
105: return (nferror(NODESTSYSREL, relname, 0)); /* attempt to destroy system catalog */
106:
107: if ((i = delete(&Reldes, &tid)) != 0)
108: syserr("DESTROY: delete(rel) %d", i);
109:
110: /*
111: ** for concurrency reasons, flush the relation-relation page
112: ** where the tuple was just deleted. This will prevent anyone
113: ** from being able to "openr" the relation while it is being
114: ** destroyed. It also allows recovery to finish the destroy
115: ** it the system crashes during this destroy.
116: */
117: if (i = flush_rel(&Reldes, FALSE))
118: syserr("destroy:flush rel %d", i);
119:
120: purgetup(&Attdes, relt.relid, ATTRELID, relt.relowner, ATTOWNER, 0);
121:
122: /*
123: ** If this is a user relation, then additional processing
124: ** might be needed to clean up indicies, protection constraints
125: ** etc.
126: */
127: if ((relt.relstat & S_CATALOG) == 0)
128: userdestroy(&relt);
129:
130: if ((relt.relstat & S_VIEW) == 0)
131: {
132: ingresname(relname, Usercode, newrelname);
133: if (unlink(newrelname) < 0)
134: syserr("destroy: unlink(%.14s)", newrelname);
135: }
136: return (0);
137:
138: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.