|
|
1.1 ! root 1: # include <ingres.h> ! 2: # include <access.h> ! 3: # include <catalog.h> ! 4: # include <batch.h> ! 5: # include <btree.h> ! 6: # include <sccs.h> ! 7: ! 8: SCCSID(@(#)replace.c 8.2 2/8/85) ! 9: ! 10: # define SAMETUP 0 ! 11: # define SAMEKEYS 1 ! 12: # define DIFFTUP 2 ! 13: ! 14: /* ! 15: ** REPLACE - replace an already existing tuple ! 16: ** ! 17: ** Replace will replace the tuple specified by TID ! 18: ** with the new tuple. An attempt is made to not ! 19: ** move the tuple if at all possible. ! 20: ** ! 21: ** Three separate conditions are dealt with. If the ! 22: ** new tuple is the same as the old tuple, a return ! 23: ** of zero occures and the page is not changed. ! 24: ** ! 25: ** If the keys(if any) are the same and the canonical ! 26: ** tuple lengths are the same, then the new tuple will ! 27: ** be placed in the same location. ! 28: ** ! 29: ** If the lengths or the keys are different, then the ! 30: ** tuple is deleted and the new tuple inserted ! 31: ** ! 32: ** Checkdups specifies whether to check for duplicates. ! 33: ** If the new tuple is a duplicate of one already there, ! 34: ** then the tuple at TID is deleted ! 35: ** ! 36: ** Returns: ! 37: ** <0 fatal error ! 38: ** 1(DUPTUP) new tuple was duplicate of returned tid ! 39: ** 2(DELTUP) tuple identified by tid has been deleted ! 40: ** 3(BADLID) bad lid ! 41: ** ! 42: ** If replace returns 1 then tid is set to the ! 43: ** duplicate tuple. This is necessary for updating ! 44: ** secondary indices. ! 45: ** ! 46: ** Trace Flags: ! 47: ** 24.4-7 ! 48: */ ! 49: ! 50: ! 51: replace(d, tid, tuple, checkdups) ! 52: register DESC *d; ! 53: register TID *tid; ! 54: char *tuple; ! 55: int checkdups; ! 56: { ! 57: register int i; ! 58: int j; ! 59: char oldtuple[MAXTUP]; ! 60: TID primtid, tidloc, tidpos; ! 61: long primpage, old_lid[MAXLID], new_lid[MAXLID], page, t; ! 62: int need, same, numatts; ! 63: int len, oldlength; ! 64: char *new, *old, *oldt; ! 65: char *getint_tuple(); ! 66: char btree[MAXNAME + 4]; ! 67: long oldtid; ! 68: int lidwid, compare; ! 69: struct locator temp; ! 70: ! 71: # ifdef xATR1 ! 72: if (tTf(24, 4)) ! 73: { ! 74: printf("replace: %.14s,", d->reldum.relid); ! 75: dumptid(tid); ! 76: printf("replace: "); ! 77: printup(d, tuple); ! 78: } ! 79: # endif ! 80: ! 81: /* make tuple canonical */ ! 82: need = canonical(d, tuple); ! 83: ! 84: /* if heap or ordered, no dup checking */ ! 85: if (abs(d->reldum.relspec) == M_HEAP || d->reldum.reldim > 0) ! 86: checkdups = FALSE; ! 87: ! 88: if (i = get_page(d, tid)) ! 89: return (i); /* fatal error */ ! 90: ! 91: /* check if tid exists */ ! 92: if (i = invalid(tid)) ! 93: return (i); /* already deleted or invalid */ ! 94: ! 95: oldt = getint_tuple(d, tid, oldtuple); ! 96: /* reset page back to main relation page */ ! 97: if (i = get_page(d, tid)) ! 98: return(i); ! 99: oldlength = tup_len(tid); ! 100: lidwid = LIDSIZE * d->reldum.reldim; ! 101: ! 102: if (d->reldum.reldim > 0) ! 103: { ! 104: /* extract lid values from tuples */ ! 105: btreename(d->reldum.relid, btree); ! 106: old = oldt + d->reldum.relwid - lidwid; ! 107: bmove(old, old_lid, lidwid); ! 108: new = tuple + d->reldum.relwid - lidwid; ! 109: bmove(new, new_lid, lidwid); ! 110: compare = 0; ! 111: for (i = 0; i < d->reldum.reldim; ++i) ! 112: { ! 113: if (new_lid[i] > old_lid[i]) ! 114: { ! 115: compare = 1; ! 116: break; ! 117: } ! 118: else if (new_lid[i] == old_lid[i]) ! 119: compare = -1; ! 120: else ! 121: { ! 122: compare = 0; ! 123: break; ! 124: } ! 125: } ! 126: if (compare >= 0) ! 127: { ! 128: /* do insertion and deletion of new lid and old values in ! 129: ** order that insures that they will be placed in the proper ! 130: ** place ! 131: */ ! 132: if (compare == 1) ! 133: { ! 134: if (insert_mbtree(d, btree, new_lid, tid, &tidpos) < 0) ! 135: return(BADLID); ! 136: if (fwrite(old_lid, 1, lidwid, Del_infp) != lidwid) ! 137: syserr("write error in replace"); ! 138: ++Del_cnt; ! 139: } ! 140: else if (compare == 0) ! 141: { ! 142: page = RT; ! 143: for (j = 0; j < d->reldum.reldim; ++j) ! 144: { ! 145: if (new_lid[j] > 0 && (t = get_tid(page, new_lid[j], &temp)) > 0) ! 146: page = t; ! 147: else if (t == -1) ! 148: { ! 149: for (i = j + 1; i < d->reldum.reldim; ++i) ! 150: { ! 151: if (new_lid[i] != 1 && new_lid[i] != 0) ! 152: return(BADLID); ! 153: } ! 154: break; ! 155: } ! 156: else if (new_lid[j] == 0) ! 157: { ! 158: for (i = j + 1; i < d->reldum.reldim; ++i) ! 159: { ! 160: if (new_lid[i] != 0) ! 161: return(BADLID); ! 162: } ! 163: break; ! 164: } ! 165: else ! 166: return(BADLID); ! 167: } ! 168: for (i = 0; i < d->reldum.reldim; ++i) ! 169: if (new_lid[i] < 0) ! 170: return(BADLID); ! 171: delete_btree(old_lid, d->reldum.reldim); ! 172: if (insert_mbtree(d, btree, new_lid, tid, &tidpos) < 0) ! 173: return(BADLID); ! 174: } ! 175: } ! 176: } ! 177: ! 178: /* check whether tuples are the same, different lengths, different keys */ ! 179: same = DIFFTUP; /* assume diff lengths or keys */ ! 180: if (oldlength == need) ! 181: { ! 182: /* same size. check for same domains */ ! 183: same = SAMETUP; /* assume identical */ ! 184: new = tuple; ! 185: old = oldt; ! 186: /* ignore lid field */ ! 187: numatts = d->reldum.relatts - d->reldum.reldim; ! 188: for (i = 1; i <= numatts; i++) ! 189: { ! 190: len = d->relfrml[i] & I1MASK; ! 191: if (icompare(new, old, d->relfrmt[i], len)) ! 192: { ! 193: if (d->relxtra[i]) ! 194: { ! 195: same = DIFFTUP; ! 196: break; ! 197: } ! 198: same = SAMEKEYS; ! 199: } ! 200: old += len; ! 201: new += len; ! 202: } ! 203: } ! 204: ! 205: # ifdef xATR2 ! 206: if (tTf(24, 5)) ! 207: printf("replace:same=%d\n", same); ! 208: # endif ! 209: ! 210: switch (same) ! 211: { ! 212: ! 213: case SAMETUP: ! 214: /* new tuple same as old tuple */ ! 215: i = DUPTUP; /* flag as duplicate */ ! 216: /* though character strings may compare equal, ! 217: ** they can look different, so if they do look different ! 218: ** go ahead and do the replace using put_tuple. */ ! 219: if (!bequal(tuple, oldt, d->reldum.relwid - lidwid)) ! 220: goto puttuple; ! 221: break; ! 222: ! 223: case SAMEKEYS: ! 224: /* keys the same, lengths the same, tuples different */ ! 225: if (checkdups) ! 226: { ! 227: /* This is either an ISAM or HASH file. If mainpg ! 228: ** is non-zero, then the primary page=mainpg -1. ! 229: ** Otherwise, "find" must be called to determine ! 230: ** the primary page ! 231: */ ! 232: if (Acc_head->mainpg) ! 233: { ! 234: primpage = Acc_head->mainpg -1; ! 235: stuff_page(&primtid, &primpage); ! 236: } ! 237: else ! 238: { ! 239: if (i = find(d, FULLKEY, &primtid, &primtid, tuple)) ! 240: return (i); /* fatal error */ ! 241: if (i = get_page(d, tid)) /* restore page for tuple */ ! 242: return (i); ! 243: } ! 244: ! 245: if (i = scan_dups(d, &primtid, tuple)) ! 246: { ! 247: if (i == DUPTUP) ! 248: { ! 249: del_tuple(tid, oldlength); /* tuple a duplicate */ ! 250: d->reladds--; ! 251: /* copy tid of duplicate tuple */ ! 252: bmove(&primtid, tid, sizeof(primtid)); ! 253: } ! 254: break; ! 255: } ! 256: } ! 257: goto puttuple; ! 258: ! 259: case DIFFTUP: ! 260: /* keys different or lengths different */ ! 261: get_page(d, tid); ! 262: del_tuple(tid, oldlength); ! 263: bmove(tid, &oldtid, LIDSIZE); ! 264: ! 265: /* find where to put tuple */ ! 266: if (i = findbest(d, tid, tuple, need, checkdups)) ! 267: { ! 268: d->reladds--; ! 269: break; ! 270: } ! 271: ! 272: /* place new tuple in page */ ! 273: puttuple: ! 274: put_tuple(tid, Acctuple, need); ! 275: i = NEWTUP; ! 276: ! 277: if (same == DIFFTUP && d->reldum.reldim > 0) ! 278: { ! 279: /* main tid value has changed, update btree */ ! 280: if (compare < 0) ! 281: search_btree(oldtid, &tidpos); ! 282: /* tid different, must be reflected in BTree */ ! 283: replace_btree(*tid, &tidpos); ! 284: } ! 285: } ! 286: ! 287: # ifdef xATR1 ! 288: if (tTf(24, 6)) ! 289: { ! 290: printf("replace rets %d,", i); ! 291: dumptid(tid); ! 292: } ! 293: # endif ! 294: return (i); ! 295: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.