This commit is contained in:
Oliver Lehmann 1989-05-10 09:50:32 +00:00
parent 9ace144589
commit 8deb75986e
2 changed files with 455 additions and 0 deletions

View File

@ -0,0 +1,315 @@
# include <stdio.h>
# include "gen.h"
# include "../h/dbs.h"
# include "../h/access.h"
# include "../h/aux.h"
# include "../h/catalog.h"
# include "../h/tree.h"
# include "../h/symbol.h"
# include "../h/pipes.h"
# include "../h/bs.h"
# include "decomp.h"
# include "../ovqp/ovqp.h"
int Bopen; /* TRUE if batch file is open */
static int Qvpointer; /* index into available Qvect space in ovqpnod() */
static SYMBOL *Qvect[MAXNODES];
char *Ovqpbuf;
/*
** CALL_OVQP -- Routines which interface to the One Variable Query Processor.
**
** This file contains the routines associated with sending queries
** and receiving results from OVQP. The interface to these routines is
** still messy. Call_ovqp is given the query, mode, and result relation
** as parameters and gets the source relation, and two flags
** (Newq, Newr) as globals. The routines include:
**
** Call_ovqp -- Sends a One-var query to ovqp and flushes the pipe.
**
** Readresult -- Reads the result from a one-var query.
**
** Endovqp -- Informs ovqp that the query is over. Helps to synchronize
** the batch file (if any).
**
*/
/*
** Call_ovqp -- send query down pipe to ovqp and flush pipe.
** Inputs are:
** mode retrieve, append, etc.
** resultnum result relation id
** qtree the query
** Sourcevar (global) if >= 0 then source var
** Newq send NEWQ symbol
** Newr send NEWR symbol
*/
call_ovqp(qtree, mode, resultnum)
QTREE *qtree;
int mode;
int resultnum;
{
register QTREE *tree;
register int i;
char ovqpbuf[LBUFSIZE];
extern int Batchupd;
extern DESC Inddes;
extern int derror();
extern DESC *readopen();
extern char *rangename();
extern DESC *specopen();
# ifdef xOTM
if (AAtTf(76, 1))
timtrace(7, 0);
# endif
tree = qtree;
# ifdef xDTR1
AAtTfp(8, 0, "CALL_OVQP:\n");
if (AAtTf(8, 1))
{
if (Newq)
printree(tree, "new query to ovqp");
else
printf("query same as previous\n");
}
if (AAtTfp(8, 2, "Sourcevar=%d\t", Sourcevar))
{
if (Sourcevar >= 0)
printf("relid=%s\t", rangename(Sourcevar));
if (resultnum >= 0)
printf("Resultname=%s", rnum_convert(resultnum));
if (((ROOT_NODE *) tree)->rootuser)
printf(", userqry");
putchar('\n');
}
# endif
/* assign mode of this query */
Ov_qmode = mode;
if (Newr)
Newr = FALSE;
if (resultnum >= 0)
Result = specopen(resultnum);
else
Result = (DESC *) 0;
if (Sourcevar >= 0)
Source = readopen(Sourcevar);
else
Source = (DESC *) 0;
/* assume this will be direct update */
Userqry = Buflag = FALSE;
if (((ROOT_NODE *) tree)->rootuser)
{
Userqry = TRUE;
/* handle batch file */
if (Result && Ov_qmode != (int) mdRETR)
{
if (Batchupd || ctoi(Result->reldum.relindxd) == SECBASE)
{
if (Bopen == 0)
{
if (ctoi(Result->reldum.relindxd) == SECBASE)
opencatalog(AA_INDEX, 0);
if (i = openbatch(Result, &Inddes, Ov_qmode))
AAsyserr(12009, i);
Bopen = TRUE;
}
Buflag = TRUE;
}
}
}
/* now write the query list itself */
if (Newq)
{
Ovqpbuf = ovqpbuf;
initbuf(Ovqpbuf, LBUFSIZE, LISTFULL, derror);
Qvpointer = 0;
Alist = Bylist = Qlist = Tlist = (SYMBOL **) 0;
Targvc = ((ROOT_NODE *) tree)->lvarc;
Qualvc = bitcnt(((ROOT_NODE *) tree)->rvarm);
Agcount = 0;
if (tree->sym.type == AGHEAD)
{
Alist = &Qvect[0];
if (tree->left->sym.type == BYHEAD)
{
mklist(tree->left->right);
ovqpnod(tree->left); /* BYHEAD node */
Bylist = &Qvect[Qvpointer];
mklist(tree->left->left);
}
else
mklist(tree->left);
}
else
{
if (tree->left->sym.type != TREE)
{
Tlist = &Qvect[0];
mklist(tree->left);
}
}
/* now for the qualification */
ovqpnod(tree); /* ROOT node */
if (tree->right->sym.type != QLEND)
{
Qlist = &Qvect[Qvpointer];
mklist(tree->right);
}
ovqpnod(Qle); /* QLEND node */
}
/* Now call ovqp */
if (strategy())
{
# ifdef xOTM
if (AAtTf(76, 2))
timtrace(9, 0);
# endif
i = scan(); /* scan the relation */
# ifdef xOTM
if (AAtTf(76, 2))
timtrace(10, 0);
# endif
}
else
i = EMPTY;
# ifdef xOTM
if (AAtTf(76, 1))
timtrace(8, 0);
# endif
/* return result of query */
return (i == NONEMPTY); /* TRUE if tuple satisfied */
}
/*
** Endovqp -- Inform ovqp that processing is complete. "Ack" indicates
** whether to wait for an acknowledgement from ovqp. The overall
** mode of the query is sent followed by an EXIT command.
**
** Ovqp decides whether to use batch update or not. If ack == ACK
** then endovqp will read a RETVAL symbol from ovqp and return
** a token which specifies whether to call the update processor or not.
*/
endovqp(ack)
int ack;
{
register int i;
extern int Qry_mode;
if (ack != RUBACK)
{
if (Eql && Qry_mode == (int) mdRETTERM)
eqleol(EXIT); /* signal end of retrieve to EQL process */
}
i = NOUPDATE;
if (ack == ACK)
{
if (Bopen)
{
closebatch();
Bopen = FALSE;
i = UPDATE;
}
}
else
{
if (Bopen)
{
rmbatch();
Bopen = FALSE;
}
}
Retcode.rc_tupcount = Tupsfound;
closecatalog(FALSE);
return (i);
}
/*
** Add node n to ovqp's list
*/
ovqpnod(n)
QTREE *n;
{
register SYMBOL *s;
register QTREE *q;
register int i;
extern QTREE *ckvar();
extern SYMBOL *need();
q = n;
s = &q->sym;
/* VAR nodes must be specially processed */
if (s->type == VAR)
{
/* locate currently active VAR */
q = ckvar(q);
/* Allocate an ovqp var node for the VAR */
s = need(Ovqpbuf, SYM_HDR_SIZ + VAR_SIZ);
s->len = VAR_SIZ;
((SVAR_NODE *) s)->vattno = ctou(((VAR_NODE *) q)->attno);
((SVAR_NODE *) s)->vtype = ((VAR_NODE *) q)->frmt;
((SVAR_NODE *) s)->vlen = ((VAR_NODE *) q)->frml;
/* If VAR has been substituted for, get value */
if (((VAR_NODE *) q)->valptr)
{
/* This is a substituted variable */
if (((VAR_NODE *) q)->varno == Sourcevar)
AAsyserr(12010, ((VAR_NODE *) q)->varno, Sourcevar);
s->type = S_VAR;
((SVAR_NODE *) s)->vpoint = (short *) ((VAR_NODE *) q)->valptr;
}
else
{
/* Var for one variable query */
if (((VAR_NODE *) q)->varno != Sourcevar)
AAsyserr(12011, ((VAR_NODE *) q)->varno, Sourcevar);
s->type = VAR;
if (((VAR_NODE *) q)->attno)
{
i = ctou(((VAR_NODE *) q)->attno);
((SVAR_NODE *) s)->vpoint = (short *) (Intup + Source->reloff[i]);
}
else
((SVAR_NODE *) s)->vpoint = (short *) &Intid;
}
}
if (s->type == AOP)
Agcount++;
/* add symbol to list */
if (Qvpointer > MAXNODES - 1)
ov_err(NODOVFLOW);
Qvect[Qvpointer++] = s;
}

View File

@ -0,0 +1,140 @@
# include <stdio.h>
# include "gen.h"
# include "../h/dbs.h"
# include "../h/access.h"
# include "../h/aux.h"
# include "../h/catalog.h"
# include "../h/tree.h"
# include "../h/symbol.h"
# include "../h/pipes.h"
# include "../h/bs.h"
# include "decomp.h"
# include "../ovqp/ovqp.h"
/*
** Readagg_result -- read results from ovqp from a simple aggregate.
*/
readagg_result(r)
register QTREE **r;
{
register QTREE *aop;
register int i;
# ifndef NO_F4
register int f4;
# endif
register char *val;
extern char *AAbmove();
Tend = Outtup;
while (aop = *r++)
{
i = ctou(aop->sym.len);
if (aop->sym.type == CHAR)
AApad(Tend, i);
# ifndef NO_F4
if (f4 = aop->sym.type == FLOAT && i == sizeof (float))
i = sizeof (double);
# endif
AAbmove(Tend, aop->sym.value, i);
Tend += i;
# ifndef NO_F4
if (f4)
{
val = (char *) aop->sym.value;
((F4TYPE *) val)->f4type = ((F8TYPE *) val)->f8type;
}
# endif
# ifdef xDTR1
if (AAtTf(8, 3))
writenod(aop);
# endif
}
}
ov_err(code)
int code;
{
derror(code);
}
DESC *openindex(name)
char *name;
{
register DESC *d;
register int varno;
extern DESC *readopen();
varno = SECINDVAR;
Rangev[varno].relnum = rnum_assign(name);
d = readopen(varno);
return (d);
}
/*
** Use "AArelclose()" for closing relations. See
** desc_close in openrs.c for details.
*/
extern int AArelclose();
int (*Des_closefunc)() = AArelclose;
init_decomp()
{
# ifdef XTRA
static ACCBUF xtrabufs[XTRABUFS];
AAam_addbuf(xtrabufs, XTRABUFS);
# endif
}
startdecomp()
{
/* called at the start of each user query */
Retcode.rc_tupcount = 0;
initrange();
rnum_init();
startovqp();
}
/*
** Files_avail -- returns how many file descriptors are available
** for decomposition. For decomp combined with ovqp, the fixed
** overhead for files is:
**
** 4 -- pipes
** 1 -- relation relation
** 1 -- attribute relation
** 1 -- standard output
** 1 -- concurrency
** 1 -- AA_INDEX relation
**
** Optional overhead is:
**
** 1 -- for EQL data pipe
** 1 -- for batch file on updates
*/
files_avail(mode)
int mode;
{
register int i;
i = MAXFILES - 9;
if (Eql)
i--;
if (mode != (int) mdRETR)
i--;
return (i);
}