Annotation of 42BSD/ingres/source/decomp/byeval.c, revision 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.