1: # include <pv.h> 2: # include <ingres.h> 3: # include <aux.h> 4: # include <catalog.h> 5: # include <func.h> 6: # include <sccs.h> 7: # include <errors.h> 8: 9: SCCSID(@(#)destroy.c 8.3 2/8/85) 10: 11: extern short tTdbu[]; 12: extern int destroy(); 13: extern int null_fn(); 14: 15: struct fn_def DstroyFn = 16: { 17: "DESTROY", 18: destroy, 19: null_fn, 20: null_fn, 21: NULL, 22: 0, 23: tTdbu, 24: 100, 25: 'Z', 26: 0 27: }; 28: 29: 30: /* 31: ** DESTROY RELATION 32: ** 33: ** The relations in pv are destroyed. This involves three steps: 34: ** 1 - remove tuple from relation relation 35: ** 2 - remove tuples from attribute relation 36: ** 3 - unlink physical file 37: ** 38: ** If the relation is a secondary index, the entry is removed 39: ** from the index relation, and the primary relation is set to 40: ** be "not indexed" (unless there is another index on it). 41: ** 42: ** If the relation has an index, all its indexes are also 43: ** destroyed. 44: ** 45: ** If any errors occured while destroying the relations, 46: ** then the last error number is returned, otherwise 47: ** 0 is returned. 48: ** 49: ** If any query modification was defined on the relation, 50: ** the qrymod catalogues are updated. 51: ** 52: ** Trace Flags: 53: ** 32 54: */ 55: 56: destroy(pc, pv) 57: int pc; 58: PARM *pv; 59: { 60: register int i, ret; 61: register char *name; 62: 63: opencatalog("relation", OR_WRITE); 64: opencatalog("attribute", OR_WRITE); 65: 66: for (ret = 0; pc-- > 0; ) 67: { 68: name = ((pv++)->pv_val).pv_str; 69: if (i = des(name)) 70: ret = i; 71: } 72: return (ret); 73: } 74: 75: 76: des(name) 77: char *name; 78: { 79: register int i; 80: register char *relname; 81: struct tup_id tid; 82: char newrelname[MAXNAME + 3]; 83: extern DESC Reldes, Attdes, Inddes, Treedes; 84: struct relation relt, relk; 85: 86: relname = name; 87: # ifdef xZTR1 88: tTfp(32, -1, "destroy: %s\n", relname); 89: # endif 90: 91: newrelname[MAXNAME + 2] = 0; 92: 93: /* get the tuple from relation relation */ 94: setkey(&Reldes, &relk, relname, RELID); 95: setkey(&Reldes, &relk, Usercode, RELOWNER); 96: if ((i = getequal(&Reldes, &relk, &relt, &tid)) != 0) 97: { 98: if (i < 0) 99: syserr("DESTROY: geteq(rel/%s) %d", relname, i); 100: return (nferror(RELNOEXIST, relname, 0)); /* nonexistant relation */ 101: } 102: 103: /* don't allow a system relation to be destroyed */ 104: if (relt.relstat & S_CATALOG) 105: return (nferror(NODESTSYSREL, relname, 0)); /* attempt to destroy system catalog */ 106: 107: if ((i = delete(&Reldes, &tid)) != 0) 108: syserr("DESTROY: delete(rel) %d", i); 109: 110: /* 111: ** for concurrency reasons, flush the relation-relation page 112: ** where the tuple was just deleted. This will prevent anyone 113: ** from being able to "openr" the relation while it is being 114: ** destroyed. It also allows recovery to finish the destroy 115: ** it the system crashes during this destroy. 116: */ 117: if (i = flush_rel(&Reldes, FALSE)) 118: syserr("destroy:flush rel %d", i); 119: 120: purgetup(&Attdes, relt.relid, ATTRELID, relt.relowner, ATTOWNER, 0); 121: 122: /* 123: ** If this is a user relation, then additional processing 124: ** might be needed to clean up indicies, protection constraints 125: ** etc. 126: */ 127: if ((relt.relstat & S_CATALOG) == 0) 128: userdestroy(&relt); 129: 130: if ((relt.relstat & S_VIEW) == 0) 131: { 132: ingresname(relname, Usercode, newrelname); 133: if (unlink(newrelname) < 0) 134: syserr("destroy: unlink(%.14s)", newrelname); 135: } 136: return (0); 137: 138: }