# /* ** RMQM -- DBU to delete protection and integrity constraints ** ** Defines: ** dest_const ** dest_integ ** dest_prot ** i_cat ** dl_all ** del_int ** del_tree ** chk_const ** r_relstat ** tree_const ** tree_prot ** prot_protree ** int_inttree ** ** Required By: ** DBU driver ** ** Files: ** ../ingres.h ** ../access.h ** ../aux.h ** ../catalog.h ** ../symbol.h ** ** Compilation Flags: ** xZTR1 ** ** Trace Flags: ** 13 ** ** History: ** 1/10/79 -- (marc) written */ # include "../ingres.h" # include "../access.h" # include "../aux.h" # include "../unix.h" # include "../catalog.h" # include "../symbol.h" /* ** DEST_CONST -- destroy constraints ** ** Parameters: ** argc -- number of parameters in argv ** argv -- argv [0] == 5 destroy permission ** == 6 destroy integrity constraint ** argv [1] relation from which to destroy constrain ** argv [2] == if (argc != 2) relation from which to delete ** constraints ** argv[3] ... argv[argc - 1] == id of constraint ** ** Returns: ** 0 ** ** Side Effects: ** destroys constraints. Involves activity on catalogs 'relation', ** protect, integrities, and tree. ** ** Requires: ** dest_integ() ** dest_prot() ** ** Called By: ** DBU driver ** ** Trace Flags: ** 13, 0 ** ** Diagnostics: ** 5202 no relation user owns by the name given ** ** Syserrs: ** bad openr, bad function mode !(5 || 6) ** ** History: ** 1/10/79 -- (marc) written */ dest_const(argc, argv) int argc; char **argv; { struct descriptor d; register i; int mode; extern struct admin Admin; # ifdef xZTR1 if (tTf(13, 0)) { printf("dest_const\n"); prargs(argc, argv); } # endif if (!(Admin.adhdr.adflags & A_QRYMOD)) return (0); i = openr(&d, -1, argv[1]); if (i < 0) syserr("dest_const: openr(%s) %d", argv[1], i); if (i == 1 || !bequal(Usercode, d.relowner, 2)) { error(5202, argv[1], 0); return (0); } argv[argc] = 0; if (i = atoi(argv[0], &mode)) syserr("dest_const: bad mode string \"%s\"", argv[0]); if (mode == 5) dest_prot(&d, &argv[2]); else if (mode == 6) dest_integ(&d, &argv[2]); else syserr("dest_const: bad mode %d", mode); return (0); } /* ** DEST_INTEG -- directs destruction of integrity constraints ** ** Parameters: ** desc -- descriptor for relation ** intv -- 0 terminated list of id strings, if first element ** is 0 means "all" ** ** Returns: ** none ** ** Side Effects: ** deletes integrity constraint. Activity on 'relation', integrities, ** and tree. ** ** Requires: ** i_cat() ** del_all() ** del_int() ** chk_const() ** tree_const() ** int_inttree() ** ** Called By: ** dest_const ** ** Trace Flags: ** 13, 1 ** ** Diagnostics: ** 5203 no integrity constraint by given id ** ** History: ** 1/10/79 -- (marc) written */ dest_integ(desc, intv) struct descriptor *desc; char *intv[]; { register struct descriptor *d; extern struct descriptor Intdes; struct integrity tuple, key; struct tree tkey; register i, j; int tree_const(); int int_inttree(); d = desc; # ifdef xZTR1 if (tTf(13, 1)) printf("dest_integ((%s, %s)...)\n", d->relid, d->relowner); # endif i_cat("integrities", &Intdes, &key, d->relid, INTRELID, d->relowner, INTRELOWNER, mdINTEG, &tkey); if (intv[0] == 0) { /* destroy integrity 'relation' ALL */ if (!(d->relstat & S_INTEG)) return (0); del_all(d, &Intdes, &key, &tuple, &tkey, S_INTEG, &tree_const, &int_inttree); return (0); } /* destroy integrity 'relation' int {, int} */ for (i = 0; intv[i]; i++) del_int(&Intdes, &key, &tuple, &tkey, intv[i], INTTREE, &tree_const, &int_inttree); /* rescan to output error messages */ for (j = 0; j < i; j++) if (*intv[j]) error(5203, intv[j], 0); /* finally, check that there are still integrity constraints ** on the relation, if not must reset the S_INTEG bit in the relation ** relation tuple for that relation. */ chk_const(d, &Intdes, &key, &tuple, d->relid, INTRELID, d->relowner, INTRELOWNER, S_INTEG); } /* ** DEST_PROT -- directs destruction of protection constraints ** ** Parameters: ** desc -- descriptor for relation ** intv -- 0 terminated list of id strings, if first element ** is 0 means "all" ** ** Returns: ** none ** ** Side Effects: ** deletes protection constraint. Activity on 'relation', ** protect, and tree. ** ** Requires: ** i_cat() ** del_all() ** del_int() ** chk_const() ** tree_prot() ** prot_protree() ** ** Called By: ** dest_const ** ** Trace Flags: ** 13, 2 ** ** Diagnostics: ** 5204 no protection constraint by given id ** ** History: ** 1/10/79 -- (marc) written */ dest_prot(desc, intv) struct descriptor *desc; char *intv[]; { register struct descriptor *d; extern struct descriptor Prodes; struct protect tuple, key; struct tree tkey; register i, j; int propermid; int prot_protree(); int tree_prot(); d = desc; # ifdef xZTR1 if (tTf(13, 2)) printf("dest_prot((%s, %s)...)\n", d->relid, d->relowner); # endif i_cat("protect", &Prodes, &key, d->relid, PRORELID, d->relowner, PRORELOWN, mdPROT, &tkey); if (intv[0] == 0) { /* destroy permit 'relation' ALL */ if (!(d->relstat & S_PROTRET) || !(d->relstat & S_PROTALL)) r_relstat(d, S_PROTRET | S_PROTALL, 1); if (!(d->relstat & S_PROTUPS)) return (0); del_all(d, &Prodes, &key, &tuple, &tkey, S_PROTUPS, &tree_prot, &prot_protree); return (0); } /* destroy permit 'relation' int {, int} */ for (i = 0; intv[i]; i++) { if (j = atoi(intv[i], &propermid)) syserr("dest_prot: bad atoi \"%s\" %d", intv[i], j); if (propermid == 0) { if (!(d->relstat & S_PROTALL)) { r_relstat(d, S_PROTALL, 1); *intv[i] = 0; } continue; } else if (propermid == 1) { if (!(d->relstat & S_PROTRET)) { r_relstat(d, S_PROTRET, 1); *intv[i] = 0; } continue; } del_int(&Prodes, &key, &tuple, &tkey, intv[i], PROPERMID, &tree_prot, &prot_protree); } /* rescan to output error messages */ for (j = 0; j < i; j++) if (*intv[j]) error(5204, intv[j], 0); /* finally, check that there are still permissions ** on the relation, if not must reset the S_PROTUPS bit in the relation ** relation tuple for that relation's relstat. */ chk_const(d, &Prodes, &key, &tuple, d->relid, PRORELID, d->relowner, PRORELOWN, S_PROTUPS); } /* ** I_CAT -- prepare catalogs for deletin of constraint ** ** Initializes treerelid, treeowner, and treetype fields ** of tree key. Also relation id and owner fields of ** appropriate catalog c_desc, with key 'key'. ** ** Parameters: ** c_name -- name of catalog for opencatalog ** c_desc -- descriptor of catalog ** key -- key for catalog ** relid -- relation.relid for relation to be de-constrained ** id_attno -- attno of relid in constraint catalog c_desc ** relowner -- relation.relowner for rel to be de-constrained ** own_attno -- attno of owner in constrain catalog ** type -- treetype for tree tuple (depends on catalog) ** tkey -- key for tree catalog ** ** Returns: ** none ** ** Side Effects: ** opencatalogs the constraint catalog c_desc, and the "tree" rel ** for READ/WRITE. Sets keys. ** ** Called By: ** dest_prot() ** dest_int() ** ** Trace Flags: ** 13, 3 ** ** History: ** 1/10/79 -- (marc) written */ i_cat(c_name, c_desc, key, relid, id_attno, relowner, own_attno, type, tkey) char *c_name; struct descriptor *c_desc; char *key; char *relid; int id_attno; char *relowner; int own_attno; int type; struct tree *tkey; { extern struct descriptor Treedes; # ifdef xZTR1 if (tTf(13, 3)) printf("i_cat(c_name \"%s\", relid %s id_attno %d relowner %s own_attno %d type %d)\n", c_name, relid, id_attno, relowner, own_attno, type); # endif opencatalog("tree", 2); setkey(&Treedes, tkey, relid, TREERELID); setkey(&Treedes, tkey, relowner, TREEOWNER); setkey(&Treedes, tkey, &type, TREETYPE); opencatalog(c_name, 2); clearkeys(c_desc); setkey(c_desc, key, relid, id_attno); setkey(c_desc, key, relowner, own_attno); } /* ** DEL_ALL -- delete all constraints for a given relation ** ** Deletes all constraints of a given type given by a constraint ** catalog 'c_desc'. Note that Protection constraints 0 & 1, given ** by relation.relstat field are not deleted here. ** ** Parameters: ** r_desc -- descriptor for relation to de-constrain (for ** r_relstat) ** c_desc -- constraint catalog descriptor ** key -- c_desc's key ** tuple -- c_desc's tuple (needed because sizeof tuple is not ** known here, so must be allocated beforehand) ** tkey -- tree key with TREERELID and TREERELOWNER setkeyed ** bit -- bits in relstat to reset after deleting all constraints ** tree_pred -- called with constraint tuple to determine ** wether a tree tuple is present or not (as can happen ** for protect catalog) ** tree_field -- should return the treeid from tuple ** ** Returns: ** none ** ** Side Effects: ** tree and constraint catalog activity ** ** Requires: ** del_tree() ** r_relstat() ** ** Called By: ** dest_???? ** ** Trace Flags: ** 13, 4 ** ** Syserrs: ** bad find, get, delete, flush_rel ** ** History: ** 1/10/79 -- (marc) written */ del_all(r_desc, c_desc, key, tuple, tkey, bit, tree_pred, tree_field) struct descriptor *r_desc; struct descriptor *c_desc; char *key; char *tuple; struct tree *tkey; int bit; int (*tree_pred)(); int (*tree_field)(); { struct tup_id lotid, hitid; register i; # ifdef xZTR1 if (tTf(13, 4)) printf("del_all(bit=0%o)\n", bit); # endif if (i = find(c_desc, EXACTKEY, &lotid, &hitid, key)) syserr("del_all: find %d", i); while (!(i = get(c_desc, &lotid, &hitid, tuple, TRUE))) { if (!kcompare(c_desc, tuple, key)) { /* for each constraint of for a relation */ if (i = delete(c_desc, &lotid)) syserr("del_all: delete %d", i); /* for crash recovery */ if (i = flush_rel(c_desc, FALSE)) syserr("del_all: flush_rel %d", i); /* if there is a tree tuple, destroy it */ if ((*tree_pred)(tuple)) del_tree(tkey, (*tree_field)(tuple)); } } if (i != 1) syserr("del_all: get %d", i); /* turn off bit in relstat field */ r_relstat(r_desc, bit, 0); } /* ** DEL_INT -- delete from a constraint catalog a constraint ** ** Parameters: ** c_desc -- catalog descriptor ** key -- catalog key ** tuple -- catalog tuple (needed because tuple size unknown here) ** tkey -- tree key with TREERELID and TREERELOWNER setkeyed ** constid -- integer constraint id in string form ** constattno -- attno of comstraint number in c_desc ** tree_pred -- predicate on existence of tree tuple ** tree_field -- returns treeid from constrain tuple ** ** Returns: ** none ** ** Side Effects: ** constraint and tree catalog activity. ** *constid set to 0 if constraint id exists. ** ** Requires: ** del_tree() ** ** Called By: ** dest_???? ** ** Trace Flags: ** 13, 5 ** ** Syserrs: ** bad atoi (parser error), getequal, delete, flush_rel ** ** History: ** 1/10/79 -- (marc) written */ del_int(c_desc, key, tuple, tkey, constid, constattno, tree_pred, tree_field) struct descriptor *c_desc; char *key; char *tuple; struct tree *tkey; char *constid; int constattno; int (*tree_pred)(); int (*tree_field)(); { struct tup_id tid; register i; int constnum; # ifdef xZTR1 if (tTf(13, 5)) printf("del_int(constid=%s, constattno=%d)\n", constid, constattno); # endif if (i = atoi(constid, &constnum)) syserr("del_int: bad atoi \"%s\" %d", constid, i); setkey(c_desc, key, &constnum, constattno); if (!(i = getequal(c_desc, key, tuple, &tid))) { if (i = delete(c_desc, &tid)) syserr("del_int(%d) %d", constid, i); if ((*tree_pred)(tuple)) del_tree(tkey, (*tree_field)(tuple)); *constid = '\0'; return; } else if (i != 1) syserr("dest_int: getequal %d", i); /* bad constnum */ } /* ** DEST_TREE -- destroy a tree tuple with for a given treeid ** ** Deletes all tuples from tree with 'treeid' and previously set ** keys. ** ** Parameters: ** key -- tre key ** treeid -- integer treeid ** ** Returns: ** none ** ** Side Effects: ** tree activity ** ** Called By: ** del_int, del_all ** ** Trace Flags: ** 13, 6 ** ** Syserrs: ** bad find, get, delete, flush_rel, no tuple qualified. ** ** History: ** 1/10/79 -- (marc) written */ del_tree(key, treeid) struct tree *key; int treeid; { struct tree tuple; struct tup_id lotid, hitid; register i; register flag; extern struct descriptor Treedes; # ifdef xZTR1 if (tTf(13, 6)) printf("del_tree(treeid=%d)\n", treeid); # endif setkey(&Treedes, key, &treeid, TREEID); if (i = find(&Treedes, EXACTKEY, &lotid, &hitid, key)) syserr("del_tree: bad find %d treeid %d", i, treeid); flag = 0; while (!(i = get(&Treedes, &lotid, &hitid, &tuple, TRUE))) { if (!kcompare(&Treedes, &tuple, key)) { if (i = delete(&Treedes, &lotid)) syserr("del_tree: delete treeid %d %d", treeid, i); if (!flag) flag++; } } if (i != 1) syserr("del_tree: bad get %d", i); if (!flag) syserr("del_tree: no tuples qualified treeid %d", treeid); if (i = flush_rel(&Treedes, FALSE)) syserr("del_tree: flush_rel(&Treedes) %d", i); } /* ** CHK_CONST -- check constraint catlg for tuples for a rel, and reset relatin.relstat ** ** Parameters: ** r_desc -- relation desc for de-constrained relation ** c_desc -- catalog desc ** key -- catalog key (here unknown size) ** tuple -- " tuple space " " " " " ** relid -- relation name ** id_attno -- attno of relid ** relowner -- relation owner ** own_attno -- relowner attno ** bit -- bits to reset in relstat if there are no constraints left ** ** Returns: ** none ** ** Side Effects: ** reads catalog, maybe changes relstat field of relation relations's ** r_desc tuple ** ** Requires: ** r_relstat ** ** Called By: ** dest_???? ** ** Trace Flags: ** 13, 7 ** ** Syserrs: ** bad getequal ** ** History: ** 1/10/79 -- (marc) written */ chk_const(r_desc, c_desc, key, tuple, relid, id_attno, relowner, own_attno, bit) struct descriptor *r_desc; struct descriptor *c_desc; char *key; char *tuple; char *relid; int id_attno; char *relowner; int own_attno; int bit; { struct tup_id tid; register i; # ifdef xZTR1 if (tTf(13, 7)) printf("chk_const: relid %s id_attno %d relowner %s own_attno %d bit 0%o)\n", relid, id_attno, relowner, own_attno, bit); # endif clearkeys(c_desc); setkey(c_desc, key, relid, id_attno); setkey(c_desc, key, relowner, own_attno); if ((i = getequal(c_desc, key, tuple, &tid)) == 1) r_relstat(r_desc, bit, 0); else if (i < 0) syserr("chk_const: getequal %d", i); } /* ** R_RELSTAT -- set or reset bits in the relation.relstat field ** ** Does the above for relation described by desc. ** ** Parameters: ** desc -- relation to have relation.relstat field changed ** bit -- bits to set or reset ** action -- 0 reset, 1 set ** ** Returns: ** none ** ** Side Effects: ** relation is opened for READ/WRITE, relstat changed ** ** Called By: ** everyone ** ** Trace Flags: ** 13, 8 ** ** Syserrs: ** bad getequal, replace, flush_rel ** ** History: ** 1/10/79 -- (marc) written */ r_relstat(desc, bit, action) struct descriptor *desc; int bit; int action; { struct relation tuple, key; struct tup_id tid; register i; extern struct descriptor Reldes; register struct descriptor *d; d = desc; # ifdef xZTR1 if (tTf(13, 8)) printf("r_relstat(bit=0%o, action %d)\n", bit, action); # endif opencatalog("relation", 2); clearkeys(&Reldes); setkey(&Reldes, &key, d->relid, RELID); setkey(&Reldes, &key, d->relowner, RELOWNER); if (i = getequal(&Reldes, &key, &tuple, &tid)) syserr("r_relstat: getequal %s, %s, %d", d->relid, d->relowner, i); if (action) { if (tuple.relstat == (i = tuple.relstat | bit)) return; tuple.relstat = i; } else { if (tuple.relstat == (i = tuple.relstat & ~bit)) return; tuple.relstat = i; } if ((i = replace(&Reldes, &tid, &tuple, 0)) < 0 || i == 2) syserr("r_relstat: replace %d", i); if (i = flush_rel(&Reldes, FALSE)) syserr("r_relstat: flush_rel(&Reldes) %d", i); } /* ** TREE_CONST -- True predicate ** ** Called indirectly by routines wishing to know if ** a integrity constraint has an associated tree tuple. ** As this is always the case, returns TRUE always. ** ** Parameters: ** i -- integrity tuple ** ** Returns: ** TRUE ** ** Side Effects: ** none ** ** Called By: ** sent to del_int, del_all, by dest_int ** ** Trace Flags: ** 13, 9 ** ** History: ** 1/11/79 -- (marc) written */ tree_const(i) struct integrity *i; { # ifdef xZTR1 if (tTf(13, 9)) printf("tree_const()\n"); # endif return (TRUE); } /* ** TREE_PROT -- Protection tuple tree predicate ** ** Called indirectly by routines wishing to know if ** a protection constraint has an associated tree tuple. ** ** Parameters: ** p -- protect tuple ** ** Returns: ** TRUE -- if p->protree != -1 ** FLASE -- otherwise ** ** Side Effects: ** none ** ** Called By: ** sent to del_int, del_all, by dest_prot ** ** Trace Flags: ** 13, 9 ** ** History: ** 1/11/79 -- (marc) written */ tree_prot(p) struct protect *p; { # ifdef xZTR1 if (tTf(13, 9)) printf("tree_prot(p->protree=%d)\n", p->protree); # endif if (p->protree == -1) return (FALSE); else return (TRUE); } /* ** PROT_PROTREE -- get protree field of a protection tuple ** ** Parameters: ** p -- protect tuple ** ** Returns: ** p->protree ** ** Side Effects: ** none ** ** Called By: ** Indirectly. Passed to del_int, del_all by dest_prot ** ** Trace Flags: ** 13, 9 ** ** History: ** 1/11/79 -- (marc) written */ prot_protree(p) struct protect *p; { # ifdef xZTR1 if (tTf(13, 9)) printf("prot_protree(protree=%d)\n", p->protree); # endif return (p->protree); } /* ** INT_INTTREE -- get inttree field of a integrity tuple ** ** Parameters: ** i -- integrity tuple ** ** Returns: ** i->inttree ** ** Side Effects: ** none ** ** Called By: ** Indirectly. Passed to del_int, del_all by dest_int ** ** Trace Flags: ** 13, 9 ** ** History: ** 1/11/79 -- (marc) written */ int_inttree(i) struct integrity *i; { # ifdef xZTR1 if (tTf(13, 9)) printf("int_inttree(inttree=%d)\n", i->inttree); # endif return (i->inttree); }