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

Defined functions

update defined in line 15; used 1 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1231
Valid CSS Valid XHTML 1.0 Strict