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