1: # include "../ingres.h" 2: # include "../aux.h" 3: # include "../symbol.h" 4: # include "../tree.h" 5: # include "../pipes.h" 6: # include "ovqp.h" 7: # include "strategy.h" 8: 9: 10: exactkey(ap, key) 11: struct accessparam *ap; 12: struct key *key; 13: 14: /* 15: ** Exactkey checks to see if the relation described 16: ** by "ap" can be used in a hashed scan. 17: ** All the key domains of the relation must 18: ** have simple clauses of equality associated 19: ** with them in the qualification. 20: ** 21: ** Returns 0 if the relation can't be used. 22: ** 23: ** Returns > 0 if it can. 24: */ 25: { 26: register struct accessparam *a; 27: register struct key *k; 28: register struct simp *s; 29: int d, i, j; 30: 31: # ifdef xOTR1 32: if (tTf(25, -1)) 33: printf("Exactkey\n"); 34: # endif 35: 36: a = ap; 37: k = key; 38: i = 0; 39: if (a->mode == EXACTKEY) 40: { 41: 42: for (i = 0; d = a->keydno[i]; i++) 43: { 44: 45: s = Simp; 46: for (j = 0; j < Nsimp; j++) 47: { 48: if (s->relop == opEQ && s->att == d) 49: { 50: k->keysym = s->const; 51: k->dnumber = (a->sec_index == TRUE) ? i+1 : d; 52: k++; 53: # ifdef xOTR1 54: if (tTf(25, 1)) 55: { 56: printf("exact key on dom %d\tvalue=", d); 57: prsym(s->const); 58: } 59: # endif 60: break; 61: } 62: s++; 63: } 64: if (j == Nsimp) 65: { 66: i = 0; /* failure. at lease one key isn't used */ 67: break; 68: } 69: } 70: k->dnumber = 0; /* mark end of list */ 71: } 72: # ifdef xOTR1 73: if (tTf(25, 9)) 74: printf("exactkey returning %d\n", i); 75: # endif 76: return (i); 77: } 78: 79: 80: rangekey(ap, l, h) 81: struct accessparam *ap; 82: struct key *l; 83: struct key *h; 84: 85: /* 86: ** Range key checks if the relation described by 87: ** "ap" is ISAM and there are simple clauses 88: ** on the first key and any additional keys. 89: ** 90: ** Rangekey accumulates both high and low keys, 91: ** which are not necessary the same. If it 92: ** every finds a high or a low key on the first 93: ** domain of the relation then success=TRUE. 94: ** 95: ** Returns 1 if Rangekey ok 96: ** 0 if Rangekey is not ok 97: ** -1 if Rangekey ok and all clauses are equality clauses 98: */ 99: { 100: register struct key *low, *high; 101: register struct simp *s; 102: struct accessparam *a; 103: int sec_indx, d, i; 104: int rel, success, ns, lowkey, allexact; 105: 106: # ifdef xOTR1 107: if (tTf(25, 5)) 108: printf("Rangekey\n"); 109: # endif 110: 111: a = ap; 112: sec_indx = a->sec_index == TRUE; 113: low = l; 114: high = h; 115: allexact = -1; /* assume all clauses equality clauses */ 116: s = Simp; 117: success = FALSE; 118: if (a->mode == LRANGEKEY) 119: { 120: 121: for (ns = 0; ns < Nsimp; ns++) 122: { 123: rel = s->relop; 124: for (i = 0; d = a->keydno[i]; i++) 125: { 126: if (d == s->att) 127: { 128: /* this is either a high range value or low range value */ 129: lowkey = (rel == opGTGE); 130: if (lowkey || rel == opEQ) 131: { 132: /* low range key */ 133: # ifdef xOTR1 134: if (tTf(25, 6)) 135: printf("low key on dom %d\t", d); 136: # endif 137: low->keysym = s->const; 138: low->dnumber = sec_indx ? i+1 : d; 139: low++; 140: } 141: if (!lowkey || rel == opEQ) 142: { 143: /* high range key */ 144: # ifdef xOTR1 145: if (tTf(25, 6)) 146: printf("high key on dom %d\t", d); 147: # endif 148: high->keysym = s->const; 149: high->dnumber = sec_indx ? i+1 : d; 150: high++; 151: } 152: # ifdef xOTR1 153: if (tTf(25, 6)) 154: prsym(s->const); 155: # endif 156: if (i == 0) 157: success = TRUE; 158: if (rel != opEQ) 159: allexact = 1; /* at least one inequality */ 160: break; 161: } 162: } 163: s++; /* try next simple clause */ 164: } 165: } 166: 167: high->dnumber = 0; /* mark end of list */ 168: low->dnumber = 0; /* mask end of list */ 169: 170: /* if success then return whether all clauses were equality */ 171: if (success) 172: success = allexact; 173: 174: # ifdef xOTR1 175: if (tTf(25, 5)) 176: printf("rangekey returning %d\n", success); 177: # endif 178: return (success); 179: } 180: 181: 182: setallkey(relkey, keytuple) 183: struct key *relkey; 184: char *keytuple; 185: 186: /* 187: ** Setallkey takes a key struct, decodes it and 188: ** calls setkey with each value. 189: ** 190: ** Called from strategy(). 191: ** 192: ** returns 0 if ok. 193: ** returns -1 in the special case of a deblanked hashkey 194: ** being bigger than the corresponding domain. 195: */ 196: { 197: register struct key *k; 198: register struct stacksym *sk; 199: register int dnum; 200: struct symbol **s; 201: char *p, temp[256]; 202: int l; 203: 204: clearkeys(Scanr); 205: k = relkey; 206: while (dnum = k->dnumber) 207: { 208: s = &k->keysym; 209: sk = Stack; 210: getsymbol(sk, &s); /* copy symbol to stack. caution:getsym changes the value of s. */ 211: rcvt(sk, Scanr->relfrmt[dnum], Scanr->relfrml[dnum]); /* convert key to correct type */ 212: p = (char *) sk->value; 213: 214: if (sk->type == CHAR) 215: { 216: /* 217: ** The length of a character key must 218: ** be made equal to the domain length. 219: ** The key is copied to a temp place 220: ** and a null byte is inserted at the 221: ** end. In addition, if the key without 222: ** blanks is longer than the domain and 223: ** this is an exactkey, then the query 224: ** is false. 225: */ 226: p = temp; 227: l = cmove(sk, p); /* copy symbol to temp removing blanks & nulls */ 228: # ifdef xOTR1 229: if (tTf(26, 9)) 230: printf("length is %d\n", l); 231: # endif 232: if (Fmode == EXACTKEY && l > (Scanr->relfrml[dnum] & 0377)) 233: /* key too large. qualification is false */ 234: return (-1); 235: } 236: setkey(Scanr, keytuple, p, dnum); /* set the key */ 237: k++; 238: } 239: # ifdef xOTR1 240: if (tTf(26, 8)) 241: printup(Scanr, keytuple); 242: # endif 243: return (0); 244: } 245: 246: 247: cmove(sym, dest) 248: struct stacksym *sym; 249: char *dest; 250: 251: /* 252: ** Cmove copies a char symbol into "dest". 253: ** It stops when the length is reached or 254: ** when a null byte is found. 255: ** 256: ** returns the number of non-blank chars 257: ** in the string. 258: */ 259: { 260: register char *d, *s; 261: register int l; 262: int blank; 263: 264: s = cpderef(sym->value); /* s points to the char string */ 265: d = dest; 266: blank = 0; 267: 268: for (l = (sym->len & 0377); l--; s++) 269: { 270: *d++ = *s; 271: if (*s == ' ') 272: blank++; 273: if (*s == '\0') 274: { 275: d--; 276: break; 277: } 278: } 279: 280: *d = '\0'; 281: return ((d - dest) - blank); /* return length of string */ 282: } 283: 284: indexcheck() 285: 286: /* 287: ** Indexcheck is called by scan() to check whether 288: ** a secondary index tuple satisfies the simple 289: ** clauses under which it was scanned. 290: ** 291: ** Returns 1 if the tuple is ok, 292: ** 0 otherwise. 293: */ 294: { 295: register int i; 296: 297: if (Fmode == EXACTKEY) 298: i = keycheck(&Lkey_struct, Keyl, 0); /* check for equality */ 299: else 300: { 301: i = keycheck(&Lkey_struct, Keyl, 1); /* check for >= */ 302: /* If the lowkey passed, check the highkey also */ 303: if (i) 304: i = keycheck(&Hkey_struct, Keyh, -1); /* check for <= */ 305: } 306: # ifdef xOTR1 307: if (tTf(26, 10)) 308: printf("indexcheck ret %d\n", i); 309: # endif 310: return (i); 311: } 312: 313: keycheck(keys, keytuple, mode) 314: struct key *keys; 315: char *keytuple; 316: int mode; 317: 318: /* 319: ** Keycheck compares Intup with keytuple 320: ** according to the domains specified in the 321: ** "keys" struct. 322: ** 323: ** mode is either >0, =0, <0 depending on 324: ** whether check is for Intup >= keytuple, 325: ** Intup == keytuple, Intup <= keytuple respectively 326: ** 327: ** returns TRUE or FALSE accordingly. 328: */ 329: { 330: register struct key *k; 331: register char *kp; 332: register int dnum; 333: int offset, i, type, success; 334: 335: kp = keytuple; 336: success = TRUE; 337: 338: for (k = keys; dnum = k->dnumber; k++) 339: { 340: 341: offset = Scanr->reloff[dnum]; 342: if (i = icompare(&Intup[offset], &kp[offset], Scanr->relfrmt[dnum], Scanr->relfrml[dnum] & I1MASK)) 343: { 344: if (i < 0 && mode < 0 || i > 0 && mode > 0) 345: continue; 346: success = FALSE; 347: break; 348: } 349: } 350: return (success); 351: }