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