|
|
1.1 root 1: # include <ingres.h>
2: # include <tree.h>
3: # include <symbol.h>
4: # include <pv.h>
5: # include "globs.h"
6: # include <sccs.h>
7:
8: SCCSID(@(#)ageval.c 7.1 2/5/81)
9:
10: /*
11: ** AGEVAL -- evaluate simple aggregate.
12: **
13: ** Ageval is passed the tree of a simple aggregate,
14: ** and an array of space to store the results. The
15: ** amount of space actually allocated is stored in
16: ** (*result)->sym.len
17: **
18: ** If the aggregate is unique (eg. countu, sumu, avgu)
19: ** or if the aggregate is multi-variable, special
20: ** processing is done. A temporary relation is formed
21: ** with a result domain for each single agg in the tree.
22: ** Decomp is called to retrieve
23: ** the values to be aggregated into that relation.
24: **
25: ** If the aggregate is unique, then duplicates are
26: ** removed from the temporary relation.
27: **
28: ** Next the aggregate is run on either the original relation
29: ** or on the temporary relation.
30: **
31: ** Finally the result is read from OVQP and if a
32: ** temporary relation was used, it is destroyed.
33: **
34: ** Trace Flags:
35: ** 41
36: */
37:
38:
39: QTREE *
40: ageval(tree, result)
41: QTREE *tree; /* root of aggregate */
42: QTREE *result[]; /* space for results */
43: {
44: register QTREE *aghead, *resdom, *aop;
45: QTREE *newtree;
46: QTREE *lnodv[MAXDOM + 2];
47: char agbuf[AGBUFSIZ];
48: int temp_relnum, i;
49: extern int derror();
50: extern QTREE *makroot(), *makavar(), *makresdom();
51:
52: # ifdef xDTR1
53: if (tTf(41, 2))
54: {
55: printf("entered ageval\n");
56: treepr(tree);
57: }
58: # endif
59:
60: aghead = tree;
61: aop = aghead->left;
62: temp_relnum = NORESULT;
63:
64: /* if PRIME or multi-var, form aggregate domain in temp relation */
65: if (prime(aop) || aghead->sym.value.sym_root.tvarc > 1)
66: {
67: initbuf(agbuf, AGBUFSIZ, AGBUFFULL, derror);
68:
69: lnodv[lnode(aop, lnodv, 0)] = 0;
70:
71: /* create new tree for retrieve and give it the qualification */
72: newtree = makroot(agbuf);
73: newtree->right = aghead->right;
74: aghead->right = De.de_qle;
75:
76: /* put a resdom on new tree for each aop in orig tree */
77: /* make each aop in orig tree reference new relation */
78: for (i = 0; aop = lnodv[i]; )
79: {
80:
81: /* create resdom for new tree */
82: resdom = makresdom(agbuf, aop);
83: resdom->sym.value.sym_resdom.resno = ++i;
84: resdom->right = aop->right;
85:
86: /* connect it to newtree */
87: resdom->left = newtree->left;
88: newtree->left = resdom;
89:
90: /* make orig aop reference new relation */
91: aop->right = makavar(resdom, FREEVAR, i);
92: }
93:
94: /* make result relation */
95: temp_relnum = mak_t_rel(newtree, "a", -1);
96:
97: /* prepare for query */
98: mapvar(newtree, 0);
99: decomp(newtree, mdRETR, temp_relnum);
100: De.de_rangev[FREEVAR].relnum = temp_relnum;
101: De.de_sourcevar = FREEVAR;
102:
103: /* if prime, remove dups */
104: if (prime(aghead->left))
105: {
106: /* modify to heapsort */
107: removedups(FREEVAR);
108: }
109:
110: }
111:
112: De.de_newq = 1;
113: De.de_newr = TRUE;
114:
115: call_ovqp(aghead, mdRETR, NORESULT); /* call ovqp with no result relation */
116: De.de_newq = 0;
117:
118: /* pick up results */
119: readagg_result(result);
120:
121: /* if temp relation was created, destroy it */
122: if (temp_relnum != NORESULT)
123: dstr_rel(temp_relnum);
124:
125: }
126: /*
127: ** Determine if an aggregate contains any
128: ** prime aggregates. Note that there might
129: ** be more than one aggregate.
130: */
131:
132: prime(aop)
133: QTREE *aop;
134: {
135: register QTREE *a;
136:
137: a = aop;
138: do
139: {
140: switch (a->sym.value.sym_op.opno)
141: {
142: case opCOUNTU:
143: case opSUMU:
144: case opAVGU:
145: return (TRUE);
146: }
147: } while (a = a->left);
148: return (FALSE);
149: }
150: /*
151: ** Remove dups from an unopened relation
152: ** by calling heapsort
153: */
154:
155: removedups(var)
156: int var;
157: {
158: register char *p;
159: char *rangename();
160:
161: closer1(var); /* guarantee that relation has been closed */
162: initp();
163: p = rangename(var); /* get name of relation */
164: # ifdef xDTR1
165: if (tTf(41, 1))
166: {
167: printf("removing dups from %s\n", p);
168: }
169: # endif
170: setp(PV_STR, p);
171: setp(PV_STR,"heapsort");
172: setp(PV_STR,"num");
173: call_dbu(mdMODIFY, FALSE);
174: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.