P8000/WEGA/contrib/ingres/dbs/src/dbu/readtree.c

360 lines
7.1 KiB
C

# include <stdio.h>
# include "gen.h"
# include "../h/dbs.h"
# include "../h/catalog.h"
# include "../h/tree.h"
# include "../h/symbol.h"
# include "../h/pipes.h"
# include "../h/bs.h"
/*
** READTREE.C -- query tree input procedures
**
** This file contains routines to read trees from pipes and
** catalogs.
**
** Defines:
** readqry
** readsymbol
** readtree
** relntrrd
** gettree
** declare
** clrrange
*/
extern struct pipfrmt Pipe;
extern struct pipfrmt Outpipe;
/*
** if DBU's other than DISPLAY choose to use readtree.c,
** QBUFFULL should be passed to gettree() as a parameter
*/
# define QBUFFULL 5410
# define STACKFULL 5411
/* this structure should be identical to the one in pr_prot.c */
struct rngtab
{
char relid[MAXNAME];
char rowner[2];
char rused;
};
extern struct rngtab Rangev[];
extern int Resultvar;
/* check out match for these two in decomp.h */
# define QBUFSIZ 2000 /* query buffer */
char Qbuf[QBUFSIZ]; /* tree buffer space */
int Qmode; /* type of query */
extern DESC Treedes;
/*
** READQRY
**
** Reads in query symbols from input pipe into core
** locations and sets up information needed for later
** processing.
**
** Returns ptr to root of querytree
**
** Locbuf is a 'struct srcid' since that is the largest node of
** a QMODE, SOURCEID, or RESULTVAR node.
*/
QTREE *readqry(rdfn)
int (*rdfn)(); /* tree read function */
{
register SYMBOL *s;
struct srcid locbuf;
register QTREE *rtval;
register char *p;
int berror();
extern char *readtree();
extern QTREE *trbuild();
/* initialize for new query block */
initbuf(Qbuf, QBUFSIZ, QBUFFULL, berror);
clrrange();
Resultvar = -1;
Qmode = -1;
s = (SYMBOL *) &locbuf;
/* read symbols from input */
for ( ; ; )
{
readsymbol(s, rdfn);
# ifdef xZTR1
AAtTfp(12, 0, "READQRY: symbol type %d\n", s->type);
# endif
switch (s->type)
{
case QMODE:
if (Qmode != -1)
AAsyserr(11127);
Qmode = s->value[0];
break;
case RESULTVAR:
if (Resultvar != -1)
AAsyserr(11128);
Resultvar = s->value[0];
break;
case SOURCEID:
declare(((SRCID *) s)->srcvar, ((SRCID *) s)->srcname, ((SRCID *) s)->srcown);
break;
case TREE: /* beginning of tree, no more other stuff */
p = readtree(s, rdfn);
if (!(rtval = trbuild(p)))
berror(STACKFULL);
return (rtval);
default:
AAsyserr(11129, s->type);
}
}
}
/*
** READSYMBOL
** reads in one symbol from pipe into symbol struct.
*/
readsymbol(dest, rdfn)
char *dest; /* if non-zero, pts to allocated space */
int (*rdfn)(); /* tree read function */
{
register int len;
register SYMBOL *p;
extern char *need();
/* check if enough space for type and len of sym */
p = (SYMBOL *) (dest? dest: need(Qbuf, SYM_HDR_SIZ));
if ((*rdfn)(p, TYP_LEN_SIZ) < TYP_LEN_SIZ)
goto err3;
len = ctou(p->len);
if (len)
{
if (!dest)
{
/* this will be contiguous with above need call */
need(Qbuf, len);
}
if ((*rdfn)(p->value, len) < len)
{
err3:
AAsyserr(11130);
}
}
}
/*
** READTREE
**
** reads in tree symbols into a buffer up to a root (end) symbol
*/
char *readtree(tresym, rdfn)
SYMBOL *tresym;
int (*rdfn)();
{
register QTREE *nod;
register char *rtval;
extern char *need();
rtval = need(Qbuf, QT_HDR_SIZ);
/* insert type and len of TREE node */
AAbmove(tresym, &(((QTREE *) rtval)->sym), TYP_LEN_SIZ);
for ( ; ; )
{
/* space for left & right pointers */
nod = (QTREE *) need(Qbuf, QT_PTR_SIZ);
readsymbol((char *) 0, rdfn);
if (nod->sym.type == ROOT)
return (rtval);
}
}
/*
** RELNTRRD -- read tree from AA_TREE relation
**
** This looks exactly like the 'pipetrrd' call, except that info
** comes from the AA_TREE catalog instead of from the pipe. It
** must be initialized by calling it with a (char *) 0 pointer and
** the segment name wanted as 'treeid'.
**
** Parameters:
** ptr -- (char *) 0 -- "initialize".
** else -- pointer to read area.
** cnt -- count of number of bytes to read.
** treeid -- if ptr == (char *) 0, this is the tree id,
** otherwise this parameter is not supplied.
**
** Returns:
** count of actual number of bytes read.
**
** Side Effects:
** static variables are adjusted correctly. Note that
** this routine can be used on only one tree
** at one time.
*/
relntrrd(ptr, cnt, treerelid, treeowner, treetype, treeid)
char *ptr;
int cnt;
char *treerelid;
char *treeowner;
char treetype;
int treeid;
{
static struct tree trseg;
static char *trp;
static short seqno;
register char *p;
register int n;
register int i;
struct tree trkey;
struct tup_id tid;
p = ptr;
n = cnt;
if (!p)
{
/* initialize -- make buffer appear empty */
trp = &trseg.treetree[sizeof trseg.treetree];
AAbmove(treerelid, trseg.treerelid, MAXNAME);
AAbmove(treeowner, trseg.treeowner, 2);
trseg.treetype = treetype;
trseg.treeid = treeid;
seqno = 0;
opencatalog(AA_TREE, 0);
return (0);
}
/* fetch characters */
while (n-- > 0)
{
/* check for segment empty */
if (trp >= &trseg.treetree[sizeof trseg.treetree])
{
/* then read new segment */
AAam_clearkeys(&Treedes);
AAam_setkey(&Treedes, &trkey, trseg.treerelid, TREERELID);
AAam_setkey(&Treedes, &trkey, trseg.treeowner, TREEOWNER);
AAam_setkey(&Treedes, &trkey, &trseg.treetype, TREETYPE);
AAam_setkey(&Treedes, &trkey, &trseg.treeid, TREEID);
AAam_setkey(&Treedes, &trkey, &seqno, TREESEQ);
seqno++;
if (i = AAgetequal(&Treedes, &trkey, &trseg, &tid))
AAsyserr(11131, i);
trp = &trseg.treetree[0];
}
/* do actual character fetch */
*p++ = *trp++;
}
return (cnt);
}
/*
** GETTREE -- get tree from AA_TREE catalog
**
** This function, given an internal treeid, fetches and builds
** that tree from the AA_TREE catalog.
**
** Parameters:
** treeid -- internal id of tree to fetch and build.
** init -- passed to 'readqry' to tell whether or not
** to initialize the query buffer.
**
** Returns:
** Pointer to root of tree.
*/
QTREE *gettree(treerelid, treeowner, treetype, treeid)
char *treerelid;
char *treeowner;
char treetype;
int treeid;
{
register QTREE *t;
extern int relntrrd();
/* initialize relntrrd() for this treeid */
relntrrd((char *) 0, 0, treerelid, treeowner, treetype, treeid);
/* read and build query tree */
t = readqry(relntrrd);
return (t);
}
/*
** BERROR -- Buffer overflow routine.
**
** Called on Tree buffer overflow; returns via reset()
** to DBU controller after sending back an error to process 1.
*/
berror(err)
int err;
{
# ifdef xZTR1
AAtTfp(12, 1, "BERROR: %d\n", err);
# endif
error(err, (char *) 0);
reset();
}
/*
** declare -- declare a range table entry
*/
declare(var, name, owner)
int var;
char *name;
char *owner;
{
register struct rngtab *r;
register int v;
v = var;
if (v > MAXNAME)
AAsyserr(11132, v);
# ifdef xZTR1
AAtTfp(12, 2, "DECLARE: var=%d, name=\"%s\", owner=\"%s\"\n",
var, name, owner);
# endif
r = &Rangev[v];
r->rused++;
AAbmove(name, r->relid, sizeof r->relid);
AAbmove(owner, r->rowner, sizeof r->rowner);
}
/*
** CLRRANGE -- clear range table entries
*/
clrrange()
{
register int i;
register struct rngtab *r;
# ifdef xZTR1
AAtTfp(12, 3, "CLRRANGE\n");
# endif
r = Rangev;
for (i = 0; i <= MAXVAR; )
r[i++].rused = 0;
}