Annotation of 42BSD/ingres/source/qrymod/trscan.c, revision 1.1.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.