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