|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.