|
|
1.1 ! root 1: # include <ingres.h> ! 2: # include <aux.h> ! 3: # include <catalog.h> ! 4: # include <symbol.h> ! 5: # include <tree.h> ! 6: # include "../decomp/globs.h" ! 7: # include "strategy.h" ! 8: # include <sccs.h> ! 9: ! 10: SCCSID(@(#)strategy.c 7.2 9/12/83) ! 11: ! 12: /* ! 13: ** STRATEGY ! 14: ** ! 15: ** Attempts to limit access scan to less than the entire De.ov_source ! 16: ** relation by finding a key which can be used for associative ! 17: ** access to the De.ov_source reln or an index thereon. The key is ! 18: ** constructed from domain-value specifications found in the ! 19: ** clauses of the qualification list using sub-routine findsimp ! 20: ** in findsimp.c and other subroutines in file key.c ! 21: */ ! 22: ! 23: ! 24: ! 25: strategy() ! 26: { ! 27: register int i, allexact; ! 28: struct accessparam sourceparm, indexparm; ! 29: struct index itup, rtup; ! 30: struct key lowikey[MAXKEYS+1], highikey[MAXKEYS+1]; ! 31: register DESC *d; ! 32: DESC *openindex(); ! 33: extern DESC Inddes; ! 34: ! 35: # ifdef xOTR1 ! 36: if (tTf(70, 0)) ! 37: printf("STRATEGY\tSource=%.12s\tNewq = %d\n", ! 38: De.ov_source ? De.ov_source->reldum.relid : "(none)", ! 39: De.de_newq); ! 40: # endif ! 41: ! 42: while (De.de_newq) /* if De.de_newq=TRUE then compute a new strategy */ ! 43: /* NOTE: This while loop is executed only once */ ! 44: { ! 45: De.ov_scanr = De.ov_source; ! 46: ! 47: if (!De.ov_scanr) ! 48: return (1); /* return immediately if there is no source relation */ ! 49: ! 50: De.ov_fmode = NOKEY; /* assume a find mode with no key */ ! 51: ! 52: if (!De.ov_qlist) ! 53: break; /* if no qualification then you must scan entire rel */ ! 54: ! 55: /* ! 56: ** Here we check for the special condition ! 57: ** of a where clause consisting only of a tid. ! 58: */ ! 59: if ( tid_only_test() ) ! 60: return (1); ! 61: ! 62: /* copy structure of source relation into sourceparm */ ! 63: paramd(De.ov_source, &sourceparm); ! 64: ! 65: /* if source is unkeyed and has no sec index then give up */ ! 66: if (sourceparm.mode == NOKEY && De.ov_source->reldum.relindxd <= 0) ! 67: break; ! 68: ! 69: /* find all simple clauses if any */ ! 70: if (!findsimps()) ! 71: break; /* break if there are no simple clauses */ ! 72: ! 73: /* Four steps are now performed to try and find a key. ! 74: ** First if the relation is hashed then an exact key is searched for. ! 75: ** ! 76: ** Second if there are secondary indexes, then a search is made ! 77: ** for an exact key. If that fails then a check is made for ! 78: ** a range key. The result of the rangekey check is saved. ! 79: ** ! 80: ** Third if the relation is an ISAM a check is made for ! 81: ** an exact key or a range key. ! 82: ** ! 83: ** Fourth if there is a secondary index, then if step two ! 84: ** found a key, that key is used. ! 85: ** ! 86: ** Lastly, give up and scan the entire relation ! 87: */ ! 88: ! 89: /* step one. Try to find exact key on primary */ ! 90: if (exactkey(&sourceparm, De.ov_lkey_struct)) ! 91: { ! 92: De.ov_fmode = EXACTKEY; ! 93: break; ! 94: } ! 95: ! 96: /* step two. If there is an index, try to find an exactkey on one of them */ ! 97: if (De.ov_source->reldum.relindxd) ! 98: { ! 99: ! 100: opencatalog("indexes", 0); ! 101: setkey(&Inddes, &itup, De.ov_source->reldum.relid, IRELIDP); ! 102: setkey(&Inddes, &itup, De.ov_source->reldum.relowner, IOWNERP); ! 103: if (i = find(&Inddes, EXACTKEY, &De.ov_lotid, &De.ov_hitid, (char *)&itup)) ! 104: syserr("strategy:find indexes %d", i); ! 105: ! 106: while (!(i = get(&Inddes, &De.ov_lotid, &De.ov_hitid, (char *)&itup, NXTTUP))) ! 107: { ! 108: # ifdef xOTR1 ! 109: if (tTf(70, 3)) ! 110: printup(&Inddes, (char *)&itup); ! 111: # endif ! 112: if (!bequal(itup.irelidp, De.ov_source->reldum.relid, MAXNAME) || ! 113: !bequal(itup.iownerp, De.ov_source->reldum.relowner, 2)) ! 114: continue; ! 115: parami(&itup, &indexparm); ! 116: if (exactkey(&indexparm, De.ov_lkey_struct)) ! 117: { ! 118: De.ov_fmode = EXACTKEY; ! 119: d = openindex(itup.irelidi); ! 120: /* temp check for 6.0 index */ ! 121: if ((int) d->reldum.relindxd == -1) ! 122: ov_err(BADSECINDX); ! 123: De.ov_scanr = d; ! 124: break; ! 125: } ! 126: if (De.ov_fmode == LRANGEKEY) ! 127: continue; /* a range key on a s.i. has already been found */ ! 128: if (allexact = rangekey(&indexparm, lowikey, highikey)) ! 129: { ! 130: bmove((char *)&itup, (char *)&rtup, sizeof itup); /* save tuple */ ! 131: De.ov_fmode = LRANGEKEY; ! 132: } ! 133: } ! 134: if (i < 0) ! 135: syserr("stragery:bad get from index-rel %d", i); ! 136: /* If an exactkey on a secondary index was found, look no more. */ ! 137: if (De.ov_fmode == EXACTKEY) ! 138: break; ! 139: } ! 140: ! 141: ! 142: ! 143: /* step three. Look for a range key on primary */ ! 144: if (i = rangekey(&sourceparm, De.ov_lkey_struct, De.ov_hkey_struct)) ! 145: { ! 146: if (i < 0) ! 147: De.ov_fmode = EXACTKEY; ! 148: else ! 149: De.ov_fmode = LRANGEKEY; ! 150: break; ! 151: } ! 152: ! 153: /* last step. If a secondary index range key was found, use it */ ! 154: if (De.ov_fmode == LRANGEKEY) ! 155: { ! 156: if (allexact < 0) ! 157: De.ov_fmode = EXACTKEY; ! 158: d = openindex(rtup.irelidi); ! 159: /* temp check for 6.0 index */ ! 160: if ((int) d->reldum.relindxd == -1) ! 161: ov_err(BADSECINDX); ! 162: De.ov_scanr = d; ! 163: bmove((char *)lowikey, (char *)De.ov_lkey_struct, sizeof lowikey); ! 164: bmove((char *)highikey, (char *)De.ov_hkey_struct, sizeof highikey); ! 165: break; ! 166: } ! 167: ! 168: /* nothing will work. give up! */ ! 169: break; ! 170: ! 171: } ! 172: ! 173: /* check for De.de_newq = FALSE and no source relation */ ! 174: if (!De.ov_scanr) ! 175: return (1); ! 176: /* ! 177: ** At this point the strategy is determined. ! 178: ** ! 179: ** If De.ov_fmode is EXACTKEY then De.ov_lkey_struct contains ! 180: ** the pointers to the keys. ! 181: ** ! 182: ** If De.ov_fmode is LRANGEKEY then De.ov_lkey_struct contains ! 183: ** the pointers to the low keys and De.ov_hkey_struct ! 184: ** contains pointers to the high keys. ! 185: ** ! 186: ** If De.ov_fmode is NOKEY, then a full scan will be performed ! 187: */ ! 188: # ifdef xOTR1 ! 189: if (tTf(70, -1)) ! 190: printf("De.ov_fmode= %d\n",De.ov_fmode); ! 191: # endif ! 192: ! 193: /* set up the key tuples */ ! 194: if (De.ov_fmode != NOKEY) ! 195: { ! 196: if (setallkey(De.ov_lkey_struct, De.ov_keyl)) ! 197: return (0); /* query false. There is a simple ! 198: ** clause which can never be satisfied. ! 199: ** These simple clauses can be choosey! ! 200: */ ! 201: } ! 202: ! 203: if (i = find(De.ov_scanr, De.ov_fmode, &De.ov_lotid, &De.ov_hitid, De.ov_keyl)) ! 204: syserr("strategy:find1 %.12s, %d", De.ov_scanr->reldum.relid, i); ! 205: ! 206: if (De.ov_fmode == LRANGEKEY) ! 207: { ! 208: setallkey(De.ov_hkey_struct, De.ov_keyh); ! 209: if (i = find(De.ov_scanr, HRANGEKEY, &De.ov_lotid, &De.ov_hitid, De.ov_keyh)) ! 210: syserr("strategy:find2 %.12s, %d", De.ov_scanr->reldum.relid, i); ! 211: } ! 212: ! 213: # ifdef xOTR1 ! 214: if (tTf(70, 1)) ! 215: { ! 216: printf("Lo"); ! 217: dumptid(&De.ov_lotid); ! 218: printf("Hi"); ! 219: dumptid(&De.ov_hitid); ! 220: } ! 221: # endif ! 222: ! 223: return (1); ! 224: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.