|
|
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.