Annotation of 43BSD/ingres/source/parser/norml.c, revision 1.1

1.1     ! root        1: # include      <ingres.h>
        !             2: # include      <aux.h>
        !             3: # include      <tree.h>
        !             4: # include      <symbol.h>
        !             5: # include      <sccs.h>
        !             6: 
        !             7: SCCSID(@(#)norml.c     8.1     12/31/84)
        !             8: 
        !             9: /*
        !            10: **  NORML.C -- functions for normalizing tree
        !            11: **
        !            12: **     Defines
        !            13: **             norml -- main routine
        !            14: **             norm
        !            15: **             travers
        !            16: **             nnorm
        !            17: **             notpush
        !            18: **             adjust
        !            19: **             treedup
        !            20: **             mvands
        !            21: **
        !            22: **     Trace Flags:
        !            23: **             NORMAL.C ~~ 56, 57
        !            24: */
        !            25: 
        !            26: /*
        !            27: **  NORML -- normalizing routine
        !            28: **
        !            29: **     this routine passes the qualification clause portion of the query
        !            30: **     tree to the routines for depressing nots and for conjunctive 
        !            31: **     normalization.  It also calls a routine to place an and with one
        !            32: **     null branch at the rightmost end of the tree.
        !            33: **
        !            34: **     Parameters:
        !            35: **             ptr -- tree to normalize
        !            36: **
        !            37: **     Returns:
        !            38: **             nothing
        !            39: **
        !            40: **     Trace Flags:
        !            41: **             norml ~~ 56.0
        !            42: */
        !            43: 
        !            44: QTREE *
        !            45: norml(ptr)
        !            46: QTREE  *ptr;
        !            47: {
        !            48:        extern QTREE    *nnorm();
        !            49:        extern QTREE    *travers();
        !            50:        extern QTREE    *tree();
        !            51:        extern char     Qbuf[];
        !            52: 
        !            53: # ifdef        xPTR1
        !            54:        tTfp(56, 0, "norml(%d)\n", ptr);
        !            55: # endif
        !            56: 
        !            57:        if (ptr == NULL)
        !            58:                return (tree(NULL, NULL, QLEND, 0, 0));
        !            59: 
        !            60:        /* push through the 'nots' as far a possible */
        !            61:        ptr = nnorm(ptr);
        !            62: 
        !            63:        /* make tree into conjunctive normal form */
        !            64:        ptr = travers(ptr);
        !            65: 
        !            66:        /* terminate the list on the rightmost branch */
        !            67:        adjust(&ptr);
        !            68: 
        !            69:        /* make 'ands' into a linear list */
        !            70:        mvands(ptr);
        !            71: 
        !            72: # ifdef        xPTR1
        !            73:        tTfp(56, 1, ">>norml(%d)\n", ptr);
        !            74: # endif
        !            75: 
        !            76:        return (ptr);
        !            77: }
        !            78: 
        !            79: 
        !            80: /*
        !            81: ** NORM
        !            82: **     this routine takes a tree which has nots only at the lower ends, and
        !            83: **     places it into conjunctive normal form by repeatedly applying the
        !            84: **     replacement rule: A or (B and C) ==> (A or B) and (A or C)
        !            85: **
        !            86: **     Trace Flags:
        !            87: **             norm ~~ 56.4
        !            88: */
        !            89: 
        !            90: QTREE *
        !            91: norm(p)
        !            92: register QTREE         *p;
        !            93: {
        !            94:        register QTREE          *lptr;
        !            95:        register QTREE          *rptr;
        !            96:        extern QTREE            *treedup();
        !            97:        extern QTREE            *tree();
        !            98: 
        !            99: # ifdef        xPTR1
        !           100:        tTfp(56, 4, "norm(%d)\n", p);
        !           101: # endif
        !           102: 
        !           103:        switch (p->sym.type)
        !           104:        {
        !           105:          case AND:
        !           106:                p->left = norm(p->left);
        !           107:                p->right = norm(p->right);
        !           108:                break;
        !           109: 
        !           110:          case OR:
        !           111:                if (p->right->sym.type == AND)
        !           112:                {
        !           113:                andright:
        !           114:                        /*
        !           115:                        ** combine left subtree with each subtree of the
        !           116:                        ** right subtree
        !           117:                        */
        !           118:                        /*
        !           119:                        ** use copy first so that the copy is guaranteed to be
        !           120:                        ** the same as the original
        !           121:                        */
        !           122:                        lptr = tree(treedup(p->left), p->right->left, OR, sizeof(struct rootnode) - 2, 0);
        !           123:                        rptr = tree(p->left, p->right->right, OR, sizeof(struct rootnode) - 2, 0);
        !           124:                        lptr = norm(lptr);
        !           125:                        rptr = norm(rptr);
        !           126:                        /* change node type to AND from OR */
        !           127:                        p->left = lptr;
        !           128:                        p->right = rptr;
        !           129:                        p->sym.type = AND;      /* length is same */
        !           130:                        break;
        !           131:                }
        !           132:                if (p->left->sym.type == AND)
        !           133:                {
        !           134:                andleft:
        !           135:                        /*
        !           136:                        ** combine right subtree with each subtree of the
        !           137:                        ** left subtree
        !           138:                        */
        !           139:                        /*
        !           140:                        ** again, the copy should be used first
        !           141:                        */
        !           142:                        lptr = tree(p->left->left, treedup(p->right), OR, sizeof(struct rootnode) - 2, 0);
        !           143:                        rptr = tree(p->left->right, p->right, OR, sizeof(struct rootnode) - 2, 0);
        !           144:                        lptr = norm(lptr);
        !           145:                        rptr = norm(rptr);
        !           146:                        /* change node type to AND from OR */
        !           147:                        p->left = lptr;
        !           148:                        p->right = rptr;
        !           149:                        p->sym.type = AND;
        !           150:                        break;
        !           151:                }
        !           152:                /*
        !           153:                ** when TRAVERS is being used to optomize the normalization
        !           154:                ** order there should never be (I think) an OR as a child
        !           155:                ** of the OR in the parent.  Since TRAVERS works bottom up
        !           156:                ** in the tree the second OR level should be gone.
        !           157:                */
        !           158:                if (p->right->sym.type == OR)
        !           159:                {
        !           160:                        /* skip this (p->sym.type) "or" and normalize the right subtree */
        !           161:                        p->right = norm(p->right);
        !           162: 
        !           163:                        /* now re-try the current node */
        !           164:                        if (p->right->sym.type == AND)
        !           165:                                goto andright;
        !           166:                        break;
        !           167:                }
        !           168:                if (p->left->sym.type == OR)
        !           169:                {
        !           170:                        /* skip this "or" and normalize the left subtree */
        !           171:                        p->left = norm(p->left);
        !           172: 
        !           173:                        /* now re-try the current node */
        !           174:                        if (p->left->sym.type == AND)
        !           175:                                goto andleft;
        !           176:                        break;
        !           177:                }
        !           178:                break;
        !           179:        }
        !           180:        return (p);
        !           181: }
        !           182: 
        !           183: /*
        !           184: ** TRAVERS
        !           185: **     traverse the tree so that conversion of ORs of ANDs can
        !           186: **     take place at the innermost clauses first.  IE, normalize
        !           187: **     before replication rather than after replication.
        !           188: **
        !           189: **     This routine need not be used.  The NORM routine will completely
        !           190: **     traverse the tree and normalize it but...    TRAVERS finds
        !           191: **     the lowest subtree to normalize first so that sub-trees can
        !           192: **     be normalized before replication, hence reducing the time required
        !           193: **     to normalize large trees.  It will also make OR-less trees faster
        !           194: **     to normalize (since nothing need be done to it).
        !           195: **
        !           196: **     Trace Flags:
        !           197: **             travers ~~ 56.8
        !           198: */
        !           199: 
        !           200: QTREE *
        !           201: travers(p1)
        !           202: QTREE  *p1;
        !           203: {
        !           204:        register QTREE  *p;
        !           205:        extern QTREE            *norm();
        !           206: 
        !           207: # ifdef        xPTR1
        !           208:        tTfp(56, 8, "travers(%d)\n", p1);
        !           209: # endif
        !           210: 
        !           211:        p = p1;
        !           212:        if (p->right != NULL)
        !           213:                p->right = travers(p->right);
        !           214:        if (p->left != NULL)
        !           215:                p->left = travers(p->left);
        !           216:        if (p->sym.type == OR)
        !           217:                p = norm(p);
        !           218:        return (p);
        !           219: }
        !           220: /*
        !           221: ** NNORM
        !           222: **     this routine depresses nots in the query tree to the lowest possible
        !           223: **     nodes.  It may also affect arithmetic operators in this procedure
        !           224: **
        !           225: **     Trace Flags:
        !           226: **             nnorm ~~ 56.12
        !           227: */
        !           228: QTREE *
        !           229: nnorm(p1)
        !           230: QTREE  *p1;
        !           231: {
        !           232:        extern QTREE            *notpush();
        !           233:        register QTREE  *p;
        !           234: 
        !           235: # ifdef        xPTR1
        !           236:        tTfp(56, 12, "nnorm(%d)\n", p1);
        !           237: # endif
        !           238: 
        !           239:        p = p1;
        !           240:        if (p->sym.type == AGHEAD)
        !           241:        {
        !           242:                /*
        !           243:                ** don't need to continue past an AGHEAD
        !           244:                ** actually, it causes problems if you do
        !           245:                ** because the qualification on the agg
        !           246:                ** has already been normalized and the
        !           247:                ** QLEND needs to stay put
        !           248:                */
        !           249:                return (p);
        !           250:        }
        !           251:        if ((p->sym.type == UOP) && (p->sym.value.sym_op.opno == opNOT))
        !           252:        {
        !           253:                /* skip not node */
        !           254:                p = p->right;
        !           255:                p = notpush(p);
        !           256:        }
        !           257:        else
        !           258:        {
        !           259:                if (p->left != NULL)
        !           260:                        p->left = nnorm(p->left);
        !           261:                if (p->right != NULL)
        !           262:                        p->right = nnorm(p->right);
        !           263:        }
        !           264:        return (p);
        !           265: }
        !           266: 
        !           267: /*
        !           268: ** NOTPUSH
        !           269: **     this routine decides what to do once a not has been found in the
        !           270: **     query tree
        !           271: **
        !           272: **     Trace Flags:
        !           273: **             notpush ~~ 57.0
        !           274: */
        !           275: QTREE *
        !           276: notpush(p1)
        !           277: QTREE  *p1;
        !           278: {
        !           279:        extern QTREE            *nnorm();
        !           280:        register QTREE  *p;
        !           281: 
        !           282: # ifdef        xPTR1
        !           283:        tTfp(57, 0, "notpush(%d)\n", p1);
        !           284: # endif
        !           285: 
        !           286:        p = p1;
        !           287:        switch (p->sym.type)
        !           288:        {
        !           289:          case AND:
        !           290:                p->sym.type = OR;
        !           291:                p->left = notpush(p->left);
        !           292:                p->right = notpush(p->right);
        !           293:                break;
        !           294: 
        !           295:          case OR:
        !           296:                p->sym.type = AND;
        !           297:                p->left = notpush(p->left);
        !           298:                p->right = notpush(p->right);
        !           299:                break;
        !           300: 
        !           301:          case BOP:
        !           302:                switch (p->sym.value.sym_op.opno)
        !           303:                {
        !           304:                  case opEQ:
        !           305:                        p->sym.value.sym_op.opno = opNE;
        !           306:                        break;
        !           307: 
        !           308:                  case opNE:
        !           309:                        p->sym.value.sym_op.opno = opEQ;
        !           310:                        break;
        !           311: 
        !           312:                  case opLT:
        !           313:                        p->sym.value.sym_op.opno = opGE;
        !           314:                        break;
        !           315: 
        !           316:                  case opGE:
        !           317:                        p->sym.value.sym_op.opno = opLT;
        !           318:                        break;
        !           319: 
        !           320:                  case opLE:
        !           321:                        p->sym.value.sym_op.opno = opGT;
        !           322:                        break;
        !           323: 
        !           324:                  case opGT:
        !           325:                        p->sym.value.sym_op.opno = opLE;
        !           326:                        break;
        !           327: 
        !           328:                  default:
        !           329:                        syserr("strange BOP in notpush '%d'", p->sym.value.sym_op.opno);
        !           330:                }
        !           331:                break;
        !           332: 
        !           333:          case UOP:
        !           334:                if (p->sym.value.sym_op.opno == opNOT)
        !           335:                {
        !           336:                        /* skip not node */
        !           337:                        p = p->right;
        !           338:                        p = nnorm(p);
        !           339:                }
        !           340:                else
        !           341:                        syserr("strange UOP in notpush '%d'", p->sym.value.sym_op.opno);
        !           342:                break;
        !           343: 
        !           344:          default:
        !           345:                syserr("unrecognizable node type in notpush '%d'", p->sym.type);
        !           346:        }
        !           347:        return (p);
        !           348: }
        !           349: 
        !           350: /*
        !           351: ** ADJUST
        !           352: **     terminate qual with an AND and a QLEND at the rightmost branch
        !           353: **
        !           354: **     Trace Flags:
        !           355: **             adjust ~~ 57.4
        !           356: */
        !           357: adjust(pp)
        !           358: QTREE  **pp;
        !           359: {
        !           360:        extern QTREE            *tree();
        !           361:        register QTREE  *p;
        !           362: 
        !           363: # ifdef        xPTR1
        !           364:        tTfp(57, 4, "adjust(%d)\n", pp);
        !           365: # endif
        !           366: 
        !           367:        p = *pp;
        !           368:        switch (p->sym.type)
        !           369:        {
        !           370:          case AND: 
        !           371:                adjust(&(p->right));
        !           372:                break;
        !           373: 
        !           374:          case OR:
        !           375:          default:
        !           376:                *pp = tree(p, tree(NULL, NULL, QLEND, 0, NULL), AND, sizeof(struct rootnode) - 2, 0);
        !           377:                break;
        !           378:        }
        !           379: }
        !           380: /*
        !           381: **  TREEDUP -- 
        !           382: **
        !           383: **     Trace Flags:
        !           384: **             norm ~~ 57.8
        !           385: */
        !           386: 
        !           387: 
        !           388: QTREE
        !           389: *treedup(p1)
        !           390: QTREE  *p1;
        !           391: {
        !           392:        register QTREE  *np;
        !           393:        register QTREE  *p;
        !           394:        extern char     Qbuf[];
        !           395:        extern char     *need();
        !           396: 
        !           397: # ifdef        xPTR1
        !           398:        tTfp(57, 8, "treedup(%d)\n", p1);
        !           399: # endif
        !           400: 
        !           401:        if ((p = p1) == NULL)
        !           402:                return (p);
        !           403: 
        !           404:        np = (QTREE *) need(Qbuf, (p->sym.len & I1MASK) + QT_HDR_SIZ);
        !           405: 
        !           406:        bmove(p, np, (p->sym.len & I1MASK) + QT_HDR_SIZ);
        !           407: 
        !           408:        np->left = treedup(p->left);
        !           409:        np->right = treedup(p->right);
        !           410:        return (np);
        !           411: }
        !           412: 
        !           413: /*
        !           414: **     MVANDS -- pushes all AND's in Qual into linear list
        !           415: **
        !           416: **     Trace Flags:
        !           417: **             mvands ~~ 57.12
        !           418: */
        !           419: mvands(andp)
        !           420: QTREE  *andp;
        !           421: {
        !           422:        register QTREE  *ap, *lp, *rp;
        !           423: 
        !           424: # ifdef        xPTR1
        !           425:        tTfp(57, 12, "mvands(%d)\n", andp);
        !           426: # endif
        !           427: 
        !           428:        ap = andp;
        !           429:        if (ap->sym.type == QLEND)
        !           430:                return;
        !           431:        rp = ap->right;
        !           432:        lp = ap->left;
        !           433:        if (lp->sym.type == AND)
        !           434:        {
        !           435:                ap->left = lp->right;
        !           436:                ap->right = lp;
        !           437:                lp->right = rp;
        !           438:                mvands(ap);
        !           439:        }
        !           440:        else
        !           441:                mvands(rp);
        !           442: }

unix.superglobalmegacorp.com

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