2.11BSD/ingres/source/decomp/tempvar.c
# include "../ingres.h"
# include "../tree.h"
# include "../symbol.h"
/* DECOMP3 -- 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
*/
tempvar(node, sqlist, buf)
struct querytree *node;
struct querytree *sqlist[];
char *buf;
/*
** 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.
*/
{
register struct querytree *v, *sq, *nod;
int attno;
struct querytree *ckvar(), *need();
if ((nod = node) == NULL)
return;
if (nod->sym.type == VAR )
{
nod = ckvar(nod);
if (sq = sqlist[((struct qt_var *)nod)->varno])
{
/* This var has a subquery on it */
/* allocate a new VAR node */
if (buf)
{
v = (struct querytree *) (((struct qt_var *)nod)->valptr = (char *) need(buf, 12));
v->left = v->right = (struct querytree *) (((struct qt_var *)v)->valptr = (char *) 0);
bmove(&nod->sym, &v->sym, 6);
((struct qt_var *)nod)->varno = -1;
}
else
v = nod;
/* search for the new attno */
for (sq = sq->left; sq->sym.type != TREE; sq = sq->left)
{
if (((struct qt_var *)ckvar(sq->right))->attno == ((struct qt_var *)nod)->attno)
{
((struct qt_var *)v)->attno = ((struct qt_res *)sq)->resno;
# ifdef xDTR1
if (tTf(12, 3))
{
printf("Tempvar:");
writenod(nod);
}
# endif
return;
}
}
syserr("tempvar:dom %d of %s missing", ((struct qt_var *)nod)->attno, rangename(((struct qt_var *)nod)->varno));
}
return;
}
tempvar(nod->left, sqlist, buf);
tempvar(nod->right, sqlist, buf);
}
origvar(node, sqlist)
struct querytree *node;
struct querytree *sqlist[];
/*
** 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.
*/
{
register struct querytree *t;
register int v;
t = node;
if (!t)
return;
if (t->sym.type == VAR && ((struct qt_var *)t)->varno < 0)
{
for (; ((struct qt_var *)((struct qt_var *)t)->valptr)->varno<0; t=(struct querytree *)(((struct qt_var *)t)->valptr));
if (sqlist[v=((struct qt_var *)((struct qt_var *)t)->valptr)->varno])
{
((struct qt_var *)t)->varno = v;
((struct qt_var *)t)->valptr = 0;
}
return;
}
origvar(t->left, sqlist);
origvar(t->right, sqlist);
}
struct querytree *ckvar(node)
struct querytree *node;
/*
** Ckvar -- Return pointer to currently "active" VAR.
**
** This routine guarantees that "t" will point to
** the most current definition of the VAR.
*/
{
register struct querytree *t;
t = node;
if (t->sym.type != VAR)
{
syserr("ckvar: not a VAR %d", t->sym.type);
}
while (((struct qt_var *)t)->varno < 0)
t = (struct querytree *)(((struct qt_var *)t)->valptr);
return(t);
}