|
|
1.1 root 1: # include <stdio.h>
2: # include <ingres.h>
3: # include <resp.h>
4: # include <aux.h>
5: # include <symbol.h>
6: # include <access.h>
7: # include <batch.h>
8: # include <opsys.h>
9: # include <catalog.h>
10: # include <btree.h>
11: # include <version.h>
12: # include <sccs.h>
13: # include <errors.h>
14:
15: SCCSID(@(#)update.c 8.4 2/8/85)
16:
17: /*
18: ** Update reads a batch file written by the
19: ** access method routines (openbatch, addbatch, closebatch)
20: ** and performs the updates stored in the file.
21: **
22: ** It assumes that it is running in the database. It
23: ** is driven by the data in the Batchhd struct (see ../batch.h).
24: ** If the relation has a secondary index then update calls
25: ** secupdate. As a last step the batch file is removed.
26: **
27: ** The global flag Batch_recovery is tested in case
28: ** of an error. It should be FALSE if update is being
29: ** run as the dbu deferred update processor. It should
30: ** be TRUE if it is being used as part of the recovery
31: ** procedure.
32: */
33:
34: update()
35: {
36: register int i, mode;
37: DESC rel, d;
38: long oldtid, tupcnt;
39: char oldtup[MAXTUP], newtup[MAXTUP], tuple[MAXTUP];
40: char *batchname(), *trim_relname();
41: char *tp;
42: long bad_lid[MAXLID], lid, old_lid[MAXLID], new_lid;
43: char bad[MAXLID][10], *locv();
44: char delbtree[MAXNAME + 4], replbtree[MAXNAME + 4];
45: char tup_buf[3 * LIDSIZE], lid_buf[LIDSIZE];
46: char btree[MAXNAME + 4], out[MAXNAME + 4];
47: char filname[MAXNAME+4];
48: TID tidpos;
49: struct stat sbuf;
50: long num;
51: int first, end, batchcnt, j, k;
52: FILE *fp;
53: long temp;
54: long del_cnt;
55: extern int Btree_fd;
56: extern DESC Btreesec;
57:
58: # ifdef xZTR1
59: if (tTf(48, -1))
60: printf("Update on %s\n", batchname());
61: # endif
62: /* set up to read batchhd */
63: Batch_cnt = BATCHSIZE; /* force a read on next getbatch */
64: Batch_dirty = FALSE;
65: if ((Batch_fp = open(batchname(), O_RDWR)) < 0)
66: syserr("prim:can't open %s", batchname());
67: getbatch(&Batchhd, sizeof Batchhd);
68:
69: tupcnt = Batchhd.num_updts;
70: # ifdef xZTR1
71: if (tTf(48, 0))
72: printf("rel=%s tups=%ld\n", Batchhd.rel_name, tupcnt);
73: # endif
74: Resp.resp_tups = 0;
75: if (!tupcnt)
76: {
77: rmbatch();
78: return (1);
79: }
80:
81: /* update the primary relation */
82: if (i = openr(&rel, OR_WRITE, Batchhd.rel_name))
83: syserr("prim:can't openr %s %d", Batchhd.rel_name, i);
84: if (rel.reldum.reldim > 0)
85: {
86: bmove(rel.relbtree, &Btreesec, sizeof(Btreesec));
87: Btree_fd = rel.btree_fd;
88: }
89:
90: mode = Batchhd.mode_up;
91:
92: if (rel.reldum.reldim > 0)
93: /* create files necessary for updating btrees in specified order */
94: {
95: concat(REPL_IN, Fileset, replbtree);
96: if ((Repl_infp = fopen(replbtree, "w")) == NULL)
97: syserr("can't open %s", replbtree);
98: concat(DEL_IN, Fileset, delbtree);
99: if ((Del_infp = fopen(delbtree, "w")) == NULL)
100: syserr("can't open %s", delbtree);
101: }
102: Del_cnt = 0;
103: for (i = 0; i < MAXLID; ++i)
104: {
105: Prev_lid[i] = 0;
106: Repl_cnt[i] = 0;
107: }
108:
109: if (rel.reldum.reldim > 0)
110: {
111: if (tupcnt <= 1 || (mode != mdREPL && mode != mdAPP))
112: fclose(Repl_infp);
113: else
114: /* do replace's in ascending lid-value order */
115: {
116: d.reloff[1] = 0;
117: d.reloff[2] = Batchhd.tido_size + Batchhd.tupo_size + Batchhd.tupn_size - LIDSIZE;
118: for (i = 1; i <= rel.reldum.reldim; ++i)
119: {
120: d.reloff[i+2] = d.reloff[i+1] + LIDSIZE;
121: d.relfrmt[i+1] = INT;
122: d.relfrml[i+1] = LIDSIZE;
123: d.relgiven[i+1] = i;
124: }
125: d.relfrmt[i+1] = CHAR;
126: d.relfrml[i+1] = Batchhd.tidn_size;
127: d.relgiven[0] = 0;
128: d.relgiven[1] = i;
129: d.relgiven[i+1] = i + 1;
130: d.relfrmt[1] = CHAR;
131: d.relfrml[1] = d.reloff[2];
132: d.reldum.relspec = M_ORDER;
133: d.reldum.relatts = 2 + rel.reldum.reldim;
134: d.reldum.relwid = d.reloff[2] + LIDSIZE + Batchhd.tidn_size;
135: /* extract information about tuples from batch file */
136: if (stat(batchname(), &sbuf) < 0)
137: syserr("bad file for stat %s", batchname());
138: num = sbuf.st_size / (BATCHSIZE + IDSIZE);
139: if (num >= 1)
140: first = BATCHSIZE - Batch_cnt;
141: else
142: first = sbuf.st_size - sizeof Batchhd - IDSIZE;
143: if ((i = fwrite(&Batchbuf.bbuf[Batch_cnt], 1, first, Repl_infp)) != first)
144: syserr("can't write replace file");
145: for (i = 2; i <= num; ++i)
146: {
147: Batch_cnt = BATCHSIZE;
148: readbatch();
149: if (fwrite(Batchbuf.bbuf, 1, BATCHSIZE, Repl_infp) != BATCHSIZE)
150: syserr("can't write to replace file");
151: }
152: Batch_cnt = BATCHSIZE;
153: readbatch();
154: end = ((sbuf.st_size - BATCHSIZE - IDSIZE) % (BATCHSIZE + IDSIZE)) - IDSIZE;
155: if (end > 0)
156: if (fwrite(Batchbuf.bbuf, 1, end, Repl_infp) != end)
157: syserr("can't write to replace file 2");
158: fclose(Repl_infp);
159: sortfile(replbtree, &d, FALSE);
160: if ((Repl_outfp = fopen(ztack(REPL_OUT, Fileset), "r")) == NULL)
161: syserr("can't open replace file in update for reading\n");
162: concat("_SYStemp", Fileset, filname);
163: /* rewrite in batch file in sorted order */
164: if ((fp = fopen(filname, "w")) == NULL)
165: syserr("can't open %s", filname);
166: if ((k = fread(Batchbuf.bbuf, 1, first, Repl_outfp)) != first)
167: syserr("read error0 from replace file %d", k);
168: if (fwrite(Batchbuf.file_id, 1, IDSIZE, fp) != IDSIZE)
169: syserr("write error in batch file");
170: if (fwrite(&Batchhd, 1, sizeof Batchhd, fp) != sizeof Batchhd)
171: syserr("write error in batch file");
172: if (fwrite(Batchbuf.bbuf, 1, first, fp) != first)
173: syserr("write error in batch file");
174: for (i = 2; i <= num; ++i)
175: {
176: if ((k = fread(Batchbuf.bbuf, 1, BATCHSIZE, Repl_outfp)) != BATCHSIZE)
177: syserr("read error1 in replace file %d", k);
178: if (fwrite(&Batchbuf, 1, BATCHSIZE + IDSIZE, fp) != BATCHSIZE + IDSIZE)
179: syserr("write error into temp repl file");
180: }
181: if (end > 0)
182: {
183: if ((k = fread(Batchbuf.bbuf, 1, end, Repl_outfp)) != end)
184: syserr("read error2 from replace file %d", k);
185: if (fwrite(&Batchbuf, 1, end + IDSIZE, fp) != end + IDSIZE)
186: syserr("write error into temp repl file");
187: }
188: fclose(fp);
189: fclose(Repl_outfp);
190: unlink(ztack(REPL_OUT, Fileset));
191: rmbatch();
192: if (link(filname, batchname()) == -1)
193: syserr("can't link %s", batchname());
194: unlink(filname);
195: Batch_cnt = BATCHSIZE;
196: Batch_dirty = FALSE;
197: if ((Batch_fp = open(batchname(), O_RDWR)) < 0)
198: syserr("can't open new batch file");
199: getbatch(&Batchhd, sizeof Batchhd);
200: }
201: unlink(replbtree);
202: }
203:
204: while (tupcnt--)
205: {
206: getbatch(&oldtid, Batchhd.tido_size); /* read old tid */
207: getbatch(oldtup, Batchhd.tupo_size); /* and portions of old tuple */
208: if (!rel.reldum.reldim)
209: getbatch(newtup, Batchhd.tupn_size); /* and the newtup */
210: else
211: {
212: if (Batchhd.tupn_size > 0)
213: {
214: getbatch(newtup, Batchhd.tupn_size - rel.reldum.reldim * LIDSIZE);
215: batchcnt = Batch_cnt;
216: tp = newtup + Batchhd.tupn_size - rel.reldum.reldim * LIDSIZE;
217: getbatch(tp, rel.reldum.reldim * LIDSIZE);
218: }
219: }
220:
221: switch (mode)
222: {
223:
224: case mdDEL:
225: if ((i = delete(&rel, &oldtid)) < 0)
226: syserr("prim:bad del %d %s", i, Batchhd.rel_name);
227: break;
228:
229: case mdREPL:
230: if (i = replace(&rel, &oldtid, newtup, TRUE))
231: {
232: /* if newtuple is a duplicate, then ok */
233: if (i == 1)
234: {
235: if (rel.reldum.reldim)
236: ++Resp.resp_tups;
237: break;
238: }
239: if (i == 3)
240: {
241: bmove(newtup + rel.reldum.relwid - LIDSIZE, &new_lid, LIDSIZE);
242: bmove(tp, bad_lid, LIDSIZE * rel.reldum.reldim);
243: for(j = 0; j < rel.reldum.reldim; ++j)
244: strcpy(bad[j], locv(bad_lid[j]));
245: switch (rel.reldum.reldim)
246: {
247: case 1:
248: nferror(BADLID1, trim_relname(rel.reldum.relid), bad[0], 0);
249: break;
250: case 2:
251: nferror(BADLID2, trim_relname(rel.reldum.relid), bad[0], bad[1], 0);
252: break;
253: case 3:
254: nferror(BADLID3, trim_relname(rel.reldum.relid), bad[0], bad[1], bad[2], 0);
255: break;
256: }
257: Batch_cnt = batchcnt + LIDSIZE * (rel.reldum.reldim - 1);
258: lid = -1;
259: putbatch(&lid, LIDSIZE);
260: break;
261: }
262: /* if this is recovery and oldtup not there, try to insert newtup */
263: if (Batch_recovery && i == 2)
264: goto upinsert;
265: syserr("prim:Non-functional replace on %s (%d)", i, Batchhd.rel_name);
266: }
267: Resp.resp_tups++;
268: break;
269:
270: case mdAPP:
271: upinsert:
272: if ((i = insert(&rel, &oldtid, newtup, TRUE)) < 0)
273: syserr("prim:bad insert %d %s", i, Batchhd.rel_name);
274: if (i == 2)
275: {
276: tp = newtup + rel.reldum.relwid - rel.reldum.reldim * LIDSIZE;
277: bmove(tp, bad_lid, LIDSIZE * rel.reldum.reldim);
278: for (j = 0; j < rel.reldum.reldim; ++j)
279: strcpy(bad[j], locv(bad_lid[j]));
280: switch (rel.reldum.reldim)
281: {
282: case 1:
283: nferror(BADLID1, trim_relname(rel.reldum.relid), bad[0], 0);
284: break;
285: case 2:
286: nferror(BADLID2, trim_relname(rel.reldum.relid), bad[0], bad[1], 0);
287: break;
288: case 3:
289: nferror(BADLID3, trim_relname(rel.reldum.relid), bad[0], bad[1], bad[2], 0);
290: break;
291: }
292: oldtid = -1;
293: }
294: else if (rel.reldum.reldim > 0)
295: {
296: if (batchcnt + rel.reldum.reldim * LIDSIZE > BATCHSIZE)
297: {
298: if ((j = lseek(Batch_fp, (long) -(Batch_cnt + BATCHSIZE + 2 * IDSIZE), 1)) < 0)
299: syserr("Lseek error in update");
300: readbatch();
301: }
302: Batch_cnt = batchcnt;
303: tp = newtup + rel.reldum.relwid - LIDSIZE * rel.reldum.reldim;
304: putbatch(tp, rel.reldum.reldim * LIDSIZE);
305: }
306: break;
307:
308: default:
309: syserr("prim:impossible mode %d", mode);
310: }
311: putbatch(&oldtid, Batchhd.tidn_size); /* write new tid if necessary */
312: }
313: if (rel.reldum.reldim > 0)
314: /* do deletions in decending lid-value order */
315: {
316: fclose(Del_infp);
317: if (Del_cnt != 0)
318: {
319: if (Del_cnt > 1)
320: {
321: d.reloff[0] = -LIDSIZE;
322: d.relgiven[0] = 0;
323: for (i = 1; i <= rel.reldum.reldim; ++i)
324: {
325: d.reloff[i] = d.reloff[i-1] + LIDSIZE;
326: d.relfrmt[i] = INT;
327: d.relfrml[i] = LIDSIZE;
328: d.relgiven[i] = -i;
329: }
330: d.reldum.relspec = -M_ORDER;
331: d.reldum.relatts = rel.reldum.reldim;
332: d.reldum.relwid = LIDSIZE * rel.reldum.reldim;
333: sortfile(delbtree, &d, TRUE);
334: }
335: btreename(rel.reldum.relid, btree);
336: del_cnt = Del_cnt;
337: if (del_cnt == 1)
338: concat(DEL_IN, Fileset, out);
339: else
340: concat(DEL_OUT, Fileset, out);
341: if ((Del_outfp = fopen(out, "r")) == NULL)
342: syserr("can't open delete file in update for reading\n");
343: while (del_cnt--)
344: {
345: if (fread(old_lid, 1, LIDSIZE * rel.reldum.reldim, Del_outfp) != LIDSIZE * rel.reldum.reldim)
346: syserr("tup_buf read error");
347:
348: if (delete_btree(old_lid, rel.reldum.reldim) < 0)
349: {
350: printf("DELETE ERROR: %s: bad lid(s)\n", trim_relname(rel.reldum.relid));
351: for (i = 0; i < rel.reldum.reldim; ++i)
352: printf("\tlid%d=%ld\n", i + 1, old_lid[i]);
353: syserr("DELETE ERROR");
354: }
355: }
356: fclose(Del_outfp);
357: unlink(out);
358: }
359: unlink(delbtree);
360: }
361:
362: /* fix the tupchanged count if delete or append */
363: if (mode != mdREPL)
364: Resp.resp_tups = rel.reladds >= 0 ? rel.reladds : -rel.reladds;
365: /* close the relation but secupdate will still use the decriptor */
366: temp = rel.reladds;
367: if (i = closer(&rel))
368: syserr("prim:close err %d %s", i, Batchhd.rel_name);
369: rel.reladds = temp;
370: batchflush();
371:
372: /* if this relation is indexed, update the indexes */
373: if (rel.reldum.relindxd > 0)
374: secupdate(&rel);
375: if (rel.reldum.reldim > 0)
376: btreeupdate(&rel);
377: rmbatch();
378:
379: # ifdef xZTR1
380: if (tTf(48, 2))
381: printf("%ld tups changed\n", Resp.resp_tups);
382: # endif
383: return (0);
384: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.