# 2.11BSD#431 - /usr/ingres/source/decomp/byeval.c

##### Functions

    byeval            X
    modqual           X

       1: # include   "../ingres.h"
       2: # include   "../tree.h"
       3: # include   "../symbol.h"
       4: # include   "decomp.h"
       5:
       6: /*
       7: **	BYEVAL - process aggregate function
       8: **
       9: **	Byeval is passed the root of the original query
      10: **	tree and the root of the aggregate function to
      11: **	be processed.
      12: **
      13: **	It first creates a temporary relation which will
      14: **	hold the aggregate result. The format of the relation
      15: **	is:
      16: **	_SYSxxxxxaa(count, by-dom1, ... , by-domn, ag1, ... , agm)
      17: **
      18: **	The relation is moved into the range table and will become
      19: **	a part of the query.
      20: **
      21: **	If there are any occurences of the variables
      22: **	from the by-domains, anywhere in the original query tree,
      23: **	the aggregate relation is linked on all by-domains in the
      24: **	original query tree.
      25: **
      26: **	If the aggregate is unique, multivariable, or has a
      27: **	qualification, then special processing is done.
      28: **
      29: **	If the aggregate is qualified then the by-domains are
      30: **	projected into the result relation. This guarantees that
      31: **	every value of the by-domains will be represented in the
      32: **	aggregate result.
      33: **
      34: **	If the aggregate is unique or multivariable, then another
      35: **	temporary relation is created and the values which will be
      36: **	aggregated; along with the by-domains, are retrieved into
      37: **	the temporary relation.
      38: **
      39: **	If unique, then duplicates are removed from the temporary relation.
      40: **
      41: **	Next the result relation for the aggregate is modified
      42: **	to hash in order to speed up the processing of the aggregate
      43: **	and guarantee that there are no duplicates in the bylist.
      44: **
      45: **	The aggregate is then run, and if a temporary relation was
      46: **	created (eg. unique or multivar aggregate) then it is destroyed.
      47: **
      48: */
      49:
      50:
      51: struct querytree *byeval(root, aghead, agvar)
      52: struct querytree    *root;      /* root of orig query */
      53: struct querytree    *aghead;    /* root of ag fcn sub-tree */
      54: int         agvar;      /* variable number assigned to this aggregate */
      55:
      56: {
      57:
      58:     register struct querytree   *q, *ag, *resdom;
      59:     struct querytree        *r;
      60:     int             temp_relnum, i, filled;
      61:     struct querytree        *lnodv[MAXDOM+2], *save_node[MAXDOM+2];
      62:     char                agbuf[AGBUFSIZ];
      63:     char                nums[2];
      64:     int             relnum;
      65:     struct querytree        *byhead, **alnp;
      66:     int             bydoms, bymap, primeag, srcmap;
      67:     extern int          derror();
      68:     extern struct querytree     *makroot(), *makresdom(), *copytree(), *makavar();
      69:
      70: #	ifdef xDTR1
      71:     if (tTf(7, -1))
      72:         printf("BYEVAL\n");
      73: #	endif
      74:
      75:     ag = aghead;
      76:     byhead = ag->left;
      77:
      78:     /* first create the aggregate result relation */
      79:     /* params for create */
      80:
      81:     initp();    /* init globals for setp */
      82:     setp("0");  /* initial relstat field */
      83:     relnum = rnum_alloc();
      84:     setp(rnum_convert(relnum));
      85:     setp("count");      /* domain 1 - count field per BY value */
      86:     setp("i4");     /* format of count field */
      87:
      88:     i = bydoms = lnode(byhead->left, lnodv, 0);
      89:     lnodv[i] = 0;
      90:     alnp = &lnodv[++i];
      91:     i = lnode(byhead->right, lnodv, i);
      92:     lnodv[i] = 0;
      93:
      94:     domnam(lnodv, "by");    /* BY list domains */
      95:     domnam(alnp, "ag"); /* aggregate value domains */
      96:
      97:     call_dbu(mdCREATE, FALSE);
      98:
      99:     Rangev[agvar].relnum = relnum;
     100: #	ifdef xDTR1
     101:     if (tTf(7, 7))
     102:         printf("agvar=%d,rel=%s\n", agvar, rnum_convert(relnum));
     103: #	endif
     104:
     105:     bymap = varfind(byhead->left, NULL);
     106:
     107:     /*
     108: 	** Find all variables in the tree in which you are nested.
     109: 	** Do not look at any other aggregates in the tree. Just in
     110: 	** case the root is an aggregate, explicitly look at its
     111: 	** two descendents.
     112: 	*/
     113:     srcmap = varfind(root->left, ag) | varfind(root->right, ag);
     114: #	ifdef xDTR1
     115:     if (tTf(7, 8))
     116:         printf("bymap=%o,srcmap=%o\n", bymap, srcmap);
     117: #	endif
     118:
     119:     if (bymap & srcmap)
     120:         modqual(root, lnodv, srcmap, agvar);
     121:
     122:     /* if aggregate is unique or there is a qualification
     123: 	** or aggregate is multi-var, then special processing is done */
     124:
     125:     temp_relnum = NORESULT;
     126:     filled = FALSE;
     127:     primeag = prime(byhead->right);
     128:     if (ag->right->sym.type != QLEND || ((struct qt_root *)ag)->tvarc > 1 || primeag)
     129:     {
     130:         /* init a buffer for new tree components */
     131:         initbuf(agbuf, AGBUFSIZ, AGBUFFULL, &derror);
     132:
     133:         /* make a root for a new tree */
     134:         q = makroot(agbuf);
     135:
     136:         /*
     137: 		** Create a RESDOM for each by-domain in the original
     138: 		** aggregate. Rather than using the existing by-domain
     139: 		** function, a copy is used instead. This is necessary
     140: 		** since that subtree might be needed later (if modqual())
     141: 		** decided to use it. Decomp does not restore the trees
     142: 		** it uses and thus the by-domains might be altered.
     143: 		*/
     144:         for (i = 0; r = lnodv[i]; i++)
     145:         {
     146:             resdom = makresdom(agbuf, r);
     147:             ((struct qt_res *)resdom)->resno = i + 2;
     148:             resdom->right = copytree(r->right, agbuf);
     149:             resdom->left = q->left;
     150:             q->left = resdom;
     151:         }
     152:         mapvar(q, 0);   /* make maps on root */
     153: #		ifdef xDTR1
     154:         if (tTf(7, 2))
     155:             printree(q, "by-domains");
     156: #		endif
     157:
     158:         /* if agg is qualified, project by-domains into result */
     159:         if (ag->right->sym.type != QLEND)
     160:         {
     161:             filled = TRUE;
     162:             i = Sourcevar;  /* save value */
     163:             decomp(q, mdRETR, relnum);
     164:             Sourcevar = i;  /* restore value */
     165:         }
     166:
     167:         /* if agg is prime or multivar, compute into temp rel */
     168:         if (((struct qt_root *)ag)->tvarc > 1 || primeag)
     169:         {
     170:             q->right = ag->right;   /* give q the qualification */
     171:             ag->right = Qle;    /* remove qualification from ag */
     172:
     173:             /* put aop resdoms on tree */
     174:             for (i = bydoms + 1; r = lnodv[i]; i++)
     175:             {
     176:                 resdom = makresdom(agbuf, r);
     177:                 resdom->right = r->right;
     178:                 resdom->left = q->left;
     179:                 q->left = resdom;
     180:
     181:                 /* make aop refer to temp relation */
     182:                 r->right = makavar(resdom, FREEVAR, i);
     183:             }
     184:
     185:             /* assign result domain numbers */
     186:             for (resdom = q->left; resdom->sym.type != TREE; resdom = resdom->left)
     187:                 ((struct qt_res *)resdom)->resno = --i;
     188:
     189:             /*
     190: 			** change by-list in agg to reference new source rel.
     191: 			** Save the old bylist to be restored at the end of
     192: 			** this aggregate.
     193: 			*/
     194:             for (i = 0; resdom = lnodv[i]; i++)
     195:             {
     196:                 save_node[i] = resdom->right;
     197:                 resdom->right = makavar(resdom, FREEVAR, i + 1);
     198:             }
     199:
     200:             mapvar(q, 0);
     201: #			ifdef xDTR1
     202:             if (tTf(7, 3))
     203:                 printree(q, "new ag src");
     204: #			endif
     205:
     206:             /* create temp relation */
     207:             temp_relnum = mak_t_rel(q, "a", -1);
     208:             decomp(q, mdRETR, temp_relnum);
     209:             Rangev[FREEVAR].relnum = temp_relnum;
     210:             Sourcevar = FREEVAR;
     211:             if (primeag)
     212:                 removedups(FREEVAR);
     213: #			ifdef xDTR1
     214:             if (tTf(7, 4))
     215:                 printree(ag, "new agg");
     216: #			endif
     217:         }
     218:     }
     219:
     220:     /* set up parameters for modify to hash */
     221:     initp();
     222:     setp(rnum_convert(relnum));
     223:     setp("hash");       /* modify the empty rel to hash */
     224:     setp("num");        /* code to indicate numeric domain names */
     225:     nums[1] = '\0';
     226:     for (i = 0; i < bydoms; i++)
     227:     {
     228:         nums[0] = i + 2;
     229:         setp(nums);
     230:     }
     231:     setp("");
     232:
     233:     /* set up fill factor information */
     234:     setp("minpages");
     235:     if (filled)
     236:     {
     237:         setp("1");
     238:         setp("fillfactor");
     239:         setp("100");
     240:     }
     241:     else
     242:     {
     243:         setp("10");
     244:     }
     245:     specclose(relnum);
     246:     call_dbu(mdMODIFY, FALSE);
     247:
     248:
     249:     Newq = 1;
     250:     Newr = TRUE;
     251:     call_ovqp(ag, mdRETR, relnum);
     252:
     253:     Newq = 0;
     254:     /* if temp relation was used, destroy it */
     255:     if (temp_relnum != NORESULT)
     256:     {
     257:         for (i = 0; resdom = lnodv[i]; i++)
     258:             resdom->right = save_node[i];
     259:         dstr_rel(temp_relnum);
     260:     }
     261: }
     262:
     263:
     264:
     265:
     266: modqual(root, lnodv, srcmap, agvar)
     267: struct querytree    *root;
     268: struct querytree    *lnodv[];
     269: int         srcmap;
     270: int         agvar;
     271: {
     272:     register struct querytree   *and_eq, *afcn;
     273:     register int            i;
     274:     struct querytree        *copytree(), *need(), *makavar();
     275:
     276: #	ifdef xDTR1
     277:     if (tTf(14, 5))
     278:         printf("modqual %o\n", srcmap);
     279: #	endif
     280:
     281:     for (i = 0; afcn = lnodv[i]; i++)
     282:     {
     283:         /*  `AND' node  */
     284:         and_eq = need(Qbuf, 12);
     285:         and_eq->sym.type = AND;
     286:         and_eq->sym.len = 6;
     287:         ((struct qt_root *)and_eq)->tvarc = ((struct qt_root *)and_eq)->lvarc = ((struct qt_root *)and_eq)->lvarm = ((struct qt_root *)and_eq)->rvarm = 0;
     288:         and_eq->right = root->right;
     289:         root->right = and_eq;
     290:
     291:         /* `EQ' node  */
     292:         and_eq->left = need(Qbuf, 8);
     293:         and_eq = and_eq->left;
     294:         and_eq->sym.type = BOP;
     295:         and_eq->sym.len = 2;
     296:         ((struct qt_op *)and_eq)->opno = opEQ;
     297:
     298:         /* bydomain opEQ var */
     299:         and_eq->right = copytree(afcn->right, Qbuf);    /* a-fcn (in Source) specifying BY domain */
     300:         and_eq->left = makavar(afcn, agvar, i+2);   /* VAR ref BY domain */
     301:     }
     302: }

#### Defined functions

byeval defined in line 51; used 1 times

- in /usr/ingres/source/decomp/aggregate.c line 212

modqual defined in line 266; used 1 times

- in line 120

Last modified: 1995-04-14 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1280 |