|
|
1.1 root 1: # include <pv.h>
2: # include <ingres.h>
3: # include <access.h>
4: # include <aux.h>
5: # include <catalog.h>
6: # include <symbol.h>
7: # include <func.h>
8: # include <sccs.h>
9: # include <errors.h>
10:
11: SCCSID(@(#)rmqm.c 8.3 2/8/85)
12:
13: /*
14: ** RMQM -- DBU to delete protection and integrity constraints
15: **
16: ** Trace Flags:
17: ** 43
18: */
19:
20:
21: extern short tTdbu[];
22: extern int dest_const();
23: extern int null_fn();
24:
25: struct fn_def RmqmFn =
26: {
27: "RMQM",
28: dest_const,
29: null_fn,
30: null_fn,
31: NULL,
32: 0,
33: tTdbu,
34: 100,
35: 'Z',
36: 0
37: };
38: /*
39: ** DEST_CONST -- destroy constraints
40: **
41: ** Parameters:
42: ** pc -- number of parameters in pv
43: ** pv -- pv [0] == DESTPROT destroy permission
44: ** == DESTINTEG destroy integrity constraint
45: ** pv [1] relation from which to destroy constraint
46: ** pv [2] == if (pc != 2) relation from which to delete
47: ** constraints
48: ** pv[3] ... pv[pc - 1] == id of constraint
49: **
50: ** Returns:
51: ** 0
52: **
53: ** Side Effects:
54: ** destroys constraints. Involves activity on catalogs 'relation',
55: ** protect, integrities, and tree.
56: **
57: ** Trace Flags:
58: ** 43, 0
59: */
60:
61: dest_const(pc, pv)
62: int pc;
63: PARM pv[];
64: {
65: DESC d;
66: register int i;
67: int mode;
68: extern struct admin Admin;
69:
70: # ifdef xZTR1
71: if (tTf(43, 0))
72: {
73: printf("dest_const: ");
74: prvect(pc, pv);
75: }
76: # endif
77:
78: if (!(Admin.adhdr.adflags & A_QRYMOD))
79: return (0);
80: i = openr(&d, OR_RELTID, pv[1].pv_val.pv_str);
81: if (i < 0)
82: syserr("dest_const: openr(%s) %d", pv[1].pv_val.pv_str, i);
83:
84: if (i == 1 || !bequal(Usercode, d.reldum.relowner, UCODE_SZ))
85: {
86: error(RELNOEXIST, pv[1].pv_val.pv_str, 0);
87: return (0);
88: }
89:
90: mode = atoi(pv[0].pv_val.pv_str);
91: if (mode == DESTPROT)
92: dest_prot(&d, &pv[2]);
93: else if (mode == DESTINTEG)
94: dest_integ(&d, &pv[2]);
95: else
96: syserr("dest_const: bad mode %d", mode);
97: return (0);
98: }
99: /*
100: ** DEST_INTEG -- directs destruction of integrity constraints
101: **
102: ** Parameters:
103: ** desc -- descriptor for relation
104: ** intv -- PV_EOF terminated list of id strings, if first element
105: ** is PV_EOF means "all"
106: **
107: ** Returns:
108: ** none
109: **
110: ** Side Effects:
111: ** deletes integrity constraint. Activity on 'relation', integrities,
112: ** and tree.
113: */
114:
115: dest_integ(d, intv)
116: register DESC *d;
117: PARM intv[];
118: {
119: extern DESC Intdes;
120: struct integrity tuple, key;
121: struct tree tkey;
122: register i, j;
123: int tree_const();
124: int int_inttree();
125:
126: # ifdef xZTR1
127: if (tTf(43, 1))
128: printf("dest_integ((%s, %s)...)\n", d->reldum.relid, d->reldum.relowner);
129: # endif
130:
131: i_cat("integrities", &Intdes, &key, d->reldum.relid, INTRELID,
132: d->reldum.relowner, INTRELOWNER, mdINTEG, &tkey);
133:
134: if (intv[0].pv_type == PV_EOF)
135: {
136: /* destroy integrity 'relation' ALL */
137: if (!(d->reldum.relstat & S_INTEG))
138: return (0);
139: del_all(d, &Intdes, &key, &tuple, &tkey, S_INTEG,
140: tree_const, int_inttree);
141: return (0);
142: }
143: /* destroy integrity 'relation' int {, int} */
144: for (i = 0; intv[i].pv_type != PV_EOF; i++)
145: del_int(&Intdes, &key, &tuple, &tkey, intv[i].pv_val.pv_str, INTTREE,
146: tree_const, int_inttree);
147:
148: /* rescan to output error messages */
149: for (j = 0; j < i; j++)
150: if (*(intv[j].pv_val.pv_str))
151: error(BADINTEG, intv[j].pv_val.pv_str, 0);
152:
153: /* finally, check that there are still integrity constraints
154: ** on the relation, if not must reset the S_INTEG bit in the relation
155: ** relation tuple for that relation.
156: */
157: chk_const(d, &Intdes, &key, &tuple, d->reldum.relid, INTRELID, d->reldum.relowner,
158: INTRELOWNER, S_INTEG);
159: }
160: /*
161: ** DEST_PROT -- directs destruction of protection constraints
162: **
163: ** Parameters:
164: ** desc -- descriptor for relation
165: ** intv -- PV_EOF terminated list of id strings, if first element
166: ** is PV_EOF means "all"
167: **
168: ** Returns:
169: ** none
170: **
171: ** Side Effects:
172: ** deletes protection constraint. Activity on 'relation',
173: ** protect, and tree.
174: **
175: ** Trace Flags:
176: ** 43, 2
177: */
178:
179:
180: dest_prot(d, intv)
181: register DESC *d;
182: PARM intv[];
183: {
184: extern DESC Prodes;
185: struct protect tuple, key;
186: struct tree tkey;
187: register i, j;
188: int propermid;
189: int prot_protree();
190: int tree_prot();
191:
192: # ifdef xZTR1
193: if (tTf(43, 2))
194: printf("dest_prot((%s, %s)...)\n", d->reldum.relid, d->reldum.relowner);
195: # endif
196:
197: i_cat("protect", &Prodes, &key, d->reldum.relid, PRORELID, d->reldum.relowner,
198: PRORELOWN, mdPROT, &tkey);
199:
200: if (intv[0].pv_type == PV_EOF)
201: {
202: /* destroy permit 'relation' ALL */
203: if (!(d->reldum.relstat & S_PROTRET) || !(d->reldum.relstat & S_PROTALL))
204: r_relstat(d, S_PROTRET | S_PROTALL, 1);
205: if (!(d->reldum.relstat & S_PROTUPS))
206: return (0);
207: del_all(d, &Prodes, &key, &tuple, &tkey, S_PROTUPS,
208: tree_prot, prot_protree);
209: return (0);
210: }
211: /* destroy permit 'relation' int {, int} */
212: for (i = 0; intv[i].pv_type != PV_EOF; i++)
213: {
214: propermid = atoi(intv[i].pv_val.pv_str);
215: if (propermid == 0)
216: {
217: if (!(d->reldum.relstat & S_PROTALL))
218: {
219: r_relstat(d, S_PROTALL, 1);
220: intv[i].pv_val.pv_str = 0;
221: }
222: continue;
223: }
224: else if (propermid == 1)
225: {
226: if (!(d->reldum.relstat & S_PROTRET))
227: {
228: r_relstat(d, S_PROTRET, 1);
229: intv[i].pv_val.pv_str = 0;
230: }
231: continue;
232: }
233: del_int(&Prodes, &key, &tuple, &tkey, intv[i].pv_val.pv_str, PROPERMID,
234: tree_prot, prot_protree);
235: }
236: /* rescan to output error messages */
237: for (j = 0; j < i; j++)
238: if (intv[j].pv_val.pv_str && intv[j].pv_val.pv_str[0] )
239: error(BADPROT, intv[j].pv_val.pv_str, 0);
240:
241: /* finally, check that there are still permissions
242: ** on the relation, if not must reset the S_PROTUPS bit in the relation
243: ** relation tuple for that relation's relstat.
244: */
245: chk_const(d, &Prodes, &key, &tuple, d->reldum.relid, PRORELID,
246: d->reldum.relowner, PRORELOWN, S_PROTUPS);
247: }
248: /*
249: ** I_CAT -- prepare catalogs for deletin of constraint
250: **
251: ** Initializes treerelid, treeowner, and treetype fields
252: ** of tree key. Also relation id and owner fields of
253: ** appropriate catalog c_desc, with key 'key'.
254: **
255: ** Parameters:
256: ** c_name -- name of catalog for opencatalog
257: ** c_desc -- descriptor of catalog
258: ** key -- key for catalog
259: ** relid -- relation.relid for relation to be de-constrained
260: ** id_attno -- attno of relid in constraint catalog c_desc
261: ** relowner -- relation.relowner for rel to be de-constrained
262: ** own_attno -- attno of owner in constrain catalog
263: ** type -- treetype for tree tuple (depends on catalog)
264: ** tkey -- key for tree catalog
265: **
266: ** Returns:
267: ** none
268: **
269: ** Side Effects:
270: ** opencatalogs the constraint catalog c_desc, and the "tree" rel
271: ** for READ/WRITE. Sets keys.
272: **
273: ** Trace Flags:
274: ** 43, 3
275: */
276:
277: i_cat(c_name, c_desc, key, relid, id_attno, relowner, own_attno, type, tkey)
278: char *c_name;
279: DESC *c_desc;
280: char *key;
281: char *relid;
282: int id_attno;
283: char *relowner;
284: int own_attno;
285: int type;
286: struct tree *tkey;
287: {
288: extern DESC Treedes;
289: char realtype;
290:
291: # ifdef xZTR1
292: if (tTf(43, 3))
293: printf("i_cat(c_name \"%s\", relid %s id_attno %d relowner %s own_attno %d type %d)\n",
294: c_name, relid, id_attno, relowner, own_attno, type);
295: # endif
296:
297: realtype = type;
298: opencatalog("tree", OR_WRITE);
299: setkey(&Treedes, tkey, relid, TREERELID);
300: setkey(&Treedes, tkey, relowner, TREEOWNER);
301: setkey(&Treedes, tkey, &realtype, TREETYPE);
302: opencatalog(c_name, OR_WRITE);
303: clearkeys(c_desc);
304: setkey(c_desc, key, relid, id_attno);
305: setkey(c_desc, key, relowner, own_attno);
306: }
307: /*
308: ** DEL_ALL -- delete all constraints for a given relation
309: **
310: ** Deletes all constraints of a given type given by a constraint
311: ** catalog 'c_desc'. Note that Protection constraints 0 & 1, given
312: ** by relation.relstat field are not deleted here.
313: **
314: ** Parameters:
315: ** r_desc -- descriptor for relation to de-constrain (for
316: ** r_relstat)
317: ** c_desc -- constraint catalog descriptor
318: ** key -- c_desc's key
319: ** tuple -- c_desc's tuple (needed because sizeof tuple is not
320: ** known here, so must be allocated beforehand)
321: ** tkey -- tree key with TREERELID and TREERELOWNER setkeyed
322: ** bit -- bits in relstat to reset after deleting all constraints
323: ** tree_pred -- called with constraint tuple to determine
324: ** wether a tree tuple is present or not (as can happen
325: ** for protect catalog)
326: ** tree_field -- should return the treeid from tuple
327: **
328: ** Returns:
329: ** none
330: **
331: ** Side Effects:
332: ** tree and constraint catalog activity
333: **
334: ** Requires:
335: ** del_tree()
336: ** r_relstat()
337: **
338: ** Called By:
339: ** dest_????
340: **
341: ** Trace Flags:
342: ** 43, 4
343: **
344: ** Syserrs:
345: ** bad find, get, delete, flush_rel
346: **
347: ** History:
348: ** 1/10/79 -- (marc) written
349: */
350:
351: del_all(r_desc, c_desc, key, tuple, tkey, bit, tree_pred, tree_field)
352: DESC *r_desc;
353: DESC *c_desc;
354: char *key;
355: char *tuple;
356: struct tree *tkey;
357: int bit;
358: int (*tree_pred)();
359: int (*tree_field)();
360: {
361: TID lotid, hitid;
362: register int i;
363:
364: # ifdef xZTR1
365: if (tTf(43, 4))
366: printf("del_all(bit=0%o)\n", bit);
367: # endif
368:
369: if (i = find(c_desc, EXACTKEY, &lotid, &hitid, key))
370: syserr("del_all: find %d", i);
371: while (!(i = get(c_desc, &lotid, &hitid, tuple, TRUE)))
372: {
373: if (!kcompare(c_desc, tuple, key))
374: {
375: /* for each constraint of for a relation */
376: if (i = delete(c_desc, &lotid))
377: syserr("del_all: delete %d", i);
378: /* for crash recovery */
379: if (i = flush_rel(c_desc, FALSE))
380: syserr("del_all: flush_rel %d", i);
381: /* if there is a tree tuple, destroy it */
382: if ((*tree_pred)(tuple))
383: del_tree(tkey, (*tree_field)(tuple));
384: }
385: }
386: if (i != 1)
387: syserr("del_all: get %d", i);
388: /* turn off bit in relstat field */
389: r_relstat(r_desc, bit, 0);
390: }
391: /*
392: ** DEL_INT -- delete from a constraint catalog a constraint
393: **
394: ** Parameters:
395: ** c_desc -- catalog descriptor
396: ** key -- catalog key
397: ** tuple -- catalog tuple (needed because tuple size unknown here)
398: ** tkey -- tree key with TREERELID and TREERELOWNER setkeyed
399: ** constid -- integer constraint id in string form
400: ** constattno -- attno of comstraint number in c_desc
401: ** tree_pred -- predicate on existence of tree tuple
402: ** tree_field -- returns treeid from constrain tuple
403: **
404: ** Returns:
405: ** none
406: **
407: ** Side Effects:
408: ** constraint and tree catalog activity.
409: ** *constid set to 0 if constraint id exists.
410: **
411: ** Requires:
412: ** del_tree()
413: **
414: ** Called By:
415: ** dest_????
416: **
417: ** Trace Flags:
418: ** 43, 5
419: **
420: ** Syserrs:
421: ** bad atoi (parser error), getequal, delete, flush_rel
422: **
423: ** History:
424: ** 1/10/79 -- (marc) written
425: */
426:
427: del_int(c_desc, key, tuple, tkey, constid, constattno, tree_pred, tree_field)
428: DESC *c_desc;
429: char *key;
430: char *tuple;
431: struct tree *tkey;
432: char *constid;
433: int constattno;
434: int (*tree_pred)();
435: int (*tree_field)();
436: {
437: TID tid;
438: register int i;
439: short constnum;
440:
441: # ifdef xZTR1
442: if (tTf(43, 5))
443: printf("del_int(constid=%s, constattno=%d)\n",
444: constid, constattno);
445: # endif
446:
447: constnum = atoi(constid);
448: setkey(c_desc, key, &constnum, constattno);
449: if (!(i = getequal(c_desc, key, tuple, &tid)))
450: {
451: if (i = delete(c_desc, &tid))
452: syserr("del_int(%d) %d", constid, i);
453: if ((*tree_pred)(tuple))
454: del_tree(tkey, (*tree_field)(tuple));
455: *constid = '\0';
456: return;
457: }
458: else if (i != 1)
459: syserr("dest_int: getequal %d", i);
460: /* bad constnum */
461: }
462: /*
463: ** DEST_TREE -- destroy a tree tuple with for a given treeid
464: **
465: ** Deletes all tuples from tree with 'treeid' and previously set
466: ** keys.
467: **
468: ** Parameters:
469: ** key -- tre key
470: ** treeid -- integer treeid
471: **
472: ** Returns:
473: ** none
474: **
475: ** Side Effects:
476: ** tree activity
477: **
478: ** Trace Flags:
479: ** 43, 6
480: */
481:
482: del_tree(key, treeid)
483: struct tree *key;
484: int treeid;
485: {
486: struct tree tuple;
487: TID lotid, hitid;
488: register int i;
489: register int flag;
490: short realid;
491: extern DESC Treedes;
492:
493: # ifdef xZTR1
494: if (tTf(43, 6))
495: printf("del_tree(treeid=%d)\n", treeid);
496: # endif
497:
498: realid = treeid;
499: setkey(&Treedes, key, &realid, TREEID);
500: if (i = find(&Treedes, EXACTKEY, &lotid, &hitid, key))
501: syserr("del_tree: bad find %d treeid %d", i, treeid);
502: flag = 0;
503: while (!(i = get(&Treedes, &lotid, &hitid, &tuple, TRUE)))
504: {
505: if (!kcompare(&Treedes, &tuple, key))
506: {
507: if (i = delete(&Treedes, &lotid))
508: syserr("del_tree: delete treeid %d %d", treeid, i);
509: if (!flag)
510: flag++;
511: }
512: }
513: if (i != 1)
514: syserr("del_tree: bad get %d", i);
515: if (!flag)
516: syserr("del_tree: no tuples qualified treeid %d", treeid);
517: if (i = flush_rel(&Treedes, FALSE))
518: syserr("del_tree: flush_rel(&Treedes) %d", i);
519: }
520: /*
521: ** CHK_CONST -- check constraint catlg for tuples for a rel, and reset relatin.relstat
522: **
523: ** Parameters:
524: ** r_desc -- reon desc for de-constrained relation
525: ** c_desc -- catalog desc
526: ** key -- catalog key (here unknown size)
527: ** tuple -- " tuple space " " " " "
528: ** relid -- relation name
529: ** id_attno -- attno of relid
530: ** relowner -- relation owner
531: ** own_attno -- relowner attno
532: ** bit -- bits to reset in relstat if there are no constraints left
533: **
534: ** Returns:
535: ** none
536: **
537: ** Side Effects:
538: ** reads catalog, maybe changes relstat field of relation
539: ** relations's r_desc tuple
540: **
541: ** Trace Flags:
542: ** 43, 7
543: */
544:
545: chk_const(r_desc, c_desc, key, tuple, relid, id_attno, relowner, own_attno, bit)
546: DESC *r_desc;
547: DESC *c_desc;
548: char *key;
549: char *tuple;
550: char *relid;
551: int id_attno;
552: char *relowner;
553: int own_attno;
554: int bit;
555: {
556: TID tid;
557: register int i;
558:
559:
560: # ifdef xZTR1
561: if (tTf(43, 7))
562: printf("chk_const: relid %s id_attno %d relowner %s own_attno %d bit 0%o)\n",
563: relid, id_attno, relowner, own_attno, bit);
564: # endif
565:
566: clearkeys(c_desc);
567: setkey(c_desc, key, relid, id_attno);
568: setkey(c_desc, key, relowner, own_attno);
569: if ((i = getequal(c_desc, key, tuple, &tid)) == 1)
570: r_relstat(r_desc, bit, 0);
571: else if (i < 0)
572: syserr("chk_const: getequal %d", i);
573: }
574: /*
575: ** R_RELSTAT -- set or reset bits in the relation.relstat field
576: **
577: ** Does the above for relation described by desc.
578: **
579: ** Parameters:
580: ** d -- relation to have relation.relstat field changed
581: ** bit -- bits to set or reset
582: ** action -- 0 reset, 1 set
583: **
584: ** Returns:
585: ** none
586: **
587: ** Side Effects:
588: ** relation is opened for READ/WRITE, relstat changed
589: **
590: ** Trace Flags:
591: ** 43, 8
592: */
593:
594:
595: r_relstat(d, bit, action)
596: register DESC *d;
597: int bit;
598: int action;
599: {
600: struct relation tuple, key;
601: TID tid;
602: register int i;
603: extern DESC Reldes;
604:
605: # ifdef xZTR1
606: if (tTf(43, 8))
607: printf("r_relstat(bit=0%o, action %d)\n",
608: bit, action);
609: # endif
610:
611: opencatalog("relation", OR_WRITE);
612: clearkeys(&Reldes);
613: setkey(&Reldes, &key, d->reldum.relid, RELID);
614: setkey(&Reldes, &key, d->reldum.relowner, RELOWNER);
615: if (i = getequal(&Reldes, &key, &tuple, &tid))
616: syserr("r_relstat: getequal %s, %s, %d", d->reldum.relid,
617: d->reldum.relowner, i);
618: if (action)
619: {
620: if (tuple.relstat == (i = tuple.relstat | bit))
621: return;
622: tuple.relstat = i;
623: }
624: else
625: {
626: if (tuple.relstat == (i = tuple.relstat & ~bit))
627: return;
628: tuple.relstat = i;
629: }
630: if ((i = replace(&Reldes, &tid, &tuple, 0)) < 0 || i == 2)
631: syserr("r_relstat: replace %d", i);
632: if (i = flush_rel(&Reldes, FALSE))
633: syserr("r_relstat: flush_rel(&Reldes) %d", i);
634: }
635: /*
636: ** TREE_CONST -- True predicate
637: **
638: ** Called indirectly by routines wishing to know if
639: ** a integrity constraint has an associated tree tuple.
640: ** As this is always the case, returns TRUE always.
641: **
642: ** Parameters:
643: ** i -- integrity tuple
644: **
645: ** Returns:
646: ** TRUE
647: **
648: ** Side Effects:
649: ** none
650: **
651: ** Trace Flags:
652: ** 43, 9
653: */
654:
655: tree_const(i)
656: struct integrity *i;
657: {
658: # ifdef xZTR1
659: if (tTf(43, 9))
660: printf("tree_const()\n");
661: # endif
662:
663: return (TRUE);
664: }
665: /*
666: ** TREE_PROT -- Protection tuple tree predicate
667: **
668: ** Called indirectly by routines wishing to know if
669: ** a protection constraint has an associated tree tuple.
670: **
671: ** Parameters:
672: ** p -- protect tuple
673: **
674: ** Returns:
675: ** TRUE -- if p->protree != -1
676: ** FLASE -- otherwise
677: **
678: ** Side Effects:
679: ** none
680: **
681: ** Trace Flags:
682: ** 43, 9
683: */
684:
685: tree_prot(p)
686: struct protect *p;
687: {
688: # ifdef xZTR1
689: if (tTf(43, 9))
690: printf("tree_prot(p->protree=%d)\n", p->protree);
691: # endif
692:
693: if (p->protree == -1)
694: return (FALSE);
695: else
696: return (TRUE);
697: }
698: /*
699: ** PROT_PROTREE -- get protree field of a protection tuple
700: **
701: ** Parameters:
702: ** p -- protect tuple
703: **
704: ** Returns:
705: ** p->protree
706: **
707: ** Side Effects:
708: ** none
709: **
710: ** Trace Flags:
711: ** 43, 9
712: */
713:
714: prot_protree(p)
715: struct protect *p;
716: {
717: # ifdef xZTR1
718: if (tTf(43, 9))
719: printf("prot_protree(protree=%d)\n", p->protree);
720: # endif
721:
722: return (p->protree);
723: }
724: /*
725: ** INT_INTTREE -- get inttree field of a integrity tuple
726: **
727: ** Parameters:
728: ** i -- integrity tuple
729: **
730: ** Returns:
731: ** i->inttree
732: **
733: ** Side Effects:
734: ** none
735: **
736: ** Trace Flags:
737: ** 43, 9
738: */
739:
740: int_inttree(i)
741: struct integrity *i;
742: {
743: # ifdef xZTR1
744: if (tTf(43, 9))
745: printf("int_inttree(inttree=%d)\n", i->inttree);
746: # endif
747:
748: return (i->inttree);
749: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.