Annotation of 42BSD/ingres/source/qrymod/trscan.c, revision 1.1

1.1     ! root        1: # include      <ingres.h>
        !             2: # include      <symbol.h>
        !             3: # include      <tree.h>
        !             4: # include      "qrymod.h"
        !             5: # include      <sccs.h>
        !             6: 
        !             7: SCCSID(@(#)trscan.c    7.1     2/5/81)
        !             8: 
        !             9: /*
        !            10: **  AGGCHECK -- check for any aggregate in subtree.
        !            11: **
        !            12: **     This routine checks to insure that the view algorithm can
        !            13: **     proceed safely by checking for aggregates in the view tree.
        !            14: **
        !            15: **     Parameters:
        !            16: **             root -- the root of the tree to check.
        !            17: **
        !            18: **     Returns:
        !            19: **             TRUE -- an aggregate found.
        !            20: **             FALSE -- no aggregates in tree.
        !            21: **
        !            22: **     Side Effects:
        !            23: **             none
        !            24: **
        !            25: **     Trace Flags:
        !            26: **             none.
        !            27: */
        !            28: 
        !            29: aggcheck(root)
        !            30: QTREE  *root;
        !            31: {
        !            32:        register QTREE  *t;
        !            33: 
        !            34:        t = root;
        !            35: 
        !            36:        /* check for no pointer */
        !            37:        while (t != NULL)
        !            38:        {
        !            39:                /* check for this node an AGHEAD */
        !            40:                if (t->sym.type == AGHEAD)
        !            41:                        return (TRUE);
        !            42: 
        !            43:                /* check left subtree recursively */
        !            44:                if (aggcheck(t->left))
        !            45:                        return (TRUE);
        !            46:                
        !            47:                /* check right subtree iteratively */
        !            48:                t = t->right;
        !            49:        }
        !            50: 
        !            51:        return (FALSE);
        !            52: }
        !            53: /*
        !            54: **  VFIND -- find definition for attribute in view tree
        !            55: **
        !            56: **     The view tree is scanned for a specified RESDOM; a pointer
        !            57: **     to the value is returned.
        !            58: **
        !            59: **     Parameters:
        !            60: **             vn -- the variable number to dig out.
        !            61: **             vtree -- a pointer to the target list of the
        !            62: **                     view definition tree.
        !            63: **
        !            64: **     Returns:
        !            65: **             a pointer to the substitution value for the specified
        !            66: **                     'vn'.
        !            67: **             NULL -- if not found.
        !            68: **
        !            69: **     Side Effects:
        !            70: **             none
        !            71: **
        !            72: **     Trace Flags:
        !            73: **             none.
        !            74: */
        !            75: 
        !            76: QTREE *
        !            77: vfind(vn, vtree)
        !            78: int    vn;
        !            79: QTREE  *vtree;
        !            80: {
        !            81:        register int    n;
        !            82:        register QTREE  *v;
        !            83: 
        !            84:        n = vn;
        !            85: 
        !            86:        for (v = vtree; v->sym.type == RESDOM; v = v->left)
        !            87:        {
        !            88:                if (v->sym.value.sym_resdom.resno != n)
        !            89:                        continue;
        !            90: 
        !            91:                /* found the correct replacement */
        !            92:                return (v->right);
        !            93:        }
        !            94: 
        !            95:        if (v->sym.type != TREE)
        !            96:                syserr("vfind: bad RESDOM node %d", v->sym.type);
        !            97:        return (NULL);
        !            98: }
        !            99: /*
        !           100: **  QSCAN -- find specified VAR node in subtree
        !           101: **
        !           102: **     Intended for finding a variable in a qualification, this
        !           103: **     routine just scans a tree recursively looking for a node
        !           104: **     with the specified VAR (varno.attno) node.
        !           105: **
        !           106: **     Parameters:
        !           107: **             root -- the root of the tree to scan.
        !           108: **             vn -- the varno to scan for.
        !           109: **             an -- the attno to scan for.
        !           110: **
        !           111: **     Returns:
        !           112: **             A pointer to the first found VAR node which matches.
        !           113: **                     Scan is prefix.
        !           114: **             NULL if not found at all.
        !           115: **
        !           116: **     Side Effects:
        !           117: **             none
        !           118: **
        !           119: **     Trace Flags:
        !           120: **             none.
        !           121: */
        !           122: 
        !           123: QTREE *
        !           124: qscan(root, vn, an)
        !           125: QTREE  *root;
        !           126: int    vn;
        !           127: int    an;
        !           128: {
        !           129:        register QTREE  *t;
        !           130:        register QTREE  *u;
        !           131: 
        !           132:        t = root;
        !           133: 
        !           134:        /* check for null node */
        !           135:        if (t == NULL)
        !           136:                return (t);
        !           137: 
        !           138:        /* check to see if this node qualifies */
        !           139:        if (t->sym.type == VAR && t->sym.value.sym_var.varno == vn && t->sym.value.sym_var.attno == an)
        !           140:                return (t);
        !           141: 
        !           142:        /* check other nodes */
        !           143:        if ((u = qscan(t->left, vn, an)) != NULL)
        !           144:                return (u);
        !           145:        return (qscan(t->right, vn, an));
        !           146: }
        !           147: /*
        !           148: **  VARSET -- scan tree and set a bit vector of variables
        !           149: **
        !           150: **     The return value is a bit vector representing the set of
        !           151: **     variables used in that subtree.
        !           152: **
        !           153: **     Parameters:
        !           154: **             root -- the root of the tree to check.
        !           155: **
        !           156: **     Returns:
        !           157: **             A bit vector, such that bit zero (on the low order,
        !           158: **                     right-hand end) means var zero.
        !           159: **
        !           160: **     Side Effects:
        !           161: **             none
        !           162: **
        !           163: **     Trace Flags:
        !           164: **             none
        !           165: */
        !           166: 
        !           167: varset(root)
        !           168: QTREE  *root;
        !           169: {
        !           170:        register QTREE  *t;
        !           171:        register int    s;
        !           172: 
        !           173:        t = root;
        !           174: 
        !           175:        if (t == NULL)
        !           176:                return (0);
        !           177: 
        !           178:        /* scan left and right branches */
        !           179:        s = varset(t->left);
        !           180:        s |= varset(t->right);
        !           181: 
        !           182:        /* check out this node */
        !           183:        if (t->sym.type == VAR)
        !           184:        {
        !           185:                /* or in bit corresponding to this varno */
        !           186:                s |= 1 << t->sym.value.sym_var.varno;
        !           187:        }
        !           188: 
        !           189:        return (s);
        !           190: }
        !           191: /*
        !           192: **  SUBSVARS -- scan query tree and replace VAR nodes
        !           193: **
        !           194: **     Scans a tree and finds all VAR nodes for this variable.
        !           195: **     These nodes are looked up in the translation tree and
        !           196: **     replaced by the value found there.  If this is for a
        !           197: **     view, the corresponding node must exist in the translation
        !           198: **     tree, otherwise, a 'zero' node (of a type appropriate based
        !           199: **     on the context) is created and inserted.
        !           200: **
        !           201: **     This routine is one half of the guts of the whole view
        !           202: **     algorithm.
        !           203: **
        !           204: **     VAR nodes are detached and replaced with the replacement
        !           205: **     as defined by the view.  Note that there can never be any
        !           206: **     problems here, since VAR nodes are only used in retrieve
        !           207: **     contexts.
        !           208: **
        !           209: **     It does some extra processing with RESDOM nodes with
        !           210: **     resno = 0.  These nodes specify a 'tid' domain, and are
        !           211: **     included by the parser on REPLACE and DELETE commands
        !           212: **     (for some reason decomp wants them).  Subsvars will allow
        !           213: **     this construct iff the right hand pointer is a VAR node
        !           214: **     with attno = 0.  In this case it just changes the varno
        !           215: **     of the VAR node to be the Qt.qt_resvar number.  This is be-
        !           216: **     cause the Qt.qt_resvar is the variable number of the one and
        !           217: **     only underlying base relation of the view on an update
        !           218: **     (which is presumably the only case where this can come
        !           219: **     up).  Vrscan has already insured that there can only be
        !           220: **     a single base relation in this case.
        !           221: **
        !           222: **     This whole messy thing is only done with view substitutions.
        !           223: **
        !           224: **     Parameters:
        !           225: **             proot -- a pointer to the pointer to the root of the
        !           226: **                     tree to be updated.
        !           227: **             vn -- the varno of the view variable.  This is the
        !           228: **                     varno which will be scanned for.
        !           229: **             transtree -- a pointer to the left branch (target list)
        !           230: **                     of the translation tree.
        !           231: **             vmode -- mdVIEW if called from view processor, mdAPP
        !           232: **                     if called from the integrity processor with
        !           233: **                     an APPEND command, else something else.
        !           234: **                     Mostly, changes the handling of TID type
        !           235: **                     nodes, and forces an error on a view if the
        !           236: **                     VAR node in the scanned tree does not exist
        !           237: **                     in the vtree.
        !           238: **
        !           239: **     Returns:
        !           240: **             none
        !           241: **             (non-local on error).
        !           242: **
        !           243: **     Side Effects:
        !           244: **             The tree pointed to by *proot is updated in possibly
        !           245: **                     very exciting ways.
        !           246: **
        !           247: **     Trace Flags:
        !           248: **             32
        !           249: */
        !           250: 
        !           251: subsvars(proot, vn, transtree, vmode)
        !           252: QTREE  **proot;
        !           253: int    vn;
        !           254: QTREE  *transtree;
        !           255: int    vmode;
        !           256: {
        !           257:        register QTREE  *t;
        !           258:        register QTREE  *v;
        !           259:        register int    i;
        !           260:        extern QTREE    *vfind();
        !           261:        extern QTREE    *makezero();
        !           262:        extern QTREE    *treedup();
        !           263: 
        !           264:        t = *proot;
        !           265:        v = transtree;
        !           266: 
        !           267: #      ifdef xQTR3
        !           268:        if (tTf(32, 0))
        !           269:                printf("subsvars: vn %d root %u transtree %u\n", vn, t, v);
        !           270: #      endif
        !           271: 
        !           272:        if (t == NULL)
        !           273:                return;
        !           274: 
        !           275:        /* check left branch of the tree */
        !           276:        subsvars(&t->left, vn, v, vmode);
        !           277: 
        !           278:        /* check for special 'tid' RESDOM (used by DEL and REPL) */
        !           279:        if (t->sym.type == RESDOM && t->sym.value.sym_resdom.resno == 0)
        !           280:        {
        !           281:                /* test for not Qt.qt_resvar, in which case we ignore leaf */
        !           282:                if (vn != Qt.qt_resvar)
        !           283:                        return;
        !           284: 
        !           285:                /* t->right better be VAR node, attno 0 */
        !           286:                t = t->right;
        !           287:                if (t->sym.type != VAR || t->sym.value.sym_var.attno != 0 || t->sym.value.sym_var.varno != vn)
        !           288:                        syserr("subsvars: RESDOM 0 not VAR 0 %d, %d, %d",
        !           289:                                vn, t->sym.value.sym_var.attno, t->sym.type);
        !           290:                
        !           291:                /* change varno to new Qm.qm_newresvar (set by vrscan) */
        !           292: #              ifdef xQTR3
        !           293:                if (tTf(32, 1))
        !           294:                        printf("RESDOM 0: Qm.qm_newresvar %d\n", Qm.qm_newresvar);
        !           295: #              endif
        !           296:                t->sym.value.sym_var.varno = Qm.qm_newresvar;
        !           297:                return;
        !           298:        }
        !           299: 
        !           300:        /* scan right branch */
        !           301:        subsvars(&t->right, vn, v, vmode);
        !           302: 
        !           303:        /* check for interesting node */
        !           304:        if (t->sym.type != VAR || t->sym.value.sym_var.varno != vn)
        !           305:                return;
        !           306: 
        !           307:        /* test for special 'tid' attribute case */
        !           308:        if (t->sym.value.sym_var.attno == 0 && vmode == mdVIEW)
        !           309:        {
        !           310:                qmerror(3340, Qt.qt_qmode, vn, 0);      /* views do not have tids */
        !           311:        }
        !           312: 
        !           313:        /* find var in vtree */
        !           314:        v = vfind(t->sym.value.sym_var.attno, v);
        !           315:        if (v == NULL)
        !           316:        {
        !           317:                if (vmode == mdVIEW)
        !           318:                        syserr("subsvars: attno %d", t->sym.value.sym_var.attno);
        !           319:                else if (vmode == mdAPP)
        !           320:                        v = makezero();
        !           321:        }
        !           322:        else
        !           323:                v = treedup(v);
        !           324: 
        !           325:        /* replace VAR node */
        !           326:        if (v != NULL)
        !           327:                *proot = v;
        !           328: }

unix.superglobalmegacorp.com

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