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