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
prime defined in line 133; used 5 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1182
Valid CSS Valid XHTML 1.0 Strict