|
|
1.1 ! root 1: # include <ingres.h> ! 2: # include <aux.h> ! 3: # include <catalog.h> ! 4: # include <tree.h> ! 5: # include <symbol.h> ! 6: # include <pv.h> ! 7: # include <resp.h> ! 8: # include <func.h> ! 9: # include "qrymod.h" ! 10: # include <sccs.h> ! 11: ! 12: SCCSID(@(#)d_integ.c 7.1 2/5/81) ! 13: ! 14: ! 15: /* ! 16: ** D_INTEG -- define integrity constraint ! 17: ** ! 18: ** An integrity constraint (as partially defined by the last ! 19: ** tree defined by d_tree) is defined. ! 20: ** ! 21: ** Parameters: ! 22: ** none ! 23: ** ! 24: ** Returns: ! 25: ** none ! 26: ** ! 27: ** Side Effects: ! 28: ** Activity in 'relation' and 'integrities' catalogs. ! 29: ** ! 30: ** Trace Flags: ! 31: ** 49 ! 32: */ ! 33: ! 34: extern DESC Intdes; ! 35: extern DESC Reldes; ! 36: ! 37: extern d_integ(), null_fn(); ! 38: extern short tTqm[80]; ! 39: ! 40: struct fn_def DefIntFn = ! 41: { ! 42: "DINTEG", ! 43: d_integ, ! 44: null_fn, ! 45: null_fn, ! 46: NULL, ! 47: 0, ! 48: tTqm, ! 49: 80, ! 50: 'Q', ! 51: 0 ! 52: }; ! 53: ! 54: ! 55: ! 56: d_integ(pc, pv) ! 57: int pc; ! 58: PARM *pv; ! 59: { ! 60: register int i; ! 61: register QTREE *t; /* definition tree */ ! 62: struct integrity inttup; ! 63: struct tup_id tid; ! 64: register int rv; /* result variable */ ! 65: struct relation relkey; ! 66: struct relation reltup; ! 67: ! 68: if (pv[0].pv_type != PV_QTREE) ! 69: syserr("d_integ: tree"); ! 70: t = pv[0].pv_val.pv_qtree; ! 71: rv = Qt.qt_resvar; ! 72: ! 73: /* ! 74: ** Check for valid environment. ! 75: ** The tree must exist, have a qualification, and have ! 76: ** no target list. The query mode must be mdINTEG. ! 77: ** ! 78: ** User level stuff checks to see that this is single ! 79: ** variable aggregate free, since that's all we know ! 80: ** about thusfar. Also, the relation in question must ! 81: ** not be a view. ! 82: */ ! 83: ! 84: # ifdef xQTR3 ! 85: if (t == NULL) ! 86: syserr("d_integ: NULL tree"); ! 87: if ((i = t->right->sym.type) != AND) ! 88: syserr("d_integ: qual %d", i); ! 89: if ((i = t->left->sym.type) != TREE) ! 90: syserr("d_integ: TL %d", i); ! 91: if (Qt.qt_qmode != mdINTEG) ! 92: syserr("d_integ: Qmode %d", Qt.qt_qmode); ! 93: # endif ! 94: ! 95: /* check for aggregates */ ! 96: if (aggcheck(t)) ! 97: qmerror(3490, -1, rv, 0); /* aggregates in qual */ ! 98: ! 99: /* check for multi-variable */ ! 100: for (i = 0; i < MAXRANGE; i++) ! 101: { ! 102: if (Qt.qt_rangev[i].rngvdesc == NULL) ! 103: continue; ! 104: if (i != rv) ! 105: { ! 106: # ifdef xQTR3 ! 107: if (tTf(49, 1)) ! 108: printf("d_integ: Rv %d(%.14s) i %d(%.14s)\n", ! 109: rv, Qt.qt_rangev[rv].rngvdesc->reldum.relid, ! 110: i, Qt.qt_rangev[i].rngvdesc->reldum.relid); ! 111: # endif ! 112: qmerror(3491, -1, rv, 0); /* too many vars */ ! 113: } ! 114: } ! 115: ! 116: /* check for the resultvariable being a real relation */ ! 117: if (bitset(S_VIEW, Qt.qt_rangev[rv].rngvdesc->reldum.relstat)) ! 118: qmerror(3493, -1, rv, 0); /* is a view */ ! 119: ! 120: /* guarantee that you own this relation */ ! 121: if (!bequal(Usercode, Qt.qt_rangev[rv].rngvdesc->reldum.relowner, 2)) ! 122: qmerror(3494, -1, rv, 0); /* don't own reln */ ! 123: ! 124: /* ! 125: ** Guarantee that the integrity constraint is true now. ! 126: ** This involves issuing a retrieve statement for the ! 127: ** inverse of the qualification. The target list is ! 128: ** already null, so we will get nothing printed out ! 129: ** (only a return status). ! 130: ** ! 131: ** We reset resp_tups if ok so that the user isn't annoyed ! 132: ** by a tuple count. On error, it is a count of the ! 133: ** number of tuples that don't satisfy. ! 134: */ ! 135: ! 136: Qt.qt_qmode = mdRETR; ! 137: Qt.qt_resvar = -1; ! 138: ! 139: /* issue the invert of the query */ ! 140: issueinvert(t); ! 141: if (Resp.resp_tups != 0) ! 142: qmerror(3492, -1, rv, 0); /* constraint not satisfied */ ! 143: Resp.resp_tups = -1; ! 144: ! 145: /* ! 146: ** Set up the rest of the environment. ! 147: */ ! 148: ! 149: opencatalog("integrities", 2); ! 150: clr_tuple(&Intdes, &inttup); ! 151: Qt.qt_resvar = -1; ! 152: Qt.qt_qmode = -1; ! 153: ! 154: /* ! 155: ** Set up integrity relation tuple. ! 156: ** The qualification will be scanned, and a set of ! 157: ** domains referenced will be created. Other stuff ! 158: ** is filled in from the range table and from the ! 159: ** parser. ! 160: ** ! 161: ** The tree is actually inserted into the tree catalog ! 162: ** in this step. Extra information is cleared here. ! 163: */ ! 164: ! 165: inttup.intresvar = rv; ! 166: bmove(Qt.qt_rangev[rv].rngvdesc->reldum.relid, inttup.intrelid, MAXNAME); ! 167: bmove(Qt.qt_rangev[rv].rngvdesc->reldum.relowner, inttup.intrelowner, 2); ! 168: makeidset(rv, t, inttup.intdomset); ! 169: inttup.inttree = puttree(t, inttup.intrelid, inttup.intrelowner, mdINTEG); ! 170: ! 171: /* ! 172: ** Insert tuple into integrity catalog. ! 173: */ ! 174: ! 175: i = insert(&Intdes, &tid, &inttup, FALSE); ! 176: if (i < 0) ! 177: syserr("d_integ: insert"); ! 178: if (noclose(&Intdes) != 0) ! 179: syserr("d_integ: noclose int"); ! 180: ! 181: /* ! 182: ** Update relstat S_INTEG bit. ! 183: */ ! 184: ! 185: if (!bitset(S_INTEG, Qt.qt_rangev[rv].rngvdesc->reldum.relstat)) ! 186: { ! 187: opencatalog("relation", 2); ! 188: setkey(&Reldes, &relkey, inttup.intrelid, RELID); ! 189: setkey(&Reldes, &relkey, inttup.intrelowner, RELOWNER); ! 190: i = getequal(&Reldes, &relkey, &reltup, &tid); ! 191: if (i != 0) ! 192: syserr("d_integ: geteq"); ! 193: reltup.relstat |= S_INTEG; ! 194: i = replace(&Reldes, &tid, &reltup, FALSE); ! 195: if (i != 0) ! 196: syserr("d_integ: replace"); ! 197: if (noclose(&Reldes) != 0) ! 198: syserr("d_integ: noclose rel"); ! 199: } ! 200: ! 201: return (0); ! 202: } ! 203: ! 204: ! 205: makeidset(varno, tree, dset) ! 206: int varno; ! 207: QTREE *tree; ! 208: int dset[8]; ! 209: { ! 210: register int vn; ! 211: register QTREE *t; ! 212: ! 213: vn = varno; ! 214: t = tree; ! 215: ! 216: while (t != NULL) ! 217: { ! 218: if (t->sym.type == VAR && t->sym.value.sym_var.varno == vn) ! 219: lsetbit(t->sym.value.sym_var.attno, dset); ! 220: ! 221: /* handle left subtree recursively */ ! 222: makeidset(vn, t->left, dset); ! 223: ! 224: /* handle right subtree iteratively */ ! 225: t = t->right; ! 226: } ! 227: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.