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