|
|
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.