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

Defined functions

ageval defined in line 36; used 1 times
prime defined in line 117; used 5 times
Last modified: 1995-03-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3073
Valid CSS Valid XHTML 1.0 Strict