|
|
1.1 ! root 1: # include <ingres.h> ! 2: # include <aux.h> ! 3: # include <symbol.h> ! 4: # include <tree.h> ! 5: # include <catalog.h> ! 6: # include "../decomp/globs.h" ! 7: # include "strategy.h" ! 8: # include <btree.h> ! 9: # include <sccs.h> ! 10: ! 11: SCCSID(@(#)key.c 8.4 3/20/85) ! 12: ! 13: ! 14: ! 15: /* ! 16: ** Exactkey checks to see if the relation described ! 17: ** by "ap" can be used in a hashed scan. ! 18: ** All the key domains of the relation must ! 19: ** have simple clauses of equality associated ! 20: ** with them in the qualification. ! 21: ** ! 22: ** Returns 0 if the relation can't be used. ! 23: ** ! 24: ** Returns > 0 if it can. ! 25: */ ! 26: ! 27: exactkey(ap, key) ! 28: struct accessparam *ap; ! 29: struct key *key; ! 30: { ! 31: register struct accessparam *a; ! 32: register struct key *k; ! 33: register struct simp *s; ! 34: int d, i, j; ! 35: ! 36: # ifdef xOTR1 ! 37: if (tTf(85, -1)) ! 38: printf("Exactkey\n"); ! 39: # endif ! 40: ! 41: a = ap; ! 42: k = key; ! 43: i = 0; ! 44: if (a->mode == EXACTKEY) ! 45: { ! 46: ! 47: for (i = 0; d = a->keydno[i]; i++) ! 48: { ! 49: ! 50: s = De.ov_simp; ! 51: for (j = 0; j < De.ov_nsimp; j++) ! 52: { ! 53: if (s->relop == opEQ && s->att == d) ! 54: { ! 55: k->keysym = s->const; ! 56: k->dnumber = (a->sec_index == TRUE) ? i+1 : d; ! 57: k++; ! 58: # ifdef xOTR1 ! 59: if (tTf(85, 1)) ! 60: { ! 61: printf("exact key on dom %d\tvalue=", d); ! 62: prsym(s->const); ! 63: } ! 64: # endif ! 65: break; ! 66: } ! 67: s++; ! 68: } ! 69: if (j == De.ov_nsimp) ! 70: { ! 71: i = 0; /* failure. at lease one key isn't used */ ! 72: break; ! 73: } ! 74: } ! 75: k->dnumber = 0; /* mark end of list */ ! 76: } ! 77: # ifdef xOTR1 ! 78: if (tTf(85, 9)) ! 79: printf("exactkey returning %d\n", i); ! 80: # endif ! 81: return (i); ! 82: } ! 83: ! 84: /* ! 85: ** Attempts to use the B-Tree for retrieval. ! 86: ** There are two types of searches possible, exact and range searches. ! 87: ** In order for an exact search to be possible, there must be a simple ! 88: ** equality clause using the lid field. ! 89: ** For a range search, either or both lid ranges must be provided. ! 90: ** ! 91: ** Returns 1 exact BTREEKEY search possible ! 92: ** -1 low lid key provided ! 93: ** -2 high lid key provided ! 94: ** -3 both lids provided ! 95: */ ! 96: ! 97: btreekey(lkey, hkey) ! 98: ! 99: struct key *lkey, *hkey; ! 100: { ! 101: register struct key *l, *h; ! 102: register struct simp *s; ! 103: int i, j, k; ! 104: int provided[MAXLID]; ! 105: SYMBOL *(save[MAXLID]); ! 106: ! 107: # ifdef xOTR1 ! 108: if (tTf(85, -1)) ! 109: printf("Btreekey\n"); ! 110: # endif ! 111: ! 112: l = lkey; ! 113: h = hkey; ! 114: i = 0; ! 115: for (j = 0; j < MAXLID; ++j) ! 116: provided[j] = 0; ! 117: if (De.ov_scanr->reldum.reldim > 0 && De.ov_scanr->reldum.reltups > 0) ! 118: { ! 119: s = De.ov_simp; ! 120: for (j = 0; j < De.ov_nsimp; ++j) ! 121: { ! 122: if (s->att >= De.ov_scanr->reldum.relatts - De.ov_scanr->reldum.reldim + 1) ! 123: { ! 124: if (s->relop == opEQ || s->relop == opGTGE) ! 125: { ! 126: l->keysym = s->const; ! 127: l->dnumber = s->att; ! 128: if (s->relop == opEQ) ! 129: { ! 130: provided[De.ov_scanr->reldum.relatts - s->att] = 1; ! 131: save[De.ov_scanr->reldum.relatts - s->att] = l->keysym; ! 132: ! 133: } ! 134: else if (i == -2) ! 135: i = -3; ! 136: else if (!i) ! 137: i = -1; ! 138: ++l; ! 139: } ! 140: if (s->relop == opLTLE) ! 141: { ! 142: h->keysym = s->const; ! 143: h->dnumber = s->att; ! 144: h++; ! 145: if (i == -1) ! 146: i = -3; ! 147: else if (!i) ! 148: i = -2; ! 149: } ! 150: } ! 151: s++; ! 152: for (k = 0; k < De.ov_scanr->reldum.reldim; ++k) ! 153: if (!provided[k]) ! 154: break; ! 155: if (k >= De.ov_scanr->reldum.reldim) ! 156: { ! 157: i = 1; ! 158: break; ! 159: } ! 160: } ! 161: if (i != 1) ! 162: for (k = 0; k < De.ov_scanr->reldum.reldim; ++k) ! 163: if (provided[k]) ! 164: { ! 165: h->keysym = save[k]; ! 166: h->dnumber = De.ov_scanr->reldum.relatts - k; ! 167: h++; ! 168: i = -3; ! 169: } ! 170: /* mark ends of lists */ ! 171: l->dnumber = 0; ! 172: h->dnumber = 0; ! 173: } ! 174: # ifdef xOTR1 ! 175: if (tTf(85, 9)) ! 176: printf("btreekey returning %d\n", i); ! 177: # endif ! 178: return(i); ! 179: } ! 180: /* ! 181: ** Range key checks if the relation described by ! 182: ** "ap" is ISAM and there are simple clauses ! 183: ** on the first key and any additional keys. ! 184: ** ! 185: ** Rangekey accumulates both high and low keys, ! 186: ** which are not necessary the same. If it ! 187: ** every finds a high or a low key on the first ! 188: ** domain of the relation then success=TRUE. ! 189: ** ! 190: ** Returns 1 if Rangekey ok ! 191: ** 0 if Rangekey is not ok ! 192: ** -1 if Rangekey ok and all clauses are equality clauses ! 193: */ ! 194: ! 195: rangekey(ap, l, h) ! 196: struct accessparam *ap; ! 197: struct key *l; ! 198: struct key *h; ! 199: { ! 200: register struct key *low, *high; ! 201: register struct simp *s; ! 202: struct accessparam *a; ! 203: int sec_indx, d, i; ! 204: int rel, success, ns, lowkey, allexact; ! 205: ! 206: # ifdef xOTR1 ! 207: if (tTf(85, 5)) ! 208: printf("Rangekey\n"); ! 209: # endif ! 210: ! 211: a = ap; ! 212: sec_indx = a->sec_index == TRUE; ! 213: low = l; ! 214: high = h; ! 215: allexact = -1; /* assume all clauses equality clauses */ ! 216: s = De.ov_simp; ! 217: success = FALSE; ! 218: if (a->mode == LRANGEKEY) ! 219: { ! 220: ! 221: for (ns = 0; ns < De.ov_nsimp; ns++) ! 222: { ! 223: rel = s->relop; ! 224: for (i = 0; d = a->keydno[i]; i++) ! 225: { ! 226: if (d == s->att) ! 227: { ! 228: /* this is either a high range value or low range value */ ! 229: lowkey = (rel == opGTGE); ! 230: if (lowkey || rel == opEQ) ! 231: { ! 232: /* low range key */ ! 233: # ifdef xOTR1 ! 234: if (tTf(85, 6)) ! 235: printf("low key on dom %d\t", d); ! 236: # endif ! 237: low->keysym = s->const; ! 238: low->dnumber = sec_indx ? i+1 : d; ! 239: low++; ! 240: } ! 241: if (!lowkey || rel == opEQ) ! 242: { ! 243: /* high range key */ ! 244: # ifdef xOTR1 ! 245: if (tTf(85, 6)) ! 246: printf("high key on dom %d\t", d); ! 247: # endif ! 248: high->keysym = s->const; ! 249: high->dnumber = sec_indx ? i+1 : d; ! 250: high++; ! 251: } ! 252: # ifdef xOTR1 ! 253: if (tTf(85, 6)) ! 254: prsym(s->const); ! 255: # endif ! 256: if (i == 0) ! 257: success = TRUE; ! 258: if (rel != opEQ) ! 259: allexact = 1; /* at least one inequality */ ! 260: break; ! 261: } ! 262: } ! 263: s++; /* try next simple clause */ ! 264: } ! 265: } ! 266: ! 267: high->dnumber = 0; /* mark end of list */ ! 268: low->dnumber = 0; /* mask end of list */ ! 269: ! 270: /* if success then return whether all clauses were equality */ ! 271: if (success) ! 272: success = allexact; ! 273: ! 274: # ifdef xOTR1 ! 275: if (tTf(85, 5)) ! 276: printf("rangekey returning %d\n", success); ! 277: # endif ! 278: return (success); ! 279: } ! 280: /* ! 281: ** Setallkey takes a key struct, decodes it and ! 282: ** calls setkey with each value. ! 283: ** ! 284: ** Called from strategy(). ! 285: ** ! 286: ** returns 0 if ok. ! 287: ** returns -1 in the special case of a deblanked hashkey ! 288: ** being bigger than the corresponding domain. ! 289: */ ! 290: ! 291: setallkey(relkey, keytuple) ! 292: struct key *relkey; ! 293: char *keytuple; ! 294: { ! 295: register struct key *k; ! 296: register SYMBOL *sk; ! 297: register int dnum; ! 298: struct symbol **s; ! 299: char *p, temp[256]; ! 300: int l; ! 301: ! 302: clearkeys(De.ov_scanr); ! 303: k = relkey; ! 304: while (dnum = k->dnumber) ! 305: { ! 306: s = &k->keysym; ! 307: sk = (SYMBOL *) De.ov_stack; ! 308: getsymbol(sk, &s); /* copy symbol to stack. caution:getsym changes the value of s. */ ! 309: rcvt(sk, De.ov_scanr->relfrmt[dnum], De.ov_scanr->relfrml[dnum]); /* convert key to correct type */ ! 310: p = (char *)&sk->value; ! 311: ! 312: if (sk->type == CHAR) ! 313: { ! 314: /* ! 315: ** The length of a character key must ! 316: ** be made equal to the domain length. ! 317: ** The key is copied to a temp place ! 318: ** and a null byte is inserted at the ! 319: ** end. In addition, if the key without ! 320: ** blanks is longer than the domain and ! 321: ** this is an exactkey, then the query ! 322: ** is false. ! 323: */ ! 324: p = temp; ! 325: l = cmove(sk, p); /* copy symbol to temp removing blanks & nulls */ ! 326: # ifdef xOTR1 ! 327: if (tTf(86, 9)) ! 328: printf("length is %d\n", l); ! 329: # endif ! 330: if (De.ov_fmode == EXACTKEY && l > (De.ov_scanr->relfrml[dnum] & I1MASK)) ! 331: /* key too large. qualification is false */ ! 332: return (-1); ! 333: } ! 334: setkey(De.ov_scanr, keytuple, p, dnum); /* set the key */ ! 335: k++; ! 336: } ! 337: # ifdef xOTR1 ! 338: if (tTf(86, 8)) ! 339: printup(De.ov_scanr, keytuple); ! 340: # endif ! 341: return (0); ! 342: } ! 343: /* ! 344: ** Cmove copies a char symbol into "dest". ! 345: ** It stops when the length is reached or ! 346: ** when a null byte is found. ! 347: ** ! 348: ** returns the number of non-blank chars ! 349: ** in the string. ! 350: */ ! 351: ! 352: cmove(sym, dest) ! 353: SYMBOL *sym; ! 354: char *dest; ! 355: { ! 356: register char *d, *s; ! 357: register int l; ! 358: int blank; ! 359: ! 360: s = sym->value.sym_data.cptype; /* s points to the char string */ ! 361: d = dest; ! 362: blank = 0; ! 363: ! 364: for (l = (sym->len & I1MASK); l--; s++) ! 365: { ! 366: *d++ = *s; ! 367: if (*s == ' ') ! 368: blank++; ! 369: if (*s == '\0') ! 370: { ! 371: d--; ! 372: break; ! 373: } ! 374: } ! 375: ! 376: *d = '\0'; ! 377: return ((d - dest) - blank); /* return length of string */ ! 378: } ! 379: /* ! 380: ** Indexcheck is called by scan() to check whether ! 381: ** a secondary index tuple satisfies the simple ! 382: ** clauses under which it was scanned. ! 383: ** ! 384: ** Returns 1 if the tuple is ok, ! 385: ** 0 otherwise. ! 386: */ ! 387: ! 388: indexcheck() ! 389: { ! 390: register int i; ! 391: ! 392: if (De.ov_fmode == EXACTKEY) ! 393: i = keycheck(De.ov_lkey_struct, De.ov_keyl, 0); /* check for equality */ ! 394: else ! 395: { ! 396: i = keycheck(De.ov_lkey_struct, De.ov_keyl, 1); /* check for >= */ ! 397: /* If the lowkey passed, check the highkey also */ ! 398: if (i) ! 399: i = keycheck(De.ov_hkey_struct, De.ov_keyh, -1); /* check for <= */ ! 400: } ! 401: # ifdef xOTR1 ! 402: if (tTf(86, 10)) ! 403: printf("indexcheck ret %d\n", i); ! 404: # endif ! 405: return (i); ! 406: } ! 407: /* ! 408: ** Keycheck compares De.ov_intup with keytuple ! 409: ** according to the domains specified in the ! 410: ** "keys" struct. ! 411: ** ! 412: ** mode is either >0, =0, <0 depending on ! 413: ** whether check is for De.ov_intup >= keytuple, ! 414: ** De.ov_intup == keytuple, De.ov_intup <= keytuple respectively ! 415: ** ! 416: ** returns TRUE or FALSE accordingly. ! 417: */ ! 418: ! 419: keycheck(keys, keytuple, mode) ! 420: struct key *keys; ! 421: char *keytuple; ! 422: int mode; ! 423: { ! 424: register struct key *k; ! 425: register char *kp; ! 426: register int dnum; ! 427: int offset, i, success; ! 428: ! 429: kp = keytuple; ! 430: success = TRUE; ! 431: ! 432: for (k = keys; dnum = k->dnumber; k++) ! 433: { ! 434: ! 435: offset = De.ov_scanr->reloff[dnum]; ! 436: if (i = icompare(&De.ov_intup[offset], &kp[offset], De.ov_scanr->relfrmt[dnum], De.ov_scanr->relfrml[dnum] & I1MASK)) ! 437: { ! 438: if (i < 0 && mode < 0 || i > 0 && mode > 0) ! 439: continue; ! 440: success = FALSE; ! 441: break; ! 442: } ! 443: } ! 444: return (success); ! 445: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.