279 lines
5.4 KiB
C
279 lines
5.4 KiB
C
# include <stdio.h>
|
|
# include "gen.h"
|
|
# include "../h/dbs.h"
|
|
# include "../h/aux.h"
|
|
# include "../h/pipes.h"
|
|
# include "../h/symbol.h"
|
|
# include "../h/tree.h"
|
|
# include "../h/bs.h"
|
|
# include "parser.h"
|
|
# include "../h/scanner.h"
|
|
|
|
static struct retcode *Lastcnt; /* ptr to last tuple count, or 0 */
|
|
static struct retcode Lastcsp; /* space for last tuple count */
|
|
|
|
/*
|
|
** CONTROL.C -- -- collection of control functions for the parser
|
|
**
|
|
** These routines administrate the operation of the parser for internal
|
|
** sequencing. There are 3 pairs of routines, one pair for each
|
|
** QL statement, one for each go-block, and one to handle syncronization
|
|
** with up and down processes.
|
|
**
|
|
** Defines:
|
|
** init_qlst -- initialize for a QL statement
|
|
** endqlst -- clean up after a QL statement
|
|
** syncup -- sync the process above
|
|
** syncdn -- sync the process below
|
|
** startgo -- initialize for a go-block
|
|
** endgo -- clean up after a go-block
|
|
**
|
|
**
|
|
**
|
|
** INIT_QLST -- set vbles for default mode before each QL statement
|
|
*/
|
|
init_qlst()
|
|
{
|
|
extern int neederr();
|
|
|
|
# ifdef xPTR3
|
|
AAtTfp(60, 0, "INIT_QLST:\n");
|
|
# endif
|
|
initp(); /* reset dbu buffer */
|
|
initbuf(Qbuf, TREEMAX, TREEOFLO, neederr); /* reset tree allocation */
|
|
Dbserr = 0; /* clear error condition */
|
|
Patflag = 0; /* reset pattern matching flag */
|
|
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 = 0; /* reset result relation ptr */
|
|
Qlflag = 0; /* reset qualification flag */
|
|
freesym(); /* free symbol table space */
|
|
rngreset(); /* reset used bits in range tbl */
|
|
fflush(stdout);
|
|
}
|
|
|
|
|
|
/*
|
|
** ENDQLST -- finish command checking and processing for each QL statement
|
|
*/
|
|
endqlst(op1)
|
|
int op1;
|
|
{
|
|
register int i;
|
|
register int op;
|
|
char ibuf[2]; /* two char buffer for index keys */
|
|
|
|
# ifdef xPTR3
|
|
AAtTfp(60, 2, "ENDQLST:\n");
|
|
# endif
|
|
op = op1;
|
|
|
|
/* check next token for GOVAL if the next token has been read */
|
|
switch (op)
|
|
{
|
|
case mdSAVE:
|
|
case mdCOPY:
|
|
case mdCREATE:
|
|
|
|
# ifdef DISTRIB
|
|
case mdDCREATE:
|
|
# endif
|
|
|
|
case mdINDEX:
|
|
case mdRANGE:
|
|
break;
|
|
|
|
default:
|
|
/* has vble ending and therefore must detect valid end of command */
|
|
if (Lastok.tokop != GOVAL) /* next token not start of command */
|
|
yyerror(NXTCMDERR, (char *) 0);
|
|
break;
|
|
}
|
|
if (Agflag >= MAXAGG) /* too many aggregates */
|
|
yyerror(AGGXTRA, (char *) 0);
|
|
|
|
/* command ok so far, finish up */
|
|
switch (op)
|
|
{
|
|
case mdRETR:
|
|
case mdRET_UNI:
|
|
case mdVIEW:
|
|
if (Resrng)
|
|
{
|
|
/* need to do create, everything is ready */
|
|
call_p(mdCREATE, EXEC_DBU);
|
|
cleanrel(&Desc);
|
|
}
|
|
else if (!Eql) /* need to print header */
|
|
header();
|
|
if (Dbserr)
|
|
{
|
|
/*
|
|
** might be nice to back out the create already done
|
|
** by this point so that the user doesn't need to
|
|
*/
|
|
endgo(); /* abort rest of go-block */
|
|
reset();
|
|
}
|
|
/* fall through */
|
|
|
|
case mdAPP:
|
|
case mdDEL:
|
|
case mdREPL:
|
|
if (op != (int) mdVIEW)
|
|
{
|
|
call_tree(op, EXEC_DECOMP);
|
|
break;
|
|
}
|
|
|
|
# ifdef DISTRIB
|
|
case mdDISTRIB:
|
|
op = mdVIEW;
|
|
# endif
|
|
/* else, do VIEW */
|
|
initp();
|
|
setp(Resrng->relnm);
|
|
call_tree(mdDEFINE, EXEC_QRYMOD);
|
|
call_p(op, EXEC_QRYMOD);
|
|
break;
|
|
|
|
case mdINTEG:
|
|
case mdPROT:
|
|
call_tree(mdDEFINE, EXEC_QRYMOD);
|
|
call_p(op, EXEC_QRYMOD);
|
|
break;
|
|
|
|
case mdCREATE:
|
|
|
|
# ifdef DISTRIB
|
|
case mdDCREATE:
|
|
# endif
|
|
|
|
case mdDESTROY:
|
|
case mdMODIFY:
|
|
call_p(op, EXEC_DBU);
|
|
cleanrel(&Desc);
|
|
break;
|
|
|
|
case mdCOPY:
|
|
case mdHELP:
|
|
case mdPRINT:
|
|
case mdSAVE:
|
|
case mdDISPLAY:
|
|
case mdREMQM:
|
|
call_p(op, EXEC_DBU);
|
|
break;
|
|
|
|
case mdRANGE:
|
|
break;
|
|
|
|
case mdINDEX:
|
|
call_p(op, EXEC_DBU);
|
|
if (Dbserr)
|
|
{
|
|
endgo(); /* abort rest of go-block */
|
|
reset();
|
|
}
|
|
if (Indexspec)
|
|
{
|
|
setp(Indexname);
|
|
setp(Indexspec);
|
|
setp("num");
|
|
for (i = 1; i <= Rsdmno; i++)
|
|
{
|
|
ibuf[0] = ctou(i);
|
|
ibuf[1] = '\0';
|
|
setp(ibuf);
|
|
}
|
|
call_p(mdMODIFY, EXEC_DBU);
|
|
}
|
|
break;
|
|
}
|
|
|
|
/* refresh relstat bits if necessary */
|
|
rngfresh(op);
|
|
init_qlst();
|
|
}
|
|
|
|
|
|
/*
|
|
** SYNCUP -- sync with process above
|
|
**
|
|
** send tuple count if present
|
|
*/
|
|
syncup()
|
|
{
|
|
struct pipfrmt p;
|
|
register struct pipfrmt *pp;
|
|
|
|
# ifdef xPTR3
|
|
AAtTfp(60, 3, "SYNCUP:\n");
|
|
# endif
|
|
pp = &p;
|
|
wrpipe(P_PRIME, pp, 0, (char *) 0, 0);
|
|
if (Lastcnt)
|
|
{
|
|
wrpipe(P_NORM, pp, W_up, Lastcnt, sizeof(*Lastcnt));
|
|
}
|
|
wrpipe(P_END, pp, W_up);
|
|
}
|
|
|
|
|
|
/*
|
|
** SYNCDN -- wait for sync from below
|
|
**
|
|
** save tuple count if present
|
|
*/
|
|
syncdn()
|
|
{
|
|
struct retcode up;
|
|
struct pipfrmt p;
|
|
register struct pipfrmt *pp;
|
|
|
|
# ifdef xPTR3
|
|
AAtTfp(60, 4, "SYNCDN:\n");
|
|
# endif
|
|
pp = &p;
|
|
rdpipe(P_PRIME, pp);
|
|
if (rdpipe(P_NORM, pp, R_down, &up, sizeof(up)) != 0)
|
|
{
|
|
AAbmove(&up, &Lastcsp, sizeof(up));
|
|
Lastcnt = &Lastcsp;
|
|
# ifdef xPTR3
|
|
AAtTfp(60, 1, "Reading tuple count: %ld\n", Lastcnt->rc_tupcount);
|
|
# endif
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
** STARTGO -- do whatever needs doing to set up a go-block
|
|
*/
|
|
startgo()
|
|
{
|
|
# ifdef xPTR3
|
|
AAtTfp(60, 5, "STARTGO:\n");
|
|
# endif
|
|
/* initialize for go-block */
|
|
getscr(1); /* prime the scanner input */
|
|
Lastcnt = (struct retcode *) 0; /* reset ptr to last tuple count */
|
|
init_qlst(); /* most other init's are done for each statement */
|
|
yyline = 1; /* reset line counter */
|
|
yypflag = 1; /* reset action stmnts */
|
|
}
|
|
|
|
|
|
/*
|
|
** ENDGO -- do whatever needs doing to clean up after a go block
|
|
*/
|
|
endgo()
|
|
{
|
|
# ifdef xPTR3
|
|
AAtTfp(60, 6, "ENDGO:\n");
|
|
# endif
|
|
getscr(2);
|
|
syncup();
|
|
}
|