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: }