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: }