2.11BSD/ingres/source/decomp/exec_sq.c
# include "../pipes.h"
# include "../ingres.h"
# include "../tree.h"
# include "../symbol.h"
# include "decomp.h"
/*
** DECOMP2 -- Routines for executing detached sub-queries appearing
** in sqlist. These routines include:
**
** exec_sq -- execute sub-queries and update range table.
**
** undo_sq -- restore range table and destroy temp rels.
**
** reset_sq - restore range table and reset temp rels.
**
** execsq1 -- call ovqp with subquery.
*/
exec_sq(sqlist, sqrange, disj)
struct querytree *sqlist[];
int sqrange[];
int *disj;
/*
** Exec_sq -- execute the subqueries in sqlist. Associated with
** each sub-query is a relation number stored in sqrange.
** If the sub-query has a non-null target list, the range
** table is updated to reflect the new range of the relation.
**
** If any sub-query is false, all subsequent ones are ignored
** by ovqp and exec_sq returns the var number of the false subquery.
**
** As a side effect, "disj" is incremented for each disjoint sub-query
*/
{
register struct querytree *sq;
register int i, qualfound;
# ifdef xDTR1
if (tTf(11, 0))
printf("EXEC_SQ--\n");
# endif
*disj = 0;
for (i = 0; i < MAXRANGE; i++)
{
if (sq = sqlist[i])
{
# ifdef xDTR1
if (tTf(11, 1))
printf("sq[%d]=%l\n", i, sq);
# endif
qualfound = execsq1(sq, i, sqrange[i]);
# ifdef xDTR1
if (tTf(11, 2))
printf("qualfound=%d\n", qualfound);
# endif
if (!qualfound)
{
return(i);
}
if (sq->left->sym.type != TREE)
{
/*
** Update the range table and open
** the relation's restricted replacement.
*/
new_range(i, sqrange[i]);
openr1(i);
}
else
{
(*disj)++;
}
}
}
return (-1);
}
undo_sq(sqlist, locrang, sqrange, limit, maxlimit, reopen)
char *sqlist[];
int locrang[];
int sqrange[];
int limit;
int maxlimit;
int reopen;
/*
** Undo the effects of one variable detachment on
** the range table. The two parameters "limit" and
** "maxlimit" describe how far down the list of
** subqueries were processed. Maxlimit represents
** the furthest every attained and limit represents
** the last variable processed the last time.
*/
{
register struct querytree *sq;
register int i, lim;
# ifdef xDTR1
if (tTf(11, 0))
printf("UNDO_SQ--\n");
# endif
initp(); /* setup parm vector for destroys */
lim = limit == -1 ? MAXRANGE : limit;
if (maxlimit == -1)
maxlimit = MAXRANGE;
for (i = 0; i < MAXRANGE; i++)
if (sq = (struct querytree *) sqlist[i])
{
if (sq->left->sym.type != TREE)
{
if (i < lim)
{
/* The query was run. Close the temp rel */
closer1(i);
}
/* mark the temporary to be destroyed */
dstr_mark(sqrange[i]);
/* reopen the original relation. If maxlimit
** never reached the variable "i" then the
** original relation was never closed and thus
** doesn't need to be reopened.
*/
rstrang(locrang, i);
if (reopen && i < maxlimit)
openr1(i);
}
}
dstr_flush(0); /* call destroy */
}
execsq1(sq, var, relnum)
struct querytree *sq;
int var;
int relnum;
/*
** Execsq1 -- call ovqp with mdRETR on temp relation
*/
{
register int qualfound;
Sourcevar = var;
Newq = 1;
qualfound = call_ovqp(sq, mdRETR, relnum);
return (qualfound);
}
reset_sq(sqlist, locrang, limit)
struct querytree *sqlist[];
int locrang[];
int limit;
/*
** Reset each relation until limit.
** Reset will remove all tuples from the
** relation but not destroy the relation.
** The descriptor for the relation will be removed
** from the cache.
**
** The original relation is returned to
** the range table.
**
** If limit is -1 then all relations are done.
*/
{
register struct querytree *sq;
register int i, lim;
int old, reset;
lim = limit == -1 ? MAXRANGE : limit;
reset = FALSE;
initp();
for (i = 0; i < lim; i++)
if ((sq = sqlist[i]) && sq->left->sym.type != TREE)
{
old = new_range(i, locrang[i]);
setp(rnum_convert(old));
specclose(old);
reset = TRUE;
}
if (reset)
{
/*
** Guarantee that OVQP will not reuse old
** page of relation being reset
*/
Newr = TRUE;
call_dbu(mdRESETREL, FALSE);
}
}