1: # include "../ingres.h" 2: # include "../aux.h" 3: # include "../symbol.h" 4: # include "../access.h" 5: # include "../lock.h" 6: 7: /* tTf flag 92 TTF */ 8: 9: /* 10: ** Find - determine limits for scan of a relation 11: ** 12: ** Find determines the values of an initial TID 13: ** and an ending TID for scanning a relation. 14: ** The possible calls to find are: 15: ** 16: ** find(desc, NOKEY, lotid, hightid) 17: ** sets tids to scan entire relation 18: ** 19: ** find(desc, EXACTKEY, lotid, hightid, key) 20: ** sets tids according to structure 21: ** of the relation. Key should have 22: ** been build using setkey. 23: ** 24: ** find(desc, LRANGEKEY, lotid, hightid, keylow) 25: ** Finds lotid less then or equal to keylow 26: ** for isam relations. Otherwise scans whole relation. 27: ** This call should be followed by a call with HRANGEKEY. 28: ** 29: ** find(desc, HRANGEKEY, lotid, hightid, keyhigh) 30: ** Finds hightid greater than or equal to 31: ** keyhigh for isam relations. Otherwise sets 32: ** hightid to maximum scan. 33: ** 34: ** find(desc, FULLKEY, lotid, hightid, key) 35: ** Same as find with EXACTKEY and all keys 36: ** provided. This mode is used only by findbest 37: ** and replace. 38: ** 39: ** returns: 40: ** <0 fatal error 41: ** 0 success 42: */ 43: 44: 45: 46: find(d1, mode, lotid1, hightid, key) 47: struct descriptor *d1; 48: int mode; 49: struct tup_id *lotid1; 50: struct tup_id *hightid; 51: char *key; 52: { 53: register struct descriptor *d; 54: register struct tup_id *lotid; 55: register int ret; 56: int keyok; 57: long pageid; 58: long rhash(); 59: 60: d = d1; 61: lotid = lotid1; 62: 63: # ifdef xATR1 64: if (tTf(92, 0)) 65: { 66: printf("find: m%d,s%d,%.14s\n", mode, d->relspec, d->relid); 67: if (mode != NOKEY) 68: printup(d, key); 69: } 70: # endif 71: 72: ret = 0; /* assume successful return */ 73: keyok = FALSE; 74: 75: switch (mode) 76: { 77: 78: case EXACTKEY: 79: keyok = fullkey(d); 80: break; 81: 82: case FULLKEY: 83: keyok = TRUE; 84: 85: case NOKEY: 86: case LRANGEKEY: 87: case HRANGEKEY: 88: break; 89: 90: default: 91: syserr("FIND: bad mode %d", mode); 92: } 93: 94: /* set lotid for beginning of scan */ 95: if (mode != HRANGEKEY) 96: { 97: pageid = 0; 98: stuff_page(lotid, &pageid); 99: lotid->line_id = -1; 100: } 101: 102: /* set hitid for end of scan */ 103: if (mode != LRANGEKEY) 104: { 105: pageid = -1; 106: stuff_page(hightid, &pageid); 107: hightid->line_id = -1; 108: } 109: 110: if (mode != NOKEY) 111: { 112: switch (abs(d->relspec)) 113: { 114: 115: case M_HEAP: 116: break; 117: 118: case M_ISAM: 119: if (mode != HRANGEKEY) 120: { 121: /* compute lo limit */ 122: if (ret = ndxsearch(d, lotid, key, -1, keyok)) 123: break; /* fatal error */ 124: } 125: 126: /* if the full key was provided and mode is exact, then done */ 127: if (keyok) 128: { 129: bmove(lotid, hightid, sizeof *lotid); 130: break; 131: } 132: 133: if (mode != LRANGEKEY) 134: ret = ndxsearch(d, hightid, key, 1, keyok); 135: break; 136: 137: case M_HASH: 138: if (!keyok) 139: break; /* can't do anything */ 140: pageid = rhash(d, key); 141: stuff_page(lotid, &pageid); 142: stuff_page(hightid, &pageid); 143: break; 144: 145: default: 146: ret = acc_err(AMFIND_ERR); 147: } 148: } 149: 150: # ifdef xATR2 151: if (tTf(92, 1)) 152: { 153: printf("find: ret %d\tlow", ret); 154: dumptid(lotid); 155: printf("hi"); 156: dumptid(hightid); 157: } 158: # endif 159: return (ret); 160: } 161: 162: fullkey(des) 163: struct descriptor *des; 164: /* 165: * This routine will check that enough of the tuple has been specified 166: * to enable a key access. 167: * 168: */ 169: { 170: register struct descriptor *d; 171: register int i; 172: 173: d = des; 174: for (i = 1; i <= d->relatts; i++) 175: if (d->relxtra[i] && !d->relgiven[i]) 176: return (FALSE); 177: return (TRUE); 178: }