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