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