P8000/WEGA/contrib/ingres/dbs/src/parser/rngfcn.c

387 lines
7.5 KiB
C

# include <stdio.h>
# include "gen.h"
# include "../h/dbs.h"
# include "../h/aux.h"
# include "../h/pipes.h"
# include "../h/tree.h"
# include "../h/symbol.h"
# include "parser.h"
struct atstash *Freeatt; /* free list of attrib stash */
static struct rngtab Rngtab[MAXVAR + 1]; /* range table */
static struct atstash Attable[MAXATT]; /* attrib stash space, turned into a list later */
/*
** RNGINIT
** initializes the pointers in the range table
** it should be called prior to starting the parsing
** it also initializes the attrib stash stuff because
** the attrib stash is really part of the range table
*/
rnginit()
{
register int i;
register struct atstash *atptr;
register struct rngtab *rptr;
rptr = Rngtab; /* ptr to head of range table */
for (i = 0; i <= MAXVAR; i++, rptr++) /* ">=" includes the internal entry */
{
rptr->ractiv = 0;
rptr->rmark = 0;
rptr->rposit = i;
AAsmove("", rptr->varname);
AAsmove("", rptr->relnm);
rptr->rstat = 0;
rptr->ratts = 0;
rptr->attlist = (struct atstash *) 0;
}
rngreset();
atptr = Attable;
for (i = 0; i < MAXATT - 1; i++)
{
atptr->atbnext = atptr + 1;
atptr++;
}
atptr->atbnext = (struct atstash *) 0;
Freeatt = Attable;
}
/*
** RNGLOOK
** returns a pointer to the range table entry else 0
** type = LOOKREL lookup relation
** type = LOOKVAR lookup variable
*/
struct rngtab *rnglook(p, type)
char *p;
int type;
{
register struct rngtab *rptr;
register char *param;
register int i;
param = p;
rptr = Rngtab;
switch (type)
{
case LOOKVAR:
case LOOKREL:
break;
default:
AAsyserr(18019, type);
}
for (i = 0; i < MAXVAR; i++, rptr++) /* search external vbles only */
{
if (rptr->ractiv == 1 && AAscompare(param, MAXNAME, (type == LOOKVAR ? rptr->varname : rptr->relnm), MAXNAME) == 0)
{
rptr->rmark = 1;
# ifdef xPTR2
AAtTfp(21, 6, "fnd '%s' at '%d'\n", param, rptr->rentno);
# endif
rngfront(rptr);
return (rptr);
}
}
return ((struct rngtab *) 0);
}
/*
** RNGENT
** Insert variable and relation in range table.
*/
struct rngtab *rngent(type, var, rel, relown, atts, relstat)
int type;
char *var;
char *rel;
char *relown;
int atts;
int relstat;
{
register struct rngtab *rptr;
extern struct rngtab *rngat();
extern struct rngtab *rngatndx();
# ifdef xPTR2
AAtTfp(21, 0, "RNGENT:\ttyp=%d\tvar=%s\trel=%s\n\town=%.2s\tatts=%d\tstat=0%o\n",
type, var, rel, relown, atts, relstat);
# endif
if (type == R_INTERNAL)
rptr = &Rngtab[MAXVAR];
else if (type == R_EXTERNAL)
{
if (!(rptr = rnglook(var, LOOKVAR)))
{
/* not in range table */
rptr = rngatndx(MAXVAR - 1);
}
rngfront(rptr);
}
else
AAsyserr(18020, type);
if (AAscompare(rel, MAXNAME, rptr->relnm, MAXNAME) != 0 ||
!AAbequal(relown, rptr->relnowner, 2))
{
attfree(rptr->attlist);
rptr->attlist = (struct atstash *) 0;
}
AApmove(var, rptr->varname, MAXNAME, '\0');
AApmove(rel, rptr->relnm, MAXNAME, '\0');
AAbmove(relown, rptr->relnowner, 2);
rptr->ractiv = 1;
rptr->ratts = atts;
rptr->rstat = relstat;
return (rptr);
}
/*
** RNGDEL
** removes an entry from the range table
** removes all variables for the relation name
*/
rngdel(rel)
char *rel;
{
register struct rngtab *rptr;
while ((rptr = rnglook(rel, LOOKREL)))
{
AAsmove("", rptr->relnm);
AAsmove("", rptr->varname);
rptr->rmark = 0;
rptr->ractiv = 0;
rngback(rptr);
attfree(rptr->attlist);
rptr->attlist = (struct atstash *) 0;
}
}
/*
** RNGSEND
** Writes range table information needed by DECOMP and OVQP.
*/
rngsend()
{
register struct rngtab *rptr;
register int i;
rptr = Rngtab;
for (i = 0; i < MAXVAR; i++, rptr++)
{
if (rptr->rmark != 0)
{
rngwrite(rptr);
}
}
/* send result relation range entry if not already sent */
if (Resrng && Resrng->rentno == MAXVAR)
{
rngwrite(Resrng);
}
}
/*
** RNGFRONT
** move entry 'r' to head of range table list
*/
rngfront(r)
struct rngtab *r;
{
register struct rngtab *rptr;
register struct rngtab *fptr;
register int i;
fptr = r;
rptr = Rngtab;
for (i = 0; i < MAXVAR; i++, rptr++) /* check all external vbles */
{
if (rptr->rposit < fptr->rposit)
rptr->rposit++;
}
fptr->rposit = 0;
}
/*
** RNGBACK
** move entry 'r' to back of range table list
*/
rngback(r)
struct rngtab *r;
{
register struct rngtab *rptr;
register struct rngtab *bptr;
register int i;
bptr = r;
rptr = Rngtab;
for (i = 0; i < MAXVAR; i++, rptr++) /* check all external vbles */
{
if (rptr->rposit > bptr->rposit)
rptr->rposit--;
}
bptr->rposit = MAXVAR - 1;
}
/*
** RNGRESET
** reset the used marks to '0'
*/
rngreset()
{
register struct rngtab *rptr;
register int i;
rptr = Rngtab;
for (i = MAXVAR - 1; i >= 0; i--, rptr++) /* only do external ones */
{
rptr->rmark = 0;
rptr->rentno = i;
}
Rngtab[MAXVAR].rentno = MAXVAR; /* internal vble is always MAXVAR */
}
/*
** RNGOLD -- find least recently used vble entry
*/
struct rngtab *rngatndx(ndx)
int ndx;
{
register struct rngtab *rptr;
register int i;
rptr = Rngtab;
for (i = 0; i < MAXVAR; i++, rptr++) /* do external vbles */
{
if (rptr->rposit == ndx)
return (rptr);
}
AAsyserr(18021, ndx);
}
/*
** CHECKUPD
** checks to make sure that the user can update the relation 'name1'
** the 'open' parameter is set if 'Reldesc' contains the AArelopen info
** for the relation in question.
*/
checkupd(rptr)
struct rngtab *rptr;
{
if (!Noupdt)
return;
if (rptr->rstat & S_NOUPDT)
/* no updates allowed on this relation */
yyerror(CANTUPDATE, rptr->relnm, (char *) 0);
}
/*
** RNGFRESH -- check the range table relstat information for accuracy
**
** If the command specified could have changed the relstat info
** make the appropriate adjustments to the range table
*/
rngfresh(op)
int op;
{
register struct rngtab *rptr;
register int i;
DESC desc;
/* search the entire table! */
for (i = 0, rptr = Rngtab; i <= MAXVAR; i++, rptr++)
{
if (!rptr->ractiv)
continue;
switch (op)
{
case mdDESTROY:
case mdREMQM:
if ((rptr->rstat & (S_VBASE | S_INTEG | S_PROTUPS | S_INDEX)) != 0)
{
fixordel:
/*
** AArelopen the relation, if it doesn't exist make
** sure that all range table entries are gone
*/
if (!AArelopen(&desc, -1, rptr->relnm))
{
/* relation still there, copy bits anyway */
rptr->rstat = desc.reldum.relstat;
}
else
{
/* relation not there, purge table */
rngdel(rptr->relnm);
}
}
break;
case mdVIEW:
if ((rptr->rstat & S_VBASE) == 0)
{
fixorerr:
/*
** if the relation doesn't exist then it is
** a AAsyserr, otherwise, copy the bits.
*/
if (!AArelopen(&desc, -1, rptr->relnm))
{
/* exists, copy bits */
rptr->rstat = desc.reldum.relstat;
}
else /* not there, AAsyserr */
AAsyserr(18022, rptr->relnm);
}
break;
case mdPROT:
if ((rptr->rstat & S_PROTUPS) == 0)
goto fixorerr;
break;
case mdINTEG:
if ((rptr->rstat & S_INTEG) == 0)
goto fixorerr;
break;
case mdMODIFY:
if ((rptr->rstat & S_INDEX) != 0)
goto fixordel;
break;
default:
return; /* command ok, dont waste time on rest of table */
}
}
}
/*
** RNGPRINT
** prints the contents of the range table
*/
rngprint()
{
register short i;
register short j;
register struct rngtab *rptr;
printf(" relation\tvariable\n");
printf("----------------------------\n");
for (i = 0; i < MAXVAR; i++)
{
rptr = Rngtab;
for (j = 0; j < MAXVAR; j++, rptr++)
{
if (!rptr->ractiv || i != rptr->rposit)
continue;
printf("%12s\t%.12s\n", rptr->relnm, rptr->varname);
}
}
printf("----------------------------\n");
}