1: # include <ingres.h> 2: # include <catalog.h> 3: # include <symbol.h> 4: # include <lock.h> 5: # include <tree.h> 6: # include "qrymod.h" 7: # include <sccs.h> 8: 9: SCCSID(@(#)puttree.c 8.2 1/15/85) 10: 11: /* 12: ** PUTTREE -- put tree into 'tree' catalog 13: ** 14: ** The named tree is inserted into the 'tree' catalog. 15: ** 16: ** The algorithm is to lock up the entire catalog and try to 17: ** find the smallest unique id possible for the named relation. 18: ** 19: ** Parameters: 20: ** root -- the root of the tree to insert. 21: ** treerelid -- the relid of the relation for which 22: ** this tree applies. 23: ** treeowner -- the owner of the above relation. 24: ** treetype -- the type of this tree; uses the mdXXX 25: ** type (as mdPROT, mdINTEG, mdDISTR, etc.). 26: ** 27: ** Returns: 28: ** The treeid that was assigned to this tree. 29: ** 30: ** Side Effects: 31: ** The tree catalog gets locked, and information is 32: ** inserted. 33: ** 34: ** Trace Flags: 35: ** 10 36: */ 37: 38: puttree(root, trelid, towner, ttype) 39: QTREE *root; 40: char *trelid; 41: char *towner; 42: int ttype; 43: { 44: struct tree treekey; 45: struct tree treetup; 46: struct tup_id treetid; 47: register int i; 48: auto int treeid; 49: 50: opencatalog("tree", OR_WRITE); 51: 52: /* 53: ** Find a unique tree identifier. 54: ** Lock the tree catalog, and scan until we find a 55: ** tuple which does not match. 56: */ 57: 58: setrll(A_SLP, Treedes.reltid.ltid, M_EXCL); 59: 60: setkey(&Treedes, &treekey, trelid, TREERELID); 61: setkey(&Treedes, &treekey, towner, TREEOWNER); 62: setkey(&Treedes, &treekey, &ttype, TREETYPE); 63: for (treeid = 0;; treeid++) 64: { 65: setkey(&Treedes, &treekey, &treeid, TREEID); 66: i = getequal(&Treedes, &treekey, &treetup, &treetid); 67: if (i < 0) 68: syserr("d_tree: getequal"); 69: else if (i > 0) 70: break; 71: } 72: 73: /* 74: ** We have a unique tree id. 75: ** Insert the new tuple and the tree into the 76: ** tree catalog. 77: */ 78: 79: relntrwr(NULL, 0, trelid, towner, ttype, treeid); 80: writeqry(root, relntrwr, 0); 81: relntrwr(NULL, 1); 82: 83: /* all inserted -- flush pages and unlock */ 84: if (noclose(&Treedes) != 0) 85: syserr("d_tree: noclose"); 86: unlrl(Treedes.reltid.ltid); 87: 88: return(treeid); 89: } 90: /* 91: ** RELNTRWR -- physical tree write to relation 92: ** 93: ** This is the routine called from writeqry to write trees 94: ** to the 'tree' relation (rather than the W_down pipe). 95: ** 96: ** It is assumed that the (treerelid, treeowner, treetype, 97: ** treeid) combination is unique in the tree catalog, and that 98: ** the tree catalog is locked. 99: ** 100: ** Parameters: 101: ** ptr -- a pointer to the data. If NULL, this is 102: ** a control call. 103: ** len -- the length of the data. If ptr == NULL, this 104: ** field is a control code: zero means 105: ** initialize (thus taking the next two param- 106: ** eters); one means flush. 107: ** treerelid -- the name of the relation for which this 108: ** tree applies (init only). 109: ** treeowner -- the owner of this relation (init only). 110: ** treetype -- on initialization, this tells what the 111: ** tree is used for. 112: ** treeid -- on initialization, this is the tree id we 113: ** want to use. 114: ** 115: ** Returns: 116: ** The number of bytes written ('len'). 117: ** 118: ** Side Effects: 119: ** Well, yes. Activity occurs in the tree catalog. 120: ** 121: ** Trace Flags: 122: ** none 123: */ 124: 125: relntrwr(ptr, len, treerelid, treeowner, treetype, treeid) 126: char *ptr; 127: int len; 128: char *treerelid; 129: char *treeowner; 130: int treetype; 131: int treeid; 132: { 133: static struct tree treetup; 134: struct tup_id treetid; 135: register char *p; 136: register int l; 137: static char *tptr; 138: 139: p = ptr; 140: l = len; 141: 142: /* check for special function */ 143: if (p == NULL) 144: { 145: switch (l) 146: { 147: case 0: 148: clr_tuple(&Treedes, &treetup); 149: bmove(treerelid, treetup.treerelid, MAXNAME); 150: bmove(treeowner, treetup.treeowner, 2); 151: treetup.treetype = treetype; 152: treetup.treeid = treeid; 153: tptr = treetup.treetree; 154: break; 155: 156: case 1: 157: if (tptr != treetup.treetree) 158: { 159: if (insert(&Treedes, &treetid, &treetup, FALSE) < 0) 160: syserr("relntrwr: insert 1"); 161: } 162: break; 163: 164: default: 165: syserr("relntrwr: ctl %d", l); 166: } 167: return; 168: } 169: 170: /* output bytes */ 171: while (l-- > 0) 172: { 173: *tptr++ = *p++; 174: 175: /* check for buffer overflow */ 176: if (tptr < &treetup.treetree[sizeof treetup.treetree]) 177: continue; 178: 179: /* yep, flush buffer to relation */ 180: if (insert(&Treedes, &treetid, &treetup, FALSE) < 0) 181: syserr("relntrwr: insert 2"); 182: treetup.treeseq++; 183: tptr = treetup.treetree; 184: 185: /* clear out the rest of the tuple for aesthetic reasons */ 186: *tptr = ' '; 187: bmove(tptr, tptr + 1, sizeof treetup.treetree - 1); 188: } 189: 190: return (len); 191: }