1: # include <pv.h> 2: # include <func.h> 3: # include <symbol.h> 4: # include <ingres.h> 5: # include <aux.h> 6: # include <catalog.h> 7: # include <access.h> 8: # include <lock.h> 9: # include <sccs.h> 10: # include <errors.h> 11: 12: SCCSID(@(#)index.c 8.5 2/8/85) 13: 14: extern short tTdbu[]; 15: extern int indexx(); 16: extern int null_fn(); 17: 18: struct fn_def IndexFn = 19: { 20: "INDEX", 21: indexx, 22: null_fn, 23: null_fn, 24: NULL, 25: 0, 26: tTdbu, 27: 100, 28: 'Z', 29: 0 30: }; 31: 32: 33: /* 34: ** This is the DBU routine INDEX 35: ** 36: ** pc = # of parameters 37: ** pv[0] points to primary relation name 38: ** pv[1] points to index relation name 39: ** pv[2] points to domain1 40: ** pv[3] points to domain2 41: ** . 42: ** . 43: ** . 44: ** pv[pc] = NULL 45: ** 46: */ 47: 48: struct dom 49: { 50: int id; 51: int off; 52: int frml; 53: char frm[5]; 54: }; 55: 56: indexx(pc, pv) 57: int pc; 58: PARM pv[]; 59: { 60: register int i; 61: int j; 62: register struct dom *dom; 63: register PARM *p; 64: char *primary, *indx; 65: int ndoms, newpc; 66: struct tup_id tid, hitid; 67: struct tup_id xtid; 68: PARM newpv[MAXKEYS * 2 + 4]; 69: char primtup[MAXTUP], systup[MAXTUP]; 70: DESC desc, pridesc; 71: extern DESC Reldes; 72: extern DESC Attdes; 73: extern DESC Inddes; 74: struct relation relkey, reltup; 75: struct attribute attkey, atttup; 76: struct index indtup; 77: struct dom domain[MAXKEYS]; 78: 79: primary = pv[0].pv_val.pv_str; 80: indx = pv[1].pv_val.pv_str; 81: # ifdef xZTR1 82: if (tTf(33, -1)) 83: printf("index: (pri %s ind %s)\n", primary, indx); 84: # endif 85: i = openr(&pridesc, OR_READ, primary); 86: if (i == AMOPNVIEW_ERR) 87: return (error(NOINDVIEW, primary, 0)); 88: if (i > 0) 89: return (error(NOPRIMREL, primary, 0)); 90: if (i < 0) 91: syserr("INDEX : openr (%.14s) %d", primary, i); 92: 93: if (!bequal(pridesc.reldum.relowner, Usercode, UCODE_SZ)) 94: { 95: i = NOTOWNED; 96: } 97: else if (pridesc.reldum.relstat & S_CATALOG) 98: { 99: i = NOINDXSYSREL; 100: } 101: else if (pridesc.reldum.relindxd == SECINDEX) 102: { 103: i = ALREADYINDX; 104: } 105: 106: if (i) 107: { 108: closer(&pridesc); 109: return (error(i, primary, 0)); 110: } 111: /* 112: ** GATHER INFO. ON DOMAINS 113: */ 114: opencatalog("attribute", OR_WRITE); 115: setkey(&Attdes, &attkey, primary, ATTRELID); 116: setkey(&Attdes, &attkey, pridesc.reldum.relowner, ATTOWNER); 117: pc -= 2; 118: p = &pv[2]; 119: dom = domain; 120: for (i = 0; i < pc; i++) 121: { 122: if (i >= MAXKEYS) 123: { 124: closer(&pridesc); 125: return (error(TOOMUCHDOMS, (p->pv_val).pv_str, primary, 0)); /* too many keys */ 126: } 127: setkey(&Attdes, &attkey, (p->pv_val).pv_str, ATTNAME); 128: j = getequal(&Attdes, &attkey, &atttup, &tid); 129: if (j < 0) 130: syserr("INDEX: geteq att %d", j); 131: if (j) 132: { 133: closer(&pridesc); 134: return (error(NODOM, (p->pv_val).pv_str, 0)); /* key not in relation */ 135: } 136: if (pridesc.reldum.reldim > 0 && atttup.attid == pridesc.reldum.relatts) 137: /* attempting to use lid field as part of index */ 138: { 139: closer(&pridesc); 140: return(error(NOINDXLID, primary, (p->pv_val).pv_str, 0)); 141: } 142: dom->id = atttup.attid; 143: dom->off = atttup.attoff; 144: dom->frml = atttup.attfrml & I1MASK; 145: dom->frm[0] = atttup.attfrmt; 146: p++; 147: dom++; 148: } 149: ndoms = i; 150: noclose(&Attdes); 151: 152: /* 153: ** The "order" of the steps have been altered to improve 154: ** recovery possibilities 155: */ 156: /* 157: ** STEP 1 & 2: CREATE INDEX RELATION. 158: */ 159: newpv[0].pv_val.pv_str = "0202"; 160: newpv[1].pv_val.pv_str = indx; 161: newpc = 2; 162: p = &pv[2]; 163: dom = domain; 164: for (i = 0; i < pc; i++) 165: { 166: newpv[newpc++].pv_val.pv_str = (p->pv_val).pv_str; 167: itoa(dom->frml, &dom->frm[1]); 168: newpv[newpc++].pv_val.pv_str = dom->frm; 169: dom++; 170: p++; 171: } 172: newpv[newpc++].pv_val.pv_str = "tidp"; 173: newpv[newpc++].pv_val.pv_str = "i4"; 174: newpv[newpc].pv_type = PV_EOF; 175: 176: if (create(newpc, newpv)) 177: { 178: closer(&pridesc); 179: return (-1); 180: } 181: 182: /* This is done for concurrency reasons */ 183: if (noclose(&Reldes)) 184: syserr("index: noclose"); 185: 186: /* 187: ** STEP 5: FILL UP THE SECONDARY INDEX FILE ITSELF 188: */ 189: if (Lockrel) 190: /* set a shared relation lock */ 191: setrll(A_SLP, *(long *) &pridesc.reltid, M_SHARE); /* pardon the kludge */ 192: if (i = openr(&desc, OR_WRITE, indx)) 193: syserr("INDEX: openr %.14s %d", indx, i); 194: find(&pridesc, NOKEY, &tid, &hitid); 195: while ((i = get(&pridesc, &tid, &hitid, primtup, TRUE)) == 0) 196: { 197: dom = domain; 198: for (i = j = 0; j < ndoms; j++) 199: { 200: bmove(&primtup[dom->off], &systup[i], dom->frml); 201: i += dom->frml; 202: dom++; 203: } 204: bmove(&tid, &systup[i], sizeof tid); /* move in pointer */ 205: if ((j = insert(&desc, &xtid, systup, TRUE)) < 0) 206: syserr("INDEX: insert %.14s %d", indx, j); 207: } 208: if (i < 0) 209: syserr("INDEX: get %.14s %d", primary, i); 210: closer(&pridesc); 211: closer(&desc); 212: 213: 214: /* 215: ** STEP 3: ENTRIES TO INDEX-REL 216: */ 217: pmove(primary, indtup.irelidp, MAXNAME, ' '); /* mv in primary name */ 218: bmove(pridesc.reldum.relowner, indtup.iownerp, 2); /* primary owner */ 219: pmove(indx, indtup.irelidi, MAXNAME, ' '); /* index name */ 220: indtup.irelspeci = M_HEAP; 221: for (i = 0; i < MAXKEYS; i++) 222: indtup.idom[i] = (i < ndoms) ? domain[i].id : 0; 223: opencatalog("indexes", OR_WRITE); 224: if ((i = insert(&Inddes, &tid, &indtup, TRUE)) < 0) 225: syserr("INDEX: insert ix %d", i); 226: 227: /* 228: ** STEP 4: TURN BIT ON IN PRIMARY RELATION TO SHOW IT IS BEING INDEXED 229: */ 230: opencatalog("relation", OR_WRITE); 231: setkey(&Reldes, &relkey, primary, RELID); 232: setkey(&Reldes, &relkey, pridesc.reldum.relowner, RELOWNER); 233: if (i = getequal(&Reldes, &relkey, &reltup, &tid)) 234: syserr("INDEX: geteq rel %d", i); 235: reltup.relindxd = SECBASE; 236: if ((i = replace(&Reldes, &tid, &reltup, TRUE)) < 0) 237: syserr("INDEX: replace rel %d", i); 238: 239: if (Lockrel) 240: unlrl(*(long *) &pridesc.reltid); /* release relation lock */ 241: 242: return (0); 243: }