Annotation of 42BSD/ingres/source/decomp/byeval.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.