# include # include # include # include SCCSID(@(#)tempvar.c 8.1 12/31/84) /* ** TEMPVAR ** ** This file contains routines associated with redefining ** attribute numbers. This is needed when one variable sub queries ** or reduction change the positions of attributes in a relation. ** This file includes: ** ** Tempvar -- Change the attribute numbers to new ones. ** ** Origvar -- Restore attribute numbers back to their previous values. ** ** Ckvar -- Return the currently active VAR node ** ** Trace Flags: ** 51 */ /* ** Tempvar -- Replace a VAR attribute number with its new number. ** ** Tempvar is given a list of subqueries which will potentially ** alter the attribute numbers of VARs they reference. An attno ** is changed by making the current VAR point to a new VAR node ** which has the updated attno. ** ** The new attno is determined from the target list of the subquery ** for that VAR. The RESDOM number is the new attno and the VAR it ** points to is the old attno. For example: ** RESDOM/2 -> right = VAR 1/3 ** The right subtree of result domain 2 is domain 3 of variable 1. ** Thus domain 3 should be renumbered to be domain 2. */ tempvar(node, sqlist, buf) register QTREE *node; QTREE *sqlist[]; char *buf; { register QTREE *v, *sq; QTREE *ckvar(); extern char *need(), *rangename(); if (node == NULL) return; if (node->sym.type == VAR ) { node = ckvar(node); if (sq = sqlist[node->sym.value.sym_var.varno]) { /* This var has a subquery on it */ /* allocate a new VAR node */ if (buf) { node->sym.value.sym_var.valptr = (ANYTYPE *) need(buf, QT_HDR_SIZ + sizeof(struct varnode)); v = (QTREE *) node->sym.value.sym_var.valptr; bmove(&node->sym, &v->sym, SYM_HDR_SIZ + sizeof(struct varnode) - sizeof v); v->left = v->right = NULL; v->sym.value.sym_var.valptr = NULL; node->sym.value.sym_var.varno = -1; } else v = node; /* search for the new attno */ for (sq = sq->left; sq->sym.type != TREE; sq = sq->left) { if (ckvar(sq->right)->sym.value.sym_var.attno == node->sym.value.sym_var.attno) { v->sym.value.sym_var.attno = sq->sym.value.sym_resdom.resno; # ifdef xDTR1 if (tTf(51, 3)) { printf("Tempvar:"); nodepr(node); } # endif return; } } syserr("tempvar:dom %d of %s missing", node->sym.value.sym_var.attno, rangename(node->sym.value.sym_var.varno)); } return; } tempvar(node->left, sqlist, buf); tempvar(node->right, sqlist, buf); } /* ** Origvar -- Restore VAR node to previous state. ** ** Origvar undoes the effect of tempvar. All vars listed ** in the sqlist will have their most recent tempvar removed. */ origvar(t, sqlist) register QTREE *t; QTREE *sqlist[]; { register char v; register QTREE *q; if (t == NULL) return; if (t->sym.type == VAR && t->sym.value.sym_var.varno < 0) { while ((v = (q = (QTREE *) (t->sym.value.sym_var.valptr))->sym.value.sym_var.varno) < 0) t = q; if (sqlist[v]) { t->sym.value.sym_var.varno = v; t->sym.value.sym_var.valptr = NULL; } return; } origvar(t->left, sqlist); origvar(t->right, sqlist); } /* ** Ckvar -- Return pointer to currently "active" VAR. ** ** This routine guarantees that "t" will point to ** the most current definition of the VAR. */ QTREE * ckvar(t) register QTREE *t; { if (t->sym.type != VAR) { syserr("ckvar: not a VAR %d", t->sym.type); } # ifdef xDTR1 if (tTf(51, 2)) { printf("ckvar: var %d.%d, type ", t->sym.value.sym_var.varno, t->sym.value.sym_var.attno); xputchar(t->sym.value.sym_var.varfrmt); printf("%3d\n", t->sym.value.sym_var.varfrml); } # endif while (t != NULL && t->sym.value.sym_var.varno < 0) t = (QTREE *) t->sym.value.sym_var.valptr; if (t == NULL) syserr("ckvar null valptr"); return (t); }