|
|
1.1 root 1: # include <errors.h>
2: # include <ingres.h>
3: # include <aux.h>
4: # include <opsys.h>
5: # include <access.h>
6: # include <tree.h>
7: # include <symbol.h>
8: # include "globs.h"
9: # include <sccs.h>
10:
11: SCCSID(@(#)call_ovqp.c 8.6 12/18/85)
12:
13:
14: /*
15: ** CALL_OVQP -- Routines which interface to the One Variable Query Processor.
16: **
17: ** This file contains the routines associated with sending queries
18: ** and receiving results from OVQP. The interface to these routines is
19: ** still messy. Call_ovqp is given the query, mode, and result relation
20: ** as parameters and gets the source relation, and two flags
21: ** (De.de_newq, De.de_newr) as globals. The routines include:
22: **
23: ** Call_ovqp -- Sends a One-var query to ovqp and flushes the pipe.
24: **
25: ** Readresult -- Reads the result from a one-var query.
26: **
27: ** Endovqp -- Informs ovqp that the query is over. Helps to synchronize
28: ** the batch file (if any).
29: **
30: ** Trace Flags:
31: ** 61
32: */
33: /*
34: ** Call_ovqp -- send query down pipe to ovqp and flush pipe.
35: ** Inputs are:
36: ** mode retrieve, append, etc.
37: ** resultnum result relation id
38: ** tree the query
39: ** De.de_sourcevar (global) if >= 0 then source var
40: ** De.de_newq send NEWQ symbol
41: ** De.de_newr send NEWR symbol
42: */
43:
44: call_ovqp(tree, mode, resultnum)
45: register QTREE *tree;
46: int mode;
47: int resultnum;
48: {
49: register int i;
50: char *rangename();
51: extern int derror();
52: extern bool Batchupd;
53: extern DESC Inddes;
54: int ovqpbuf[1+LBUFSIZE/sizeof(int)];
55: DESC *readopen();
56: extern DESC *specopen();
57: extern char *rnum_convert();
58:
59:
60: # ifdef xDTR1
61: if (tTf(61, -1))
62: {
63: if (tTf(61, 0))
64: printf("CALL_OVQP-\n");
65: if (tTf(61, 1))
66: {
67: if (De.de_newq)
68: {
69: printf("new query to ovqp\n");
70: treepr(tree);
71: }
72: else
73: printf("query same as previous\n");
74: }
75: if (tTf(61, 2))
76: {
77: printf("De.de_sourcevar=%d\t", De.de_sourcevar);
78: if (De.de_sourcevar >= 0)
79: printf("relid=%s\t", rangename(De.de_sourcevar));
80: if (resultnum >= 0)
81: printf("De.ov_resultname=%s", rnum_convert(resultnum));
82: if (tree->sym.value.sym_root.rootuser)
83: printf(", userqry");
84: printf("\n");
85: }
86: }
87: # endif
88:
89:
90:
91: /* assign mode of this query */
92: De.de_qmode = mode;
93:
94: if (De.de_newr)
95: {
96: De.de_newr = FALSE;
97: }
98:
99: if (resultnum >= 0)
100: {
101: De.ov_result = specopen(resultnum);
102: }
103: else
104: De.ov_result = NULL;
105:
106: if (De.de_sourcevar >= 0)
107: De.ov_source = readopen(De.de_sourcevar);
108: else
109: De.ov_source = NULL;
110:
111: /* assume this will be direct update */
112: De.ov_userqry = De.de_buflag = FALSE;
113:
114: if (tree->sym.value.sym_root.rootuser)
115: {
116: De.ov_userqry = TRUE;
117: /* handle batch file */
118: if (De.ov_result && De.de_qmode != mdRETR)
119: {
120: if (Batchupd || De.ov_result->reldum.relindxd > 0)
121: {
122: if (De.ov_bopen == 0)
123: {
124: if (De.ov_result->reldum.relindxd > 0)
125: opencatalog("indexes", OR_READ);
126: if (i = openbatch(De.ov_result, &Inddes, De.de_qmode))
127: syserr("call_ovqp:opn batch %d", i);
128: De.ov_bopen = TRUE;
129: }
130: De.de_buflag = TRUE;
131: }
132: }
133: }
134:
135: /* now write the query list itself */
136: if (De.de_newq)
137: {
138: De.ov_ovqpbuf = (char *)ovqpbuf;
139: initbuf(De.ov_ovqpbuf, LBUFSIZE, LISTFULL, derror);
140: De.de_qvptr = 0;
141: De.ov_alist = De.ov_bylist = De.ov_qlist = De.ov_tlist = NULL;
142: De.ov_targvc = tree->sym.value.sym_root.lvarc;
143: De.ov_qualvc = bitcnt(tree->sym.value.sym_root.rvarm);
144: De.ov_agcount = 0;
145:
146: if (tree->sym.type == AGHEAD)
147: {
148: De.ov_alist = &De.de_qvect[0];
149: if (tree->left->sym.type == BYHEAD)
150: {
151: mklist(tree->left->right);
152: ovqpnod(tree->left); /* BYHEAD node */
153: De.ov_bylist = &De.de_qvect[De.de_qvptr];
154: mklist(tree->left->left);
155: }
156: else
157: mklist(tree->left);
158: }
159: else
160: {
161: if (tree->left->sym.type != TREE)
162: {
163: De.ov_tlist = &De.de_qvect[0];
164: mklist(tree->left);
165: }
166: }
167:
168: /* now for the qualification */
169: ovqpnod(tree); /* ROOT node */
170:
171: if (tree->right->sym.type != QLEND)
172: {
173: De.ov_qlist = &De.de_qvect[De.de_qvptr];
174: mklist(tree->right);
175: }
176: ovqpnod(De.de_qle); /* QLEND node */
177: }
178:
179: /* Now call ovqp */
180: if (strategy())
181: {
182: i = scan(); /* scan the relation */
183: }
184: else
185: i = EMPTY;
186:
187: /* return result of query */
188: return (i == NONEMPTY); /* TRUE if tuple satisfied */
189: }
190: /*
191: ** Endovqp -- Inform ovqp that processing is complete. "Ack" indicates
192: ** whether to wait for an acknowledgement from ovqp. The overall
193: ** mode of the query is sent followed by an EXIT command.
194: **
195: ** Ovqp decides whether to use batch update or not. If ack == ACK
196: ** then endovqp will read a RETVAL symbol from ovqp and return
197: ** a token which specifies whether to call the update processor or not.
198: */
199:
200: endovqp(ack)
201: int ack;
202: {
203: register int i;
204:
205: if (ack != RUBACK)
206: {
207: if (Equel && De.de_qry_mode == mdRETTERM)
208: equeleol(EXIT); /* signal end of retrieve to equel process */
209: }
210:
211: i = NOUPDATE;
212:
213: if (ack == ACK)
214: {
215: if (De.ov_bopen)
216: {
217: closebatch();
218: De.ov_bopen = FALSE;
219: i = UPDATE;
220: }
221: }
222: else
223: {
224: if (De.ov_bopen)
225: {
226: rmbatch();
227: De.ov_bopen = FALSE;
228: }
229: }
230:
231: closecatalog(FALSE);
232:
233: return (i);
234: }
235: /*
236: ** Add node q to ovqp's list
237: */
238:
239: ovqpnod(q)
240: register QTREE *q;
241: {
242: register SYMBOL *s;
243: extern QTREE *ckvar();
244: extern char *need();
245: register int i;
246:
247: s = &q->sym;
248:
249: /* VAR nodes must be specially processed */
250: if (s->type == VAR)
251: {
252: /* locate currently active VAR */
253: q = ckvar(q);
254:
255: /* Allocate an ovqp var node for the VAR */
256: s = (SYMBOL *) need(De.ov_ovqpbuf, SYM_HDR_SIZ + sizeof s->value.sym_var);
257: s->len = sizeof s->value.sym_var;
258: s->value.sym_var.attno = q->sym.value.sym_var.attno;
259: s->value.sym_var.varfrmt = q->sym.value.sym_var.varfrmt;
260: s->value.sym_var.varfrml = q->sym.value.sym_var.varfrml;
261: s->value.sym_var.varstr = q->sym.value.sym_var.varstr;
262:
263: /* If VAR has been substituted for, get value */
264: if (q->sym.value.sym_var.valptr)
265: {
266: /* This is a substituted variable */
267: if (q->sym.value.sym_var.varno == De.de_sourcevar)
268: syserr("ovqpnod:bd sub %d,%d", q->sym.value.sym_var.varno, De.de_sourcevar);
269:
270: s->type = S_VAR;
271: s->value.sym_var.valptr = q->sym.value.sym_var.valptr;
272: }
273: else
274: {
275: /* Var for one variable query */
276: if (q->sym.value.sym_var.varno != De.de_sourcevar)
277: syserr("ovqpnod:src var %d,%d", q->sym.value.sym_var.varno, De.de_sourcevar);
278: s->type = VAR;
279: i = q->sym.value.sym_var.attno;
280: if (i != 0)
281: s->value.sym_var.valptr = (ANYTYPE *) (De.ov_intup + De.ov_source->reloff[i]);
282: else
283: s->value.sym_var.valptr = (ANYTYPE *) &De.ov_intid;
284: }
285: }
286: if (s->type == AOP)
287: De.ov_agcount++;
288:
289: /* add symbol to list */
290: if (De.de_qvptr > MAXNODES - 1)
291: ov_err(NODOVFLOW);
292: De.de_qvect[De.de_qvptr++] = s;
293: }
294: /*
295: ** READAGG_RESULT
296: */
297:
298: readagg_result(result)
299: QTREE *result[];
300: {
301: register QTREE **r, *aop;
302: register int i;
303:
304: De.ov_tend = De.ov_outtup;
305: r = result;
306:
307: while (aop = *r++)
308: {
309: i = aop->sym.len & I1MASK;
310:
311: if (aop->sym.type == CHAR)
312: pad(De.ov_tend, i);
313:
314: bmove(De.ov_tend, (char *)&aop->sym.value, i);
315:
316: De.ov_tend += i;
317: # ifdef xDTR1
318: if (tTf(61, 3))
319: nodepr(aop);
320: # endif
321: }
322: }
323:
324:
325: ov_err(code)
326: int code;
327: {
328: derror(code);
329: }
330:
331:
332: DESC *
333: openindex(name)
334: char *name;
335: {
336: register DESC *d;
337: register int varno;
338: DESC *readopen();
339:
340: varno = SECINDVAR;
341: De.de_rangev[varno].relnum = rnum_findadd(name);
342: d = readopen(varno);
343: return (d);
344: }
345: /*
346: ** Use "closer()" for closing relations. See
347: ** desc_close in openrs.c for details.
348: */
349: extern int closer();
350: int (*Des_closefunc)() = closer;
351:
352: init_decomp()
353: {
354: static struct accbuf xtrabufs[12];
355:
356: set_so_buf();
357: acc_addbuf(xtrabufs, 12);
358: }
359:
360:
361: startdecomp()
362: {
363: /* called at the start of each user query */
364: initrange();
365: rnum_init();
366: startovqp();
367: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.