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

unix.superglobalmegacorp.com

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