# include "../ingres.h" # include "../aux.h" # include "../catalog.h" # include "../access.h" # include "../lock.h" /* ** This is the DBU routine INDEX ** ** pc = # of parameters ** pv[0] points to primary relation name ** pv[1] points to index relation name ** pv[2] points to domain1 ** pv[3] points to domain2 ** . ** . ** . ** pv[pc] = -1 ** */ struct dom { int id; int off; int frml; char frm[5]; }; index(pc, pv) int pc; char **pv; { register int i; int j; register struct dom *dom; register char **p; char *primary, *indx; int ndoms, newpc; struct tup_id tid, hitid; struct tup_id xtid; char *newpv[MAXKEYS * 2 + 4]; char primtup[MAXTUP], systup[MAXTUP]; struct descriptor desc, pridesc; extern struct descriptor Reldes; extern struct descriptor Attdes; extern struct descriptor Inddes; struct relation relkey, reltup; struct attribute attkey, atttup; struct index indtup; struct dom domain[MAXKEYS]; primary = pv[0]; indx = pv[1]; # ifdef xZTR1 tTfp(5, -1, "index: (pri %s ind %s)\n", primary, indx); # endif i = openr(&pridesc, 0, primary); if (i == AMOPNVIEW_ERR) return (error(5306, primary, 0)); if (i > 0) return (error(5300, primary, 0)); if (i < 0) syserr("INDEX : openr (%.14s) %d", primary, i); if (!bequal(pridesc.relowner, Usercode, 2)) { i = 5303; } else if (pridesc.relstat & S_CATALOG) { i = 5305; } else if (pridesc.relindxd < 0) { i = 5304; } if (i) { closer(&pridesc); return (error(i, primary, 0)); } /* ** GATHER INFO. ON DOMAINS */ opencatalog("attribute", 2); setkey(&Attdes, &attkey, primary, ATTRELID); setkey(&Attdes, &attkey, pridesc.relowner, ATTOWNER); pc -= 2; p = &pv[2]; dom = domain; for (i = 0; i < pc; i++) { if (i >= MAXKEYS) { closer(&pridesc); return (error(5301, *p, primary, 0)); /* too many keys */ } setkey(&Attdes, &attkey, *p, ATTNAME); j = getequal(&Attdes, &attkey, &atttup, &tid); if (j < 0) syserr("INDEX: geteq att %d", j); if (j) { closer(&pridesc); return (error(5302, *p, 0)); /* key not in relation */ } dom->id = atttup.attid; dom->off = atttup.attoff; dom->frml = atttup.attfrml & 0377; dom->frm[0] = atttup.attfrmt; p++; dom++; } ndoms = i; noclose(&Attdes); /* ** The "order" of the steps have been altered to improve ** recovery possibilities */ /* ** STEP 1 & 2: CREATE INDEX RELATION. */ newpc = 0; newpv[newpc++] = "0202"; /* S_NOUPDT | S_INDEX | */ newpv[newpc++] = indx; p = &pv[2]; dom = domain; for (i = 0; i < pc; i++) { newpv[newpc++] = *p; itoa(dom->frml, &dom->frm[1]); newpv[newpc++] = dom->frm; dom++; p++; } newpv[newpc++] = "tidp"; newpv[newpc++] = "i4"; newpv[newpc] = (char *) -1; # ifdef xZTR1 if (tTf(5, 1)) { printf("create: "); prargs(newpc, newpv); } # endif if (create(newpc, newpv)) return (-1); /* This is done for concurrency reasons */ if (noclose(&Reldes)) syserr("index: noclose"); /* ** STEP 5: FILL UP THE SECONDARY INDEX FILE ITSELF */ if (Lockrel) /* set a shared relation lock */ setrll(A_SLP, pridesc.reltid, M_SHARE); if (i = openr(&desc, 2, indx)) syserr("INDEX: openr %.14s %d", indx, i); find(&pridesc, NOKEY, &tid, &hitid); while ((i = get(&pridesc, &tid, &hitid, primtup, TRUE)) == 0) { dom = domain; for (i = j = 0; j < ndoms; j++) { bmove(&primtup[dom->off], &systup[i], dom->frml); i += dom->frml; dom++; } bmove(&tid, &systup[i], sizeof tid); /* move in pointer */ if ((j = insert(&desc, &xtid, &systup, TRUE)) < 0) syserr("INDEX: insert %.14s %d", indx, j); } if (i < 0) syserr("INDEX: get %.14s %d", primary, i); closer(&pridesc); closer(&desc); /* ** STEP 3: ENTRIES TO INDEX-REL */ pmove(primary, indtup.irelidp, MAXNAME, ' '); /* mv in primary name */ bmove(pridesc.relowner, indtup.iownerp, 2); /* primary owner */ pmove(indx, indtup.irelidi, MAXNAME, ' '); /* index name */ indtup.irelspeci = M_HEAP; for (i = 0; i < MAXKEYS; i++) indtup.idom[i] = (i < ndoms) ? domain[i].id : 0; opencatalog("indexes", 2); if ((i = insert(&Inddes, &tid, &indtup, TRUE)) < 0) syserr("INDEX: insert ix %d", i); /* ** STEP 4: TURN BIT ON IN PRIMARY RELATION TO SHOW IT IS BEING INDEXED */ opencatalog("relation", 2); setkey(&Reldes, &relkey, primary, RELID); setkey(&Reldes, &relkey, pridesc.relowner, RELOWNER); if (i = getequal(&Reldes, &relkey, &reltup, &tid)) syserr("INDEX: geteq rel %d", i); reltup.relindxd = SECBASE; if ((i = replace(&Reldes, &tid, &reltup, TRUE)) < 0) syserr("INDEX: replace rel %d", i); if (Lockrel) unlrl(pridesc.reltid); /* release relation lock */ return (0); }