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

unix.superglobalmegacorp.com

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