1: # include <ingres.h> 2: # include <aux.h> 3: # include <catalog.h> 4: # include <access.h> 5: # include <tree.h> 6: # include <symbol.h> 7: # include "qrymod.h" 8: # include <sccs.h> 9: 10: SCCSID(@(#)integrity.c 8.3 5/12/85) 11: 12: /* 13: ** INTEGRITY.C -- Integrity Constraint Processor 14: ** 15: ** This module contains the integrity constraint processor. This 16: ** processor modifies the query to add integrity constraints. 17: ** 18: ** Currently only single-variable aggregate-free constraints are 19: ** handled. Thus the algorithm is reduced to scanning the tree 20: ** for each variable modified and appending the constraints for 21: ** that variable to the tree. 22: ** 23: ** Parameters: 24: ** none 25: ** 26: ** Returns: 27: ** The root of the modified tree. 28: ** 29: ** Side Effects: 30: ** Much relation I/O. 31: ** Modifies the tree in place, so the previous one is 32: ** lost. 33: ** 34: ** Trace Flags: 35: ** 40 -> 49 36: */ 37: 38: extern DESC Intdes; 39: 40: QTREE * 41: integrity(root) 42: QTREE *root; 43: { 44: register QTREE *r; 45: int dset[8]; 46: register QTREE *p; 47: register int i; 48: auto QTREE *iqual; 49: struct integrity inttup, intkey; 50: struct tup_id hitid, lotid; 51: extern QTREE *gettree(); 52: extern QTREE *norml(); 53: 54: # ifdef xQTR1 55: tTfp(40, -1, "\n->INTEGRITY\n"); 56: # endif 57: 58: r = root; 59: 60: /* 61: ** Check to see if we should apply the integrity 62: ** algorithm. 63: ** 64: ** This means checking to insure that we have an update 65: ** and seeing if any integrity constraints apply. 66: */ 67: 68: if (Qt.qt_qmode == mdRETR || Qt.qt_qmode == mdRET_UNI || 69: (Qt.qt_rangev[Qt.qt_resvar].rngvdesc->reldum.relstat & S_INTEG) == 0) 70: { 71: # ifdef xQTR2 72: tTfp(40, 0, "->INTEGRITY: no integ\n"); 73: # endif 74: return(r); 75: } 76: 77: /* 78: ** Create a set of the domains updated in this query. 79: */ 80: 81: for (i = 0; i < 8; i++) 82: dset[i] = 0; 83: for (p = r->left; p != NULL && p->sym.type != TREE; p = p->left) 84: { 85: # ifdef xQTR3 86: if (p->sym.type != RESDOM) 87: syserr("integrity: RESDOM %d", p->sym.type); 88: # endif 89: lsetbit(p->sym.value.sym_resdom.resno, dset); 90: } 91: 92: # ifdef xQTR3 93: if (p == NULL) 94: syserr("integrity: NULL LHS"); 95: # endif 96: # ifdef xQTR1 97: if (tTf(40, 1)) 98: pr_set(dset, "dset"); 99: # endif 100: 101: /* 102: ** Scan integrity catalog for possible tuples. If found, 103: ** include them in the integrity qualification. 104: */ 105: 106: iqual = NULL; 107: opencatalog("integrities", OR_READ); 108: setkey(&Intdes, &intkey, Qt.qt_rangev[Qt.qt_resvar].rngvdesc->reldum.relid, INTRELID); 109: setkey(&Intdes, &intkey, Qt.qt_rangev[Qt.qt_resvar].rngvdesc->reldum.relowner, INTRELOWNER); 110: find(&Intdes, EXACTKEY, &lotid, &hitid, &intkey); 111: 112: while ((i = get(&Intdes, &lotid, &hitid, &inttup, TRUE)) == 0) 113: { 114: if (kcompare(&Intdes, &intkey, &inttup) != 0) 115: continue; 116: 117: # ifdef xQTR1 118: if (tTf(40, 2)) 119: printup(&Intdes, &inttup); 120: # endif 121: 122: /* check for some domain set overlap */ 123: for (i = 0; i < 8; i++) 124: if ((dset[i] & inttup.intdomset[i]) != 0) 125: break; 126: if (i >= 8) 127: continue; 128: 129: /* some domain matches, include in integrity qual */ 130: i = Qt.qt_resvar; 131: p = gettree(Qt.qt_rangev[i].rngvdesc->reldum.relid, 132: Qt.qt_rangev[i].rngvdesc->reldum.relowner, 133: mdINTEG, inttup.inttree, FALSE); 134: # ifdef xQTR1 135: if (tTf(40, 3)) 136: treepr(p, "int_qual"); 137: # endif 138: 139: /* trim off (null) target list */ 140: p = p->right; 141: 142: /* merge the 'integrity' var into the Qt.qt_resvar */ 143: i = inttup.intresvar; 144: if (Qt.qt_remap[i] >= 0) 145: i = Qt.qt_remap[i]; 146: mergevar(i, Qt.qt_resvar, p); 147: 148: /* add to integrity qual */ 149: if (iqual == NULL) 150: iqual = p; 151: else 152: appqual(p, iqual); 153: } 154: if (i < 0) 155: syserr("integrity: get %d", i); 156: 157: /* 158: ** Clean up the integrity qualification so that it will merge 159: ** nicely into the tree, and then append it to the user's 160: ** qualification. 161: */ 162: 163: if (iqual != NULL) 164: { 165: /* replace VAR nodes by corresponding user afcn */ 166: subsvars(&iqual, Qt.qt_resvar, r->left, Qt.qt_qmode); 167: 168: /* append to tree and normalize */ 169: appqual(iqual, r); 170: # ifdef xQTR3 171: if (tTf(40, 8)) 172: treepr(r, "Unnormalized tree"); 173: # endif 174: r->right = norml(trimqlend(r->right)); 175: } 176: 177: # ifdef xQTR1 178: if (tTf(40, 15)) 179: treepr(r, "INTEGRITY->"); 180: # endif 181: 182: return (r); 183: }