|
|
BSD 4.3
# include <ingres.h>
# include <aux.h>
# include <symbol.h>
# include <tree.h>
# include "parser.h"
# include <pv.h>
# include "scanner.h"
# include <sccs.h>
# include <../ovqp/ovqp.h>
# include <errors.h>
SCCSID(@(#)control.c 8.3 2/8/85)
/*
** CONTROL.C -- -- collection of control functions for the parser
**
** These routines administrate the operation of the parser for internal
** sequencing. There are 2 pairs of routines, one pair for each
** quel statement, and one for each go-block, and there is one
** routine to finish retrieve statements.
**
** Defines:
** startgo -- initialize for a go-block
** init_quelst -- initialize for a quel statement
** endquelst -- clean up after a quel statement
** endretrieve -- clean up after a retrieve
** endgo -- clean up after a go-block
**
** Trace Flags:
** control.c ~~ 48, 49
**
** History:
** 6 Jun 80 (jiw) modified and redocumented for 6.3
** 15 Jan 79 (rick) collected and documented more
** ancient history
*/
/*
** INIT_QUELST -- set vbles for default mode before each quel statement
**
** Parameters:
** none
**
** Returns:
** nothing
**
** Trace Flags:
** init_quelst ~~ 48.0
*/
int
init_quelst()
{
extern int neederr();
extern ack_err();
extern int Err_current;
extern int Pars;
extern int Lcase;
extern int Dcase;
extern int Agflag;
extern int Opflag;
extern int Resrng;
extern int Qlflag;
# ifdef xPTR3
tTfp(48, 0, "Init_quelst\n");
# endif
Err_current = 0; /* no error yet */
Pars = 1; /* set scanner into "parser" mode */
Lcase = Dcase; /* set case mapping to default */
Agflag = 0; /* reset aggregate flag */
Opflag = 0; /* reset qmode flag */
Resrng = -1; /* reset result relation slot */
Qlflag = 0; /* reset qualification flag */
initp(); /* initialize parameter vector */
init_qt(); /* assume we have qrytree */
freesym(); /* free symbol table space */
rngreset(); /* reset used bits in range tbl */
return (1);
}
/*
** ENDQUELST -- finish command checking and processing for each quel statement
**
** Parameters:
** op -- the type of query to finish up
**
** Returns:
** nothing
**
** Trace Flags:
** endquelst ~~ 48.4, 48.5
*/
int
endquelst(op)
register int op;
{
register int i;
char ibuf[2]; /* two char buffer for index keys */
extern char *Indexspec;
extern char *Indexname;
extern int Equel;
extern int Agflag;
extern struct lasttok *Lasttok;
extern int yyerrflag;
extern int Err_current;
extern int Ingerr;
extern int Err_fnd;
extern DESC Attdes;
extern DESC Reldesc;
extern int Rsdmno;
extern PARRNG Parrng[];
extern int Resrng;
extern int printtrail();
# ifdef xPTR3
if (tTf(48, 4))
prvect(0, getp());
# endif
/* check next token for GOVAL if the next token has been read */
if (!Err_current && !yyerrflag)
switch (op)
{
case mdSAVE:
case mdCOPY:
case mdCREATE:
# ifdef DISTRIB
case mdDCREATE:
# endif
case mdINDEX:
case mdRANGE:
case mdSTOP:
break;
default:
/* has vble ending and therefore must detect valid end of command */
# ifdef xPTR3
tTfp(48, 5, "before NXTCMDERR\n");
# endif
if (Lastok.tokop != GOVAL)
/* next token not start of command */
par_error(NXTCMDERR, WARN, 0);
break;
}
if (Agflag >= MAXAGG)
/* too many aggregates */
par_error(AGGXTRA, WARN, 0);
/* command ok so far, finish up */
if (!Err_fnd)
{
switch (op)
{
case mdINDEX:
if (tTf(48, 5))
printf("mdINDEX\n");
if (call(op, NULL) < 0)
ack_err();
if (tTf(48, 5))
printf("after call to call\n");
if (Ingerr)
{
if (tTf(48, 5))
printf("Ingerr = %d\n", Ingerr);
endgo();
return (-1);
}
if (Indexspec)
{
initp();
setp(PV_STR, Indexname); /* type */
setp(PV_STR, Indexspec); /* specs */
setp(PV_STR, "num");
for (i = 1; i <= Rsdmno; i++)
{
ibuf[0] = i & I1MASK;
ibuf[1] = '\0';
setp(PV_STR, ibuf);
}
if (call(mdMODIFY, NULL) < 0)
ack_err();
}
break;
case mdRETR:
case mdRET_UNI:
case mdVIEW:
if (Resrng >= 0) /* implies result reln */
{
if (calln(mdCREATE, NULL) < 0)
ack_err();
cleanrel(&Attdes);
if ((i = openr(&Reldesc, OR_RELTID, trim_relname(Parrng[Resrng].vardesc.reldum.relid))) < 0)
syserr("result reln: error in openr '%d'", i);
rngent(R_INTERNAL, "", &Reldesc);
}
else if (!Equel)
/* need to print header */
header(getp());
if (Ingerr)
{
/*
** might be nice to back out the create already done
** by this point so that the user doesn't need to
*/
resetp();
endgo(); /* abort rest of go-block */
return (-1);
}
initp();
/* fall through */
case mdAPP:
case mdDEL:
case mdREPL:
if (op != mdVIEW)
{
call_tree(op, mdQRY, ack_err);
if (op == mdRETR || op == mdRET_UNI)
endretrieve(ack_err);
Patnum = 0;
for (i = 0; i < PATNUM; i++)
if (Pats[i].string)
{
free(Pats[i].string);
Pats[i].string = NULL;
Pats[i].len = 0;
}
break;
}
# ifdef DISTRIB
case mdDISTRIB:
op = mdVIEW;
# endif
/* else, do VIEW */
setp(PV_STR, trim_relname(Parrng[Resrng].vardesc.reldum.relid));
case mdINTEG:
case mdPROT:
call_tree(op, op, ack_err);
break;
case mdCREATE:
# ifdef DISTRIB
case mdDCREATE:
# endif
case mdDESTROY:
case mdMODIFY:
# ifdef V6POINT3COMPAT
/* in this case, if an error in the dbu's will not */
/* cause other processing to halt */
call(op, NULL);
# else
if (call(op, NULL) < 0)
ack_err();
# endif
cleanrel(&Attdes);
break;
case mdCOPY:
case mdHELP:
case mdPRINT:
case mdSAVE:
case mdDISPLAY:
case mdREMQM:
# ifdef V6POINT3COMPAT
call(op, NULL);
# else
if (call(op, NULL) < 0)
ack_err();
# endif
break;
case mdSTOP:
case mdRANGE:
break;
default:
syserr("Endquelst: bad op %d", op);
}
}
/* refresh relstat bits if necessary */
rngfresh(op);
if (init_quelst() < 0)
return (-1);
return (1);
}
/*
** STARTGO -- do whatever needs doing to set up a go-block
**
** Parameters:
** none
**
** Returns:
** nothing
**
** Trace Flags:
** startgo ~~ 48.8
*/
startgo()
{
extern int Err_fnd;
extern int Ing_err;
extern int yyline;
# ifdef xPTR3
tTfp(48, 8, "startgo\n");
# endif
/* initialize for go-block */
get_scan(PRIME); /* prime the scanner input */
Err_fnd = 0; /* no errors have been found yet */
Ingerr = 0;
if (init_quelst() < 0) /* most other init's are done for each statement */
return (-1);
yyline = 1; /* reset line counter */
return (1);
}
/*
** ENDGO -- do whatever needs doing to clean up after a go block
**
** Parameters:
** none
**
** Returns:
** nothing
**
** Trace Flags:
** endgo ~~ 48.12
*/
endgo()
{
# ifdef xPTR3
tTfp(48, 12, "endgo\n");
# endif
if (!Equel && Err_fnd > 1)
error(SUMMARY, iocv(Err_fnd), 0);
get_scan(SYNC);
resetp();
}
/*
** ENDRETRIEVE -- finishes any sort of retrieve
**
** Endretrieve either creates a result relation or prints a trailer
**
** Parameters:
** err_fcn -- function to pass to call
**
** Returns:
** nothing
**
** Trace Flags:
** endretrieve ~~ 48.14
**
** History:
** June '80 -- (jiw) broken off from call_tree
*/
endretrieve(err_fcn)
int (*err_fcn)();
{
extern int Resrng;
extern char *Relspec;
extern PARRNG Parrng[];
extern int Equel;
extern int Hdr;
if (Resrng >= 0)
{
if (Relspec)
{
initp();
setp(PV_STR, trim_relname(Parrng[Resrng].vardesc.reldum.relid));
setp(PV_STR, Relspec);
if (call(mdMODIFY, err_fcn) < 0)
(*err_fcn)();
}
}
else if (!Equel)
{
printeh();
Hdr = FALSE;
}
}
printtrail()
{
extern int Equel;
if (!Equel)
printeh();
return (-1);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.