|
|
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: # 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.