158 lines
3.5 KiB
C
158 lines
3.5 KiB
C
# include "gen.h"
|
|
# include "../h/dbs.h"
|
|
# include "../h/tree.h"
|
|
# include "../h/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)
|
|
QTREE *node;
|
|
QTREE *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 QTREE *v;
|
|
register QTREE *sq;
|
|
register QTREE *nod;
|
|
register int i;
|
|
extern QTREE *ckvar();
|
|
extern char *need();
|
|
|
|
if (!(nod = node))
|
|
return;
|
|
|
|
if (nod->sym.type == VAR)
|
|
{
|
|
nod = ckvar(nod);
|
|
i = ((VAR_NODE *) nod)->varno;
|
|
if (sq = sqlist[i])
|
|
{
|
|
/* This var has a subquery on it */
|
|
|
|
/* allocate a new VAR node */
|
|
if (buf)
|
|
{
|
|
((VAR_NODE *) nod)->valptr = need(buf, QT_HDR_SIZ + VAR_SIZ);
|
|
v = (QTREE *) ((VAR_NODE *) nod)->valptr;
|
|
v->left = (QTREE *) 0;
|
|
v->right = (QTREE *) 0;
|
|
AAbmove(&nod->sym, &v->sym, SYM_HDR_SIZ + VAR_SIZ);
|
|
((VAR_NODE *) nod)->varno = -1;
|
|
((VAR_NODE *) v)->valptr = (char *) 0;
|
|
}
|
|
else
|
|
v = nod;
|
|
|
|
/* search for the new attno */
|
|
for (sq = sq->left; sq->sym.type != TREE; sq = sq->left)
|
|
{
|
|
if (ctou(((VAR_NODE *) ckvar(sq->right))->attno) == ctou(((VAR_NODE *) nod)->attno))
|
|
{
|
|
|
|
((VAR_NODE *) v)->attno = ((RES_NODE *) sq)->resno;
|
|
# ifdef xDTR1
|
|
if (AAtTfp(12, 3, "TEMPVAR:"))
|
|
writenod(nod);
|
|
# endif
|
|
|
|
return;
|
|
}
|
|
}
|
|
AAsyserr(12027, ctou(((VAR_NODE *) nod)->attno),
|
|
rangename(((VAR_NODE *) nod)->varno));
|
|
}
|
|
return;
|
|
}
|
|
|
|
tempvar(nod->left, sqlist, buf);
|
|
tempvar(nod->right, sqlist, buf);
|
|
}
|
|
|
|
|
|
|
|
|
|
origvar(node, sqlist)
|
|
QTREE *node;
|
|
QTREE *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 QTREE *t;
|
|
register int v;
|
|
|
|
t = node;
|
|
if (!t)
|
|
return;
|
|
if (t->sym.type == VAR && ctoi(((VAR_NODE *) t)->varno) < 0)
|
|
{
|
|
for ( ; ctoi(((VAR_NODE *) ((VAR_NODE *) t)->valptr)->varno) < 0; t = (QTREE *) ((VAR_NODE *) t)->valptr)
|
|
continue;
|
|
v = ((VAR_NODE *) ((VAR_NODE *) t)->valptr)->varno;
|
|
if (sqlist[v])
|
|
{
|
|
((VAR_NODE *) t)->varno = v;
|
|
((VAR_NODE *) t)->valptr = (char *) 0;
|
|
}
|
|
return;
|
|
}
|
|
origvar(t->left, sqlist);
|
|
origvar(t->right, sqlist);
|
|
}
|
|
|
|
|
|
|
|
QTREE *ckvar(node)
|
|
QTREE *node;
|
|
|
|
/*
|
|
** Ckvar -- Return pointer to currently "active" VAR.
|
|
**
|
|
** This routine guarantees that "t" will point to
|
|
** the most current definition of the VAR.
|
|
*/
|
|
|
|
{
|
|
register QTREE *t;
|
|
|
|
t = node;
|
|
if (t->sym.type != VAR)
|
|
AAsyserr(12028, t->sym.type);
|
|
while (ctoi(((VAR_NODE *) t)->varno) < 0)
|
|
t = (QTREE *) ((VAR_NODE *) t)->valptr;
|
|
return (t);
|
|
}
|