|
|
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 <btree.h> ! 9: # include <sccs.h> ! 10: # include <errors.h> ! 11: ! 12: SCCSID(@(#)strategy.c 8.4 2/8/85) ! 13: ! 14: /* ! 15: ** STRATEGY ! 16: ** ! 17: ** Attempts to limit access scan to less than the entire De.ov_source ! 18: ** relation by finding a key which can be used for associative ! 19: ** access to the De.ov_source reln or an index thereon. The key is ! 20: ** constructed from domain-value specifications found in the ! 21: ** clauses of the qualification list using sub-routine findsimp ! 22: ** in findsimp.c and other subroutines in file key.c ! 23: */ ! 24: ! 25: strategy() ! 26: { ! 27: register int i, j, allexact; ! 28: struct accessparam sourceparm, indexparm; ! 29: struct index itup, rtup; ! 30: struct key lowikey[MAXKEYS+1], highikey[MAXKEYS+1]; ! 31: struct key lowbkey[MAXKEYS+1], highbkey[MAXKEYS+1]; ! 32: register DESC *d; ! 33: DESC *openindex(); ! 34: extern DESC Inddes; ! 35: char *tp; ! 36: long l_lid[MAXLID], h_lid[MAXLID]; ! 37: int keytype; ! 38: long last_lid(); ! 39: long page, l, t; ! 40: int lidsize; ! 41: struct locator tidloc; ! 42: extern int Btree_fd; ! 43: ! 44: # ifdef xOTR1 ! 45: if (tTf(70, 0)) ! 46: printf("STRATEGY\tSource=%.12s\tNewq = %d\n", ! 47: De.ov_source ? De.ov_source->reldum.relid : "(none)", ! 48: De.de_newq); ! 49: # endif ! 50: ! 51: while (De.de_newq) /* if De.de_newq=TRUE then compute a new strategy */ ! 52: /* NOTE: This while loop is executed only once */ ! 53: { ! 54: De.ov_scanr = De.ov_source; ! 55: ! 56: if (!De.ov_scanr) ! 57: return (1); /* return immediately if there is no source relation */ ! 58: ! 59: De.ov_fmode = NOKEY; /* assume a find mode with no key */ ! 60: ! 61: if (!De.ov_qlist) ! 62: break; /* if no qualification then you must scan entire rel */ ! 63: /* ! 64: ** Here we check for the special condition ! 65: ** of a where clause consisting only of a tid. ! 66: */ ! 67: if (tid_only_test()) ! 68: return(1); ! 69: ! 70: /* copy structure of source relation into sourceparm */ ! 71: paramd(De.ov_source, &sourceparm); ! 72: ! 73: /* if source is unkeyed and has no sec index then give up */ ! 74: if (sourceparm.mode == NOKEY && De.ov_source->reldum.relindxd <= 0 && !De.ov_source->reldum.reldim) ! 75: break; ! 76: ! 77: /* find all simple clauses if any */ ! 78: if (!findsimps()) ! 79: break; /* break if there are no simple clauses */ ! 80: ! 81: /* Four steps are now performed to try and find a key. ! 82: ** First if the relation is hashed then an exact key is search for ! 83: ** ! 84: ** Second if there are secondary indexes, then a search is made ! 85: ** for an exact key. If that fails then a check is made for ! 86: ** a range key. The result of the rangekey check is saved. ! 87: ** ! 88: ** A step to check for possible use of Btrees is made here, ! 89: ** although in actuality, an exact btreekey search is used ! 90: ** after an exact range key search but before a range key search. ! 91: ** A BTree range search is used only as a last alternative ! 92: ** to a no key search. ! 93: ** ! 94: ** Third if the relation is an ISAM a check is made for ! 95: ** an exact key or a range key. ! 96: ** ! 97: ** Fourth if there is a secondary index, then if step two ! 98: ** found a key, that key is used. ! 99: ** ! 100: ** Lastly, give up and scan the entire relation ! 101: */ ! 102: ! 103: /* step one. Try to find exact key on primary */ ! 104: if (exactkey(&sourceparm, De.ov_lkey_struct)) ! 105: { ! 106: De.ov_fmode = EXACTKEY; ! 107: break; ! 108: } ! 109: ! 110: /* step two. If there is an index, try to find an exactkey on one of them */ ! 111: if (De.ov_source->reldum.relindxd > 0) ! 112: { ! 113: ! 114: opencatalog("indexes", OR_READ); ! 115: setkey(&Inddes, &itup, De.ov_source->reldum.relid, IRELIDP); ! 116: setkey(&Inddes, &itup, De.ov_source->reldum.relowner, IOWNERP); ! 117: if (i = find(&Inddes, EXACTKEY, &De.ov_lotid, &De.ov_hitid, (char *)&itup)) ! 118: syserr("strategy:find indexes %d", i); ! 119: ! 120: while (!(i = get(&Inddes, &De.ov_lotid, &De.ov_hitid, (char *)&itup, NXTTUP))) ! 121: { ! 122: # ifdef xOTR1 ! 123: if (tTf(70, 3)) ! 124: printup(&Inddes, (char *)&itup); ! 125: # endif ! 126: if (!bequal(itup.irelidp, De.ov_source->reldum.relid, MAXNAME) || ! 127: !bequal(itup.iownerp, De.ov_source->reldum.relowner, 2)) ! 128: continue; ! 129: parami(&itup, &indexparm); ! 130: if (exactkey(&indexparm, De.ov_lkey_struct)) ! 131: { ! 132: De.ov_fmode = EXACTKEY; ! 133: d = openindex(itup.irelidi); ! 134: /* temp check for 6.0 index */ ! 135: if ((int) d->reldum.relindxd == -1) ! 136: ov_err(BADSECINDX); ! 137: De.ov_scanr = d; ! 138: break; ! 139: } ! 140: if (De.ov_fmode == LRANGEKEY) ! 141: continue; /* a range key on a s.i. has already been found */ ! 142: if (allexact = rangekey(&indexparm, lowikey, highikey)) ! 143: { ! 144: bmove((char *)&itup, (char *)&rtup, sizeof itup); /* save tuple */ ! 145: De.ov_fmode = LRANGEKEY; ! 146: } ! 147: } ! 148: if (i < 0) ! 149: syserr("stragery:bad get from index-rel %d", i); ! 150: /* If an exactkey on a secondary index was found, look no more. */ ! 151: if (De.ov_fmode == EXACTKEY) ! 152: break; ! 153: } ! 154: ! 155: /* attempt to use Btree in aiding search */ ! 156: if (i = btreekey(lowbkey, highbkey)) ! 157: { ! 158: if (i > 0) ! 159: De.ov_fmode = BTREEKEY; ! 160: else if (De.ov_fmode != LRANGEKEY) ! 161: /* use range key search over btree range search */ ! 162: { ! 163: keytype = i; ! 164: De.ov_fmode = BTREERANGE; ! 165: } ! 166: } ! 167: ! 168: /* step three. Look for a range key on primary */ ! 169: if (i = rangekey(&sourceparm, De.ov_lkey_struct, De.ov_hkey_struct)) ! 170: { ! 171: if (i < 0) ! 172: De.ov_fmode = EXACTKEY; ! 173: else if (De.ov_fmode == BTREEKEY) ! 174: /* use exact btree search over range search */ ! 175: { ! 176: bmove((char *) lowbkey, (char *) De.ov_lkey_struct, sizeof lowbkey); ! 177: bmove((char *) highbkey, (char *) De.ov_hkey_struct, sizeof highbkey); ! 178: } ! 179: else ! 180: De.ov_fmode = LRANGEKEY; ! 181: break; ! 182: } ! 183: ! 184: if (De.ov_fmode == BTREEKEY) ! 185: { ! 186: bmove((char *) lowbkey, (char *) De.ov_lkey_struct, sizeof lowbkey); ! 187: bmove((char *) highbkey, (char *) De.ov_hkey_struct, sizeof highbkey); ! 188: break; ! 189: } ! 190: ! 191: /* last step. If a secondary index range key was found, use it */ ! 192: if (De.ov_fmode == LRANGEKEY) ! 193: { ! 194: if (allexact < 0) ! 195: De.ov_fmode = EXACTKEY; ! 196: d = openindex(rtup.irelidi); ! 197: /* temp check for 6.0 index */ ! 198: if ((int) d->reldum.relindxd == -1) ! 199: ov_err(BADSECINDX); ! 200: De.ov_scanr = d; ! 201: bmove((char *)lowikey, (char *)De.ov_lkey_struct, sizeof lowikey); ! 202: bmove((char *)highikey, (char *)De.ov_hkey_struct, sizeof highikey); ! 203: break; ! 204: } ! 205: ! 206: /* nothing will work. give up! */ ! 207: break; ! 208: ! 209: } ! 210: ! 211: /* check for De.de_newq = FALSE and no source relation */ ! 212: if (!De.ov_scanr) ! 213: return (1); ! 214: /* ! 215: ** At this point the strategy is determined. ! 216: ** ! 217: ** If De.ov_fmode is EXACTKEY then De.ov_lkey_struct contains ! 218: ** the pointers to the keys. ! 219: ** ! 220: ** If De.ov_fmode is LRANGEKEY then De.ov_lkey_struct contains ! 221: ** the pointers to the low keys and De.ov_hkey_struct ! 222: ** contains pointers to the high keys. ! 223: ** ! 224: ** If De.ov_fmode is BTREEKEY then De.ov_lkey_struct contains ! 225: ** pointers to the key lid. ! 226: ** ! 227: ** If De.ov_fmode is BTREERANGE then lowbkey contains pointers ! 228: ** to the low key lid and highbkey contains pointers to the ! 229: ** high key lid. ! 230: ** ! 231: ** If De.ov_fmode is NOKEY, then a full scan will be performed ! 232: */ ! 233: # ifdef xOTR1 ! 234: if (tTf(70, -1)) ! 235: printf("De.ov_fmode= %d\n",De.ov_fmode); ! 236: # endif ! 237: ! 238: if (De.ov_fmode == BTREERANGE) ! 239: /* requires special type of search to limit tid scan */ ! 240: { ! 241: for (i = 0; i < De.ov_scanr->reldum.reldim; ++i) ! 242: { ! 243: l_lid[i] = 0; ! 244: h_lid[i] = 0; ! 245: } ! 246: lidsize = LIDSIZE * De.ov_scanr->reldum.reldim; ! 247: /* get low lids */ ! 248: if (keytype == -1 || keytype == -3) ! 249: { ! 250: tp = De.ov_keyl + De.ov_scanr->reldum.relwid - lidsize; ! 251: bmove(l_lid, tp, lidsize); ! 252: setallkey(lowbkey, De.ov_keyl); ! 253: bmove(tp, l_lid, lidsize); ! 254: } ! 255: /* get high lids */ ! 256: if (keytype == -2 || keytype == -3) ! 257: { ! 258: tp = De.ov_keyh + De.ov_scanr->reldum.relwid - lidsize; ! 259: bmove(h_lid, tp, lidsize); ! 260: setallkey(highbkey, De.ov_keyh); ! 261: bmove(tp, h_lid, lidsize); ! 262: } ! 263: Btree_fd = De.ov_scanr->btree_fd; ! 264: /* scan through lids to fill in unprovided lids and to check ! 265: ** for lids that are too big ! 266: */ ! 267: page = RT; ! 268: for (i = 0; i < De.ov_scanr->reldum.reldim; ++i) ! 269: { ! 270: if (l_lid[i] <= 0) ! 271: l_lid[i] = 1; ! 272: l = last_lid(page) - 1; ! 273: if (h_lid < 0) ! 274: return(0); ! 275: if (!h_lid[i] || h_lid[i] > l) ! 276: h_lid[i] = l; ! 277: if ((t = get_tid(page, h_lid[i], &tidloc)) < 0) ! 278: syserr("bad gettid in strategy, lid = %ld\n", h_lid[i]); ! 279: page = t; ! 280: } ! 281: /* check whether lo > hi */ ! 282: for (i = 0; i < De.ov_scanr->reldum.reldim; ++i) ! 283: if (l_lid[i] < h_lid[i]) ! 284: break; ! 285: else if (l_lid[i] > h_lid[i]) ! 286: return(0); ! 287: # ifdef xOTR1 ! 288: if (tTf(70,0)) ! 289: for (i = 0 ; i < De.ov_scanr->reldum.reldim; ++i) ! 290: printf("hi = %ld, lo = %ld\n", h_lid[i], l_lid[i]); ! 291: # endif ! 292: /* find the smallest and largest possible tids of the lids ! 293: ** within the provided range */ ! 294: btreerange(De.ov_scanr, l_lid, h_lid, &De.ov_lotid, &De.ov_hitid); ! 295: } ! 296: else ! 297: { ! 298: /* set up the key tuples */ ! 299: if (De.ov_fmode != NOKEY) ! 300: { ! 301: if (setallkey(De.ov_lkey_struct, De.ov_keyl)) ! 302: return (0); /* query false. There is a simple ! 303: ** clause which can never be satisfied. ! 304: ** These simple clauses can be choosey! ! 305: */ ! 306: } ! 307: ! 308: if (i = find(De.ov_scanr, De.ov_fmode, &De.ov_lotid, &De.ov_hitid, De.ov_keyl)) ! 309: syserr("strategy:find1 %.12s, %d", De.ov_scanr->reldum.relid, i); ! 310: ! 311: if (De.ov_fmode == LRANGEKEY) ! 312: { ! 313: setallkey(De.ov_hkey_struct, De.ov_keyh); ! 314: if (i = find(De.ov_scanr, HRANGEKEY, &De.ov_lotid, &De.ov_hitid, De.ov_keyh)) ! 315: syserr("strategy:find2 %.12s, %d", De.ov_scanr->reldum.relid, i); ! 316: } ! 317: } ! 318: ! 319: # ifdef xOTR1 ! 320: if (tTf(70, 1)) ! 321: { ! 322: printf("Lo"); ! 323: dumptid(&De.ov_lotid); ! 324: printf("Hi"); ! 325: dumptid(&De.ov_hitid); ! 326: } ! 327: # endif ! 328: ! 329: return (1); ! 330: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.