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