1: # include "../ingres.h" 2: # include "../access.h" 3: # define SAMETUP 0 4: # define SAMEKEYS 1 5: # define DIFFTUP 2 6: 7: /* tTf flag 95 TTF */ 8: /* 9: ** Replace - replace an already existing tuple 10: ** 11: ** Replace will replace the tuple specified by TID 12: ** with the new tuple. An attempt is made to not 13: ** move the tuple if at all possible. 14: ** 15: ** Three separate conditions are delt with. If the 16: ** new tuple is the same as the old tuple, a return 17: ** of zero occures and the page is not changed. 18: ** 19: ** If the keys(if any) are the same and the canonical 20: ** tuple lengths are the same, then the new tuple will 21: ** be placed in the same location. 22: ** 23: ** If the lengths or the keys are different, then the 24: ** tuple is deleted and the new tuple inserted 25: ** 26: ** Checkdups specifies whether to check for duplicates. 27: ** If the new tuple is a duplicate of one already there, 28: ** then the tuple at TID is deleted 29: ** returns: 30: ** <0 fatal error 31: ** 1 new tuple was duplicate of returned tid 32: ** 2 tuple identified by tid has been deleted 33: ** 34: ** If replace returns 1 then tid is set to the 35: ** duplicate tuple. This is necessary for updating 36: ** secondary indices. 37: */ 38: 39: 40: replace(dx, tidx, tuple, checkdups) 41: struct descriptor *dx; 42: struct tup_id *tidx; 43: char *tuple; 44: int checkdups; 45: { 46: register struct descriptor *d; 47: register int i; 48: register struct tup_id *tid; 49: char oldtuple[MAXTUP]; 50: struct tup_id primtid; 51: long primpage; 52: int need, same; 53: int len, oldlength; 54: char *new, *old, *oldt; 55: char *getint_tuple(); 56: 57: d = dx; 58: tid = tidx; 59: # ifdef xATR1 60: if (tTf(95, 0)) 61: { 62: printf("replace: %.14s,", d->relid); 63: dumptid(tid); 64: printf("replace: "); 65: printup(d, tuple); 66: } 67: # endif 68: 69: /* make tuple canonical */ 70: need = canonical(d, tuple); 71: 72: /* if heap, no dup checking */ 73: if (abs(d->relspec) == M_HEAP) 74: checkdups = FALSE; 75: 76: if (i = get_page(d, tid)) 77: return (i); /* fatal error */ 78: 79: /* check if tid exists */ 80: if (i = invalid(tid)) 81: return (i); /* already deleted or invalid */ 82: 83: oldt = getint_tuple(d, tid, oldtuple); 84: oldlength = tup_len(tid); 85: 86: /* check whether tuples are the same, different lengths, different keys */ 87: same = DIFFTUP; /* assume diff lengths or keys */ 88: if (oldlength == need) 89: { 90: /* same size. check for same domains */ 91: same = SAMETUP; /* assume identical */ 92: new = tuple; 93: old = oldt; 94: for (i = 1; i <= d->relatts; i++) 95: { 96: len = d->relfrml[i] & I1MASK; 97: if (icompare(new, old, d->relfrmt[i], len)) 98: { 99: if (d->relxtra[i]) 100: { 101: same = DIFFTUP; 102: break; 103: } 104: same = SAMEKEYS; 105: } 106: old += len; 107: new += len; 108: } 109: } 110: 111: # ifdef xATR2 112: if (tTf(95, 1)) 113: printf("replace:same=%d\n", same); 114: # endif 115: switch (same) 116: { 117: 118: case SAMETUP: 119: /* new tuple same as old tuple */ 120: i = 1; /* flag as duplicate */ 121: /* though character strings may compare equal, 122: ** they can look different, so if they do look different 123: ** go ahead and do the replace using put_tuple. */ 124: if (!bequal(tuple, oldt, d->relwid)) 125: goto puttuple; 126: break; 127: 128: case SAMEKEYS: 129: /* keys the same, lengths the same, tuples different */ 130: if (checkdups) 131: { 132: /* This is either an ISAM or HASH file. If mainpg 133: ** is non-zero, then the primary page=mainpg -1. 134: ** Otherwise, "find" must be called to determine 135: ** the primary page 136: */ 137: if (Acc_head->mainpg) 138: { 139: primpage = Acc_head->mainpg -1; 140: stuff_page(&primtid, &primpage); 141: } 142: else 143: { 144: if (i = find(d, FULLKEY, &primtid, &primtid, tuple)) 145: return (i); /* fatal error */ 146: if (i = get_page(d, tid)) /* restore page for tuple */ 147: return (i); 148: } 149: 150: if (i = scan_dups(d, &primtid, tuple)) 151: { 152: if (i == 1) 153: { 154: del_tuple(tid, oldlength); /* tuple a duplicate */ 155: d->reladds--; 156: /* copy tid of duplicate tuple */ 157: bmove(&primtid, tid, sizeof(primtid)); 158: } 159: break; 160: } 161: } 162: goto puttuple; 163: 164: case DIFFTUP: 165: /* keys different or lengths different */ 166: del_tuple(tid, oldlength); 167: 168: /* find where to put tuple */ 169: if (i = findbest(d, tid, tuple, need, checkdups)) 170: { 171: d->reladds--; 172: break; 173: } 174: 175: /* place new tuple in page */ 176: puttuple: 177: put_tuple(tid, Acctuple, need); 178: i = 0; 179: } 180: 181: # ifdef xATR1 182: if (tTf(95, 2)) 183: { 184: printf("replace rets %d,", i); 185: dumptid(tid); 186: } 187: # endif 188: 189: return (i); 190: }