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