1: # 2: /* 3: ** MODUPDATE 4: ** This routine is used to exicute the updates 5: ** for modifies so they are recoverable. 6: ** It is also used by restore to complete an aborted modify. 7: ** During a restore the Batch_recover flag should be set to 1; 8: */ 9: 10: # include "../ingres.h" 11: # include "../aux.h" 12: # include "../catalog.h" 13: # include "../access.h" 14: # include "../batch.h" 15: # include "../unix.h" 16: 17: modupdate() 18: { 19: char batchname[MAXNAME + 3]; 20: char temprel[MAXNAME+ 3]; 21: char relfile[MAXNAME + 3]; 22: register int i; 23: register int j; 24: struct stat sbuf; 25: char aflag; 26: struct tup_id tid; 27: struct descriptor desx; 28: struct attribute atttup; 29: struct relation oldreltup; 30: struct index ikey, itup; 31: char *newpv[2]; 32: extern struct descriptor Inddes, Attdes, Reldes; 33: register struct descriptor *desp; 34: char *trim_relname(); 35: long ltemp1, ltemp2; 36: 37: 38: desp = &desx; 39: concat(MODBATCH,Fileset,batchname); 40: concat(MODTEMP, Fileset, temprel); 41: 42: # ifdef xZTR1 43: if (tTf(20, 8)) 44: printf("Modupdate: %s, %s\n",batchname, temprel); 45: # endif 46: if ((Batch_fp = open(batchname, 0)) < 0) 47: syserr("MODUPDATE:Can't open %s", batchname); 48: Batch_cnt = BATCHSIZE; 49: Batch_dirty = FALSE; 50: getbatch(desp, sizeof *desp); 51: ingresname(desp->relid, desp->relowner, relfile); 52: 53: /* don't loose old file before verifying new file */ 54: if (stat(temprel, &sbuf) != -1) 55: { 56: unlink(relfile); /* Ok if failure */ 57: if (link(temprel, relfile) == -1) 58: syserr("MODUPDATE:Can't link: %s, %s", temprel, relfile); 59: unlink(temprel); 60: } 61: 62: else 63: if(stat(relfile, &sbuf) == -1 || !Batch_recovery) 64: syserr("MODUPDATE:Relation and/or temporary files for %s are missing", 65: relfile); 66: 67: 68: /* Update admin if this is relation or atribute relations */ 69: /* Should only happen in Sysmod */ 70: if ((aflag = bequal(desp->relid, "attribute ", 12)) || 71: bequal(desp->relid, "relation ", 12)) 72: { 73: ingresname(desp->relid, desp->relowner, temprel); 74: if ((i = open("admin", 2)) < 0) 75: syserr("MODUPDATE:Can't open admin file"); 76: ltemp1 = sizeof Admin.adhdr; 77: ltemp2 = sizeof *desp; 78: if (lseek(i, ltemp1, 0) < 0 || 79: (aflag && lseek(i, ltemp2, 1) < 0)) 80: syserr("MODUPDATE:Seek error"); 81: if (write(i, desp, sizeof *desp) != sizeof *desp) 82: syserr("MODUPDATE:Write error on admin"); 83: close(i); 84: 85: if (aflag) 86: { 87: closer(&Attdes); 88: cleanrel(&Admin.adattd); 89: close(Admin.adattd.relfp); 90: bmove(desp, &Admin.adattd, sizeof *desp); 91: ingresname(Admin.adattd.relid, Admin.adattd.relowner, temprel); 92: if ((Admin.adattd.relfp = open(temprel, 2)) < 0) 93: syserr("MODUPDATE: open wr Admin.adattd %d", Admin.adattd.relfp); 94: Admin.adattd.relopn = (Admin.adattd.relfp + 1) * -5; 95: } 96: else 97: { 98: closer(&Reldes); 99: cleanrel(&Admin.adreld); 100: close(Admin.adreld.relfp); 101: bmove(desp, &Admin.adreld, sizeof *desp); 102: if ((Admin.adreld.relfp = open(temprel, 2)) < 0) 103: syserr("MODUPDATE: open Admin.adreld %d", 104: Admin.adreld.relfp); 105: Admin.adreld.relopn = (Admin.adreld.relfp + 1) * -5; 106: } 107: } 108: 109: if (i = get(&Admin.adreld, &desp->reltid, &desp->reltid, &oldreltup, FALSE)) 110: syserr("MODUPDATE: get oldrel=%d",i); 111: /* update relation relation */ 112: 113: if ((i = replace(&Admin.adreld, &desp->reltid, desp, FALSE))) 114: if (i < 0 || i == 2) 115: syserr("MODUPDATE:Replace error(rel): %d", i); 116: if (i = cleanrel(&Admin.adreld)) 117: syserr("MODUPDATE:clean rel %d", i); 118: 119: /* update attribute relation */ 120: Admin.adattd.relopn = (Admin.adattd.relfp + 1) * -5; 121: for (i = desp->relatts; i > 0; i--) 122: { 123: getbatch(&tid, sizeof tid); 124: getbatch(&atttup, sizeof atttup); 125: if (j = replace(&Admin.adattd, &tid, &atttup, FALSE)) 126: if (j < 0 || j == 2) 127: syserr("MODUPDATE:Replace error(att): %d", j); 128: } 129: 130: if (i = cleanrel(&Admin.adattd)) 131: syserr("MODUPDATE:clean att %d", i); 132: 133: /* make the admin readonly */ 134: Admin.adattd.relopn = (Admin.adattd.relfp + 1) * 5; 135: 136: close(Batch_fp); 137: 138: /* if this is an index, change the relspec in the index catalog */ 139: if (oldreltup.relindxd < 0) 140: { 141: opencatalog("indexes", 2); 142: setkey(&Inddes, &ikey, desp->relid, IRELIDI); 143: setkey(&Inddes, &ikey, desp->relowner, IOWNERP); 144: if ((i = getequal(&Inddes, &ikey, &itup, &tid)) == 0) 145: { 146: itup.irelspeci = desp->relspec; 147: if ((i = replace(&Inddes, &tid, &itup, 0)) != 0) 148: if (i < 0 || i == 2) 149: syserr("MODUPDATE: rep(ix) %d", i); 150: } 151: } 152: 153: else if(desp->relindxd > 0) 154: { 155: /* destroy any secondary indexes on this primary */ 156: opencatalog("indexes", 2); 157: setkey(&Inddes, &ikey, desp->relid, IRELIDP); 158: setkey(&Inddes, &ikey, desp->relowner, IOWNERP); 159: while ((i = getequal(&Inddes, &ikey, &itup, &tid)) == 0) 160: { 161: newpv[0] = itup.irelidi; 162: newpv[1] = (char *) -1; 163: printf("destroying secondary index %s\n", trim_relname(itup.irelidi)); 164: if (destroy(1, newpv)) 165: syserr("MODUPDATE:Can't destroy %s", itup.irelidi); 166: } 167: } 168: if (i < 0) 169: syserr("MODUPDATE: geteq(ix)b %d", i); 170: 171: /* clean things up and exit */ 172: unlink(batchname); 173: # ifdef xZTR1 174: if (tTf(20, 8)) 175: printf("Leaving modupdate\n"); 176: # endif 177: return (0); 178: }