1: # include <pv.h> 2: # include <ingres.h> 3: # include <aux.h> 4: # include <catalog.h> 5: # include <access.h> 6: # include <batch.h> 7: # include <opsys.h> 8: # include <btree.h> 9: # include <symbol.h> 10: # include <sccs.h> 11: 12: SCCSID(@(#)modupdate.c 8.4 1/18/85) 13: 14: /* 15: ** MODUPDATE 16: ** This routine is used to exicute the updates 17: ** for modifies so they are recoverable. 18: ** It is also used by restore to complete an aborted modify. 19: ** During a restore the Batch_recover flag should be set to 1; 20: */ 21: 22: 23: modupdate() 24: { 25: char batchname[MAXNAME + 3]; 26: char temprel[MAXNAME+ 3]; 27: char relfile[MAXNAME + 3]; 28: char btreesec[MAXNAME + 3]; 29: register int i; 30: register int j; 31: struct stat sbuf; 32: char aflag; 33: struct tup_id tid; 34: DESC desx; 35: struct attribute attkey, atttup; 36: struct relation oldreltup; 37: struct index ikey, itup; 38: PARM newpv[2]; 39: extern DESC Inddes, Attdes, Reldes; 40: register DESC *desp; 41: extern char *trim_relname(); 42: extern int errno; 43: char btree[MAXNAME + 4], temp_btree[MAXNAME + 4]; 44: int numatts, key; 45: extern int NLidKeys; 46: 47: desp = &desx; 48: concat(MODBATCH,Fileset,batchname); 49: concat(MODTEMP, Fileset, temprel); 50: 51: # ifdef xZTR1 52: if (tTf(34, 8)) 53: printf("Modupdate: %s, %s\n",batchname, temprel); 54: # endif 55: if ((Batch_fp = open(batchname, O_RDONLY)) < 0) 56: syserr("MODUPDATE:Can't open %s", batchname); 57: Batch_cnt = BATCHSIZE; 58: Batch_dirty = FALSE; 59: getbatch(desp, sizeof *desp); 60: ingresname(desp->reldum.relid, desp->reldum.relowner, relfile); 61: 62: if (!desp->reldum.reldim || NLidKeys > 0) 63: { 64: /* don't loose old file before verifying new file */ 65: if (stat(temprel, &sbuf) >= 0) 66: { 67: unlink(relfile); /* Ok if failure */ 68: errno = 0; 69: if (link(temprel, relfile) == -1) 70: syserr("MODUPDATE:Can't link: %s, %s", temprel, relfile); 71: if (unlink(temprel) < 0) 72: syserr("modupdate:unlink(%s)", temprel); 73: } 74: 75: else 76: if(stat(relfile, &sbuf) < 0 || !Batch_recovery) 77: syserr("MODUPDATE:Relation and/or temporary files for %s are missing", 78: relfile); 79: } 80: 81: /* Update admin if this is relation or atribute relations */ 82: /* Should only happen in Sysmod */ 83: if ((aflag = bequal(desp->reldum.relid, "attribute ", MAXNAME)) || 84: bequal(desp->reldum.relid, "relation ", MAXNAME)) 85: { 86: ingresname(desp->reldum.relid, desp->reldum.relowner, temprel); 87: if ((i = open("admin", O_RDWR)) < 0) 88: syserr("MODUPDATE:Can't open admin file"); 89: if (lseek(i, (long) sizeof Admin.adhdr, 0) < 0 || 90: (aflag && lseek(i, (long) sizeof *desp, 1) < 0)) 91: syserr("MODUPDATE:Seek error"); 92: if (write(i, desp, sizeof *desp) != sizeof *desp) 93: syserr("MODUPDATE:Write error on admin"); 94: close(i); 95: 96: if (aflag) 97: { 98: closer(&Attdes); 99: cleanrel(&Admin.adattd); 100: close(Admin.adattd.relfp); 101: bmove(desp, &Admin.adattd, sizeof *desp); 102: ingresname(Admin.adattd.reldum.relid, Admin.adattd.reldum.relowner, temprel); 103: if ((Admin.adattd.relfp = open(temprel, O_RDWR)) < 0) 104: syserr("MODUPDATE: open wr Admin.adattd %d", Admin.adattd.relfp); 105: Admin.adattd.relopn = (Admin.adattd.relfp + 1) * -5; 106: } 107: else 108: { 109: closer(&Reldes); 110: cleanrel(&Admin.adreld); 111: close(Admin.adreld.relfp); 112: bmove(desp, &Admin.adreld, sizeof *desp); 113: if ((Admin.adreld.relfp = open(temprel, O_RDWR)) < 0) 114: syserr("MODUPDATE: open Admin.adreld %d", 115: Admin.adreld.relfp); 116: Admin.adreld.relopn = (Admin.adreld.relfp + 1) * -5; 117: } 118: } 119: 120: if (i = get(&Admin.adreld, &desp->reltid, &desp->reltid, &oldreltup, FALSE)) 121: syserr("MODUPDATE: get oldrel=%d",i); 122: 123: btreename(desp->reldum.relid, btree); 124: if (oldreltup.reldim > 0) 125: /* relation formerly ordered */ 126: { 127: capital(trim_relname(desp->reldum.relid), btreesec); 128: newpv[0].pv_val.pv_str = btreesec; 129: newpv[1].pv_type = PV_EOF; 130: if (destroy(1, newpv)) 131: syserr("can't destroy btreesec"); 132: unlink(btree); 133: 134: /* remove tuple corresponding to LID field from attribute 135: ** relation 136: */ 137: setkey(&Admin.adattd, &attkey, desp->reldum.relid, ATTRELID); 138: setkey(&Admin.adattd, &attkey, desp->reldum.relowner, ATTOWNER); 139: numatts = oldreltup.relatts - oldreltup.reldim + 1; 140: for (i = oldreltup.reldim; i > 0; i--, numatts++) 141: { 142: setkey(&Admin.adattd, &attkey, &numatts, ATTID); 143: if (getequal(&Admin.adattd, &attkey, &atttup, &tid) == 0) 144: if (delete(&Admin.adattd, &tid) < 0) 145: syserr("MODUPDATE: Can't delete LID field from attribute relation"); 146: } 147: } 148: 149: /* update attribute relation */ 150: 151: Admin.adattd.relopn = (Admin.adattd.relfp + 1) * -5; 152: numatts = desp->reldum.relatts - desp->reldum.reldim; 153: for (i = numatts; i > 0; i--) 154: { 155: getbatch(&tid, sizeof tid); 156: getbatch(&atttup, sizeof atttup); 157: if (j = replace(&Admin.adattd, &tid, &atttup, FALSE)) 158: if (j < 0 || j == 2) 159: syserr("MODUPDATE:Replace error(att): %d", j); 160: } 161: 162: for (i = desp->reldum.reldim; i > 0; i--) 163: { 164: /* insert tuple corresponding to LID field into attribute relation */ 165: getbatch(&atttup, sizeof atttup); 166: if ((j = insert(&Admin.adattd, &tid, &atttup, FALSE) < 0)) 167: syserr("MODUPDATE: Insert error (att): %d", j); 168: } 169: 170: unlink(batchname); 171: 172: if (i = cleanrel(&Admin.adattd)) 173: syserr("MODUPDATE:clean att %d", i); 174: 175: /* update relation relation */ 176: 177: if ((i = replace(&Admin.adreld, &desp->reltid, desp, FALSE))) 178: if (i < 0 || i == 2) 179: syserr("MODUPDATE:Replace error(rel): %d", i); 180: 181: if (i = cleanrel(&Admin.adreld)) 182: syserr("MODUPDATE:clean rel %d", i); 183: 184: if (desp->reldum.reldim > 0) 185: /* link temporary BTree file to permanent storage */ 186: { 187: concat(BTREE, Fileset, temp_btree); 188: if (link(temp_btree, btree) == -1) 189: syserr("MODUPDATE: can't link: %s, %s", temp_btree, btree); 190: if (unlink(temp_btree) < 0) 191: syserr("modupdate: unlink %s", temp_btree); 192: } 193: 194: /* make the admin readonly */ 195: Admin.adattd.relopn = (Admin.adattd.relfp + 1) * 5; 196: 197: close(Batch_fp); 198: 199: /* if this is an index, change the relspec in the index catalog */ 200: if (oldreltup.relindxd == SECINDEX) 201: { 202: opencatalog("indexes", OR_WRITE); 203: setkey(&Inddes, &ikey, desp->reldum.relid, IRELIDI); 204: setkey(&Inddes, &ikey, desp->reldum.relowner, IOWNERP); 205: if ((i = getequal(&Inddes, &ikey, &itup, &tid)) == 0) 206: { 207: itup.irelspeci = desp->reldum.relspec; 208: if ((i = replace(&Inddes, &tid, &itup, 0)) != 0) 209: if (i < 0 || i == 2) 210: syserr("MODUPDATE: rep(ix) %d", i); 211: } 212: } 213: 214: else if (desp->reldum.relindxd == SECBASE) 215: { 216: /* destroy any secondary indexes on this primary */ 217: opencatalog("indexes", OR_WRITE); 218: setkey(&Inddes, &ikey, desp->reldum.relid, IRELIDP); 219: setkey(&Inddes, &ikey, desp->reldum.relowner, IOWNERP); 220: while ((i = getequal(&Inddes, &ikey, &itup, &tid)) == 0) 221: { 222: newpv[0].pv_val.pv_str = itup.irelidi; 223: newpv[1].pv_type = PV_EOF; 224: printf("destroying secondary index %s\n", trim_relname(itup.irelidi)); 225: if (destroy(1, newpv)) 226: syserr("MODUPDATE:Can't destroy %s", itup.irelidi); 227: } 228: } 229: if (i < 0) 230: syserr("MODUPDATE: geteq(ix)b %d", i); 231: 232: /* clean things up and exit */ 233: # ifdef xZTR1 234: if (tTf(34, 8)) 235: printf("Leaving modupdate\n"); 236: # endif 237: return (0); 238: }