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