ING_DB
This commit is contained in:
parent
723a8a21af
commit
df0b6aa23b
|
|
@ -0,0 +1,239 @@
|
|||
# include <stdio.h>
|
||||
# include "gen.h"
|
||||
# include "../h/dbs.h"
|
||||
# include "../h/aux.h"
|
||||
# include "../h/symbol.h"
|
||||
# include "../h/tree.h"
|
||||
# include "../h/pipes.h"
|
||||
# include "../h/bs.h"
|
||||
# include "ovqp.h"
|
||||
|
||||
extern DESC Reldesc;
|
||||
extern DESC Srcdesc;
|
||||
|
||||
static DESC Indesc;
|
||||
|
||||
/*
|
||||
** Endqry is called at the end of a query, either
|
||||
** in response to getqry receiving an EXIT or as a
|
||||
** result of a user error
|
||||
*/
|
||||
endqry(code)
|
||||
int code;
|
||||
{
|
||||
register int i;
|
||||
|
||||
i = code;
|
||||
|
||||
if (Eql && Retrieve)
|
||||
eqleol(EXIT); /* signal end of query to EQL process */
|
||||
if (i == ACK)
|
||||
{
|
||||
if (Bopen)
|
||||
i = UPDATE;
|
||||
else
|
||||
i = NOUPDATE;
|
||||
|
||||
closeall();
|
||||
retdecomp(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == NOACK)
|
||||
{
|
||||
if (Bopen)
|
||||
{
|
||||
/* remove the batch file */
|
||||
rmbatch();
|
||||
Bopen = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
AAsyserr(17025, code);
|
||||
closeall();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ov_err(code)
|
||||
int code;
|
||||
/*
|
||||
** Usererr is called when a user generated
|
||||
** error is detected. The error number is
|
||||
** sent to DECOMP for processing. The read pipe
|
||||
** is flushed. A non-local goto (reset) returns
|
||||
** to main.c (see setexit()).
|
||||
*/
|
||||
{
|
||||
retdecomp(code); /* send error message to decomp */
|
||||
endqry(NOACK); /* end the query with no ack to decomp */
|
||||
/* and close all relations */
|
||||
rdpipe(P_SYNC, &Inpipe, R_decomp); /* flush the pipe */
|
||||
|
||||
/* copy the error message from decomp to the parser */
|
||||
copyreturn();
|
||||
reset(); /* return to main.c */
|
||||
AAsyserr(17026);
|
||||
}
|
||||
|
||||
|
||||
|
||||
closeall()
|
||||
{
|
||||
closerel(&Srcdesc);
|
||||
closerel(&Reldesc);
|
||||
closecatalog(FALSE);
|
||||
closerel(&Indesc);
|
||||
if (Bopen)
|
||||
{
|
||||
closebatch();
|
||||
Bopen = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
retdecomp(code)
|
||||
int code;
|
||||
/*
|
||||
** writes a RETVAL symbol with value "code".
|
||||
** if code = EMPTY then retdecomp will wait
|
||||
** for an EOP acknowledgement from DECOM before
|
||||
** returning.
|
||||
** If the query was a simple
|
||||
** aggregate, then the aggregate values are also written.
|
||||
*/
|
||||
|
||||
{
|
||||
struct retcode ret;
|
||||
register int i;
|
||||
register int t;
|
||||
register int l;
|
||||
register char *p;
|
||||
struct stacksym ressym;
|
||||
SYMBOL **alist;
|
||||
struct _aop_
|
||||
{
|
||||
char type;
|
||||
char len;
|
||||
int aoper;
|
||||
char atype;
|
||||
char alen;
|
||||
};
|
||||
|
||||
# ifdef xOTR1
|
||||
AAtTfp(33, 1, "RETDECOMP: returning %d\n", code);
|
||||
# endif
|
||||
ret.rc_status = code;
|
||||
ret.rc_tupcount = Tupsfound;
|
||||
wrpipe(P_NORM, &Outpipe, W_decomp, &ret, sizeof (ret));
|
||||
|
||||
if (Alist && !Bylist)
|
||||
{
|
||||
alist = Alist;
|
||||
i = Agcount;
|
||||
Tend = Outtup;
|
||||
|
||||
while (i--)
|
||||
{
|
||||
|
||||
/* find next AOP */
|
||||
while ((t = ((SYMBOL *) *++alist)->type) != AOP)
|
||||
if (t == ROOT)
|
||||
AAsyserr(17027, i);
|
||||
|
||||
t = ((SYMBOL *) &ressym)->type = ((struct _aop_ *) *alist)->atype;
|
||||
l = ((SYMBOL *) &ressym)->len = ((struct _aop_ *) *alist)->alen;
|
||||
l = ctou(l);
|
||||
p = (char *) ((SYMBOL *) &ressym)->value;
|
||||
if (t == CHAR)
|
||||
{
|
||||
((STRINGP *) p)->stringp = Tend;
|
||||
/* make sure it is blank padded */
|
||||
AApad(Tend, l);
|
||||
}
|
||||
else
|
||||
{
|
||||
AAbmove(Tend, p, sizeof (double));
|
||||
if (t == INT && l == sizeof (char))
|
||||
((I1TYPE *) p)->i1type = ((I2TYPE *) p)->i2type;
|
||||
# ifndef NO_F4
|
||||
if (t == FLOAT && l == sizeof (float))
|
||||
((F4TYPE *) p)->f4type = ((F8TYPE *) p)->f8type;
|
||||
# endif
|
||||
}
|
||||
Tend += l;
|
||||
|
||||
# ifdef xOTR1
|
||||
if (AAtTfp(33, 2, "returning aggregate:"))
|
||||
prstack(&ressym);
|
||||
# endif
|
||||
/* write top of stack to decomp */
|
||||
pwritesym(&Outpipe, W_decomp, &ressym);
|
||||
}
|
||||
}
|
||||
|
||||
wrpipe(P_END, &Outpipe, W_decomp);
|
||||
}
|
||||
openrel(desc, relname, mode)
|
||||
DESC *desc;
|
||||
char *relname;
|
||||
int mode;
|
||||
|
||||
/*
|
||||
** openrel checks to see if the descriptor already
|
||||
** holds the relation to be opened. If so it returns.
|
||||
** Otherwise it closes the relation and opens the new one
|
||||
*/
|
||||
|
||||
{
|
||||
register DESC *d;
|
||||
register char *name;
|
||||
register int i;
|
||||
|
||||
d = desc;
|
||||
name = relname;
|
||||
# ifdef xOTR1
|
||||
AAtTfp(33, 4, "OPENREL: open=%d current=%.12s, new=%.12s\n",
|
||||
d->relopn, d->reldum.relid, name);
|
||||
# endif
|
||||
|
||||
if (d->relopn)
|
||||
{
|
||||
if (AAbequal(d->reldum.relid, name, MAXNAME))
|
||||
return;
|
||||
# ifdef xOTR1
|
||||
AAtTfp(33, 5, "OPENREL: closing the old\n");
|
||||
# endif
|
||||
closerel(d);
|
||||
}
|
||||
if (i = AArelopen(d, mode, name))
|
||||
AAsyserr(17028, name, i);
|
||||
}
|
||||
|
||||
|
||||
closerel(desc)
|
||||
DESC *desc;
|
||||
|
||||
/*
|
||||
** close the relation
|
||||
*/
|
||||
|
||||
{
|
||||
register DESC *d;
|
||||
register int i;
|
||||
|
||||
d = desc;
|
||||
# ifdef xOTR1
|
||||
AAtTfp(33, 6, "CLOSEREL: open=%d rel=%.12s\n", d->relopn, d->reldum.relid);
|
||||
# endif
|
||||
if (d->relopn)
|
||||
if (i = AArelclose(d))
|
||||
AAsyserr(17029, d->reldum.relid, i);
|
||||
}
|
||||
DESC *openindex(relid)
|
||||
char *relid;
|
||||
{
|
||||
openrel(&Indesc, relid, 0);
|
||||
return (&Indesc);
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
** This is the QL syntax-error diagnostic routine. Yyerror() is
|
||||
** called whenever the parser is unable to recognize the syntax of a
|
||||
** user query, or the scanner discovers a lexical error.
|
||||
** It returns via reset();
|
||||
*/
|
||||
|
||||
/*
|
||||
** The vector following is used to map error numbers for
|
||||
** incomplete commands. The partial command is identified
|
||||
** by 'Opflag' and is used to index the vector. The contents
|
||||
** of the vector location is the error number. The 0 entries
|
||||
** are for those command which can never be incomplete without
|
||||
** generating a syntax error from the yacc parser. In other
|
||||
** words, they should never happen.
|
||||
*/
|
||||
int Messages[] =
|
||||
{
|
||||
0, /* mdRETTERM */
|
||||
2502, /* mdRETR */
|
||||
2503, /* mdAPP */
|
||||
2504, /* mdREPL */
|
||||
2505, /* mdDEL */
|
||||
0, /* mdCOPY */
|
||||
0, /* mdCREATE */
|
||||
2506, /* mdDESTROY */
|
||||
2507, /* mdHELP */
|
||||
0, /* mdINDEX */
|
||||
2508, /* mdMODIFY */
|
||||
2509, /* mdPRINT */
|
||||
0, /* mdRANGE */
|
||||
0, /* mdSAVE */
|
||||
0, /* mdDEFINE, not user specifiable */
|
||||
2510, /* mdRET_UNI */
|
||||
2511, /* mdVIEW */
|
||||
0, /* mdUPDATE, not user specifiable */
|
||||
0, /* mdRESETREL, not user specifiable */
|
||||
2512, /* mdDISPLAY, help view, help integrity, help permit */
|
||||
0, /* mdNETQRY, reserved for distr DBS */
|
||||
0, /* mdMOVEREL, reserved for distr DBS */
|
||||
2513, /* mdPROT */
|
||||
2514, /* mdINTEG */
|
||||
0, /* mdDCREATE, reserved for distr DBS */
|
||||
0, /* mdWAITQRY, reserved for distr DBS */
|
||||
2515 /* mdREMQM, destroy permit, destroy integrity */
|
||||
};
|
||||
|
||||
yyerror(num, a, b, c)
|
||||
int num;
|
||||
char *a, *b, *c;
|
||||
{
|
||||
char buff[30];
|
||||
register char *buf;
|
||||
extern char *AA_iocv();
|
||||
extern char *AA_locv();
|
||||
|
||||
buf = buff;
|
||||
if (num == SYMERR || num == NXTCMDERR)
|
||||
{
|
||||
/* syntax error */
|
||||
a = buf;
|
||||
b = 0;
|
||||
switch (Lastok.toktyp)
|
||||
{
|
||||
case I2CONST:
|
||||
AA_itoa(((I2TYPE *) Lastok.tok)->i2type, buf);
|
||||
break;
|
||||
|
||||
case I4CONST:
|
||||
AAsmove(AA_locv(((I4TYPE *) Lastok.tok)->i4type), buf);
|
||||
break;
|
||||
|
||||
# ifndef NO_F4
|
||||
case F4CONST:
|
||||
AA_ftoa(((F4TYPE *) Lastok.tok)->f4type, buf, 10, 3, 'n');
|
||||
break;
|
||||
# endif
|
||||
|
||||
case F8CONST:
|
||||
AA_ftoa(((F8TYPE *) Lastok.tok)->f8type, buf, 10, 3, 'n');
|
||||
break;
|
||||
|
||||
case SCONST:
|
||||
AAsmove(Lastok.tok, buf);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
a = "EOF";
|
||||
break;
|
||||
|
||||
default:
|
||||
AAsyserr(18025);
|
||||
}
|
||||
}
|
||||
# ifdef xPTR3
|
||||
AAtTfp(13, 0, "YYERROR: %d\n", num);
|
||||
# endif
|
||||
if (num == NXTCMDERR)
|
||||
{
|
||||
num = Messages[Opflag];
|
||||
b = 0;
|
||||
}
|
||||
error(num, AA_iocv(yyline), a, b, c, (char *) 0);
|
||||
|
||||
/* clean up and sync with monitor */
|
||||
endgo();
|
||||
|
||||
/* execute non-local goto */
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
int neederr(errnum)
|
||||
int errnum;
|
||||
{
|
||||
yyerror(errnum, (char *) 0);
|
||||
}
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
# include <stdio.h>
|
||||
# include "gen.h"
|
||||
# include "../h/dbs.h"
|
||||
# include "../h/aux.h"
|
||||
# include "../h/symbol.h"
|
||||
# include "../h/tree.h"
|
||||
# include "../h/pipes.h"
|
||||
# include "qrymod.h"
|
||||
|
||||
extern struct pipfrmt Outpipe;
|
||||
|
||||
/*
|
||||
** ISSUE -- issue query to rest of system
|
||||
**
|
||||
** This function issues a query to the rest of the DBS.
|
||||
** It can deal with true queries (that is, a tree), or with a
|
||||
** DBU request (which must already be in the pipe).
|
||||
**
|
||||
** The sync from below is read, but not passed up; a pointer
|
||||
** to it (or NULL if none) is returned.
|
||||
**
|
||||
** Parameters:
|
||||
** execid -- the execid to call.
|
||||
** funcid -- the function to call.
|
||||
** tree -- NULL -- just sync from below.
|
||||
** else -- pointer to tree to issue.
|
||||
**
|
||||
** Returns:
|
||||
** The resultcode of the query.
|
||||
**
|
||||
** Side Effects:
|
||||
** A query is executed.
|
||||
*/
|
||||
struct retcode *issue(execid, funcid, tree)
|
||||
char execid;
|
||||
char funcid;
|
||||
QTREE *tree;
|
||||
{
|
||||
register QTREE *t;
|
||||
extern pipetrwr();
|
||||
static struct retcode rc;
|
||||
register int i;
|
||||
register struct retcode *r;
|
||||
|
||||
t = tree;
|
||||
r = &rc;
|
||||
|
||||
# ifdef xQTR2
|
||||
AAtTfp(13, 1, "ISSUE:\n");
|
||||
# endif
|
||||
|
||||
/* write query tree if given */
|
||||
if (t)
|
||||
{
|
||||
wrpipe(P_PRIME, &Outpipe, execid, (char *) 0, funcid);
|
||||
writeqry(t, pipetrwr);
|
||||
wrpipe(P_END, &Outpipe, W_down);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* sync with below */
|
||||
# ifdef xQTR2
|
||||
AAtTfp(13, 2, "ISSUE: response:\n");
|
||||
# endif
|
||||
rdpipe(P_PRIME, &Outpipe);
|
||||
i = rdpipe(P_NORM, &Outpipe, R_down, r, sizeof *r);
|
||||
rdpipe(P_SYNC, &Outpipe, R_down);
|
||||
if (i == 0)
|
||||
return ((struct retcode *) 0);
|
||||
else
|
||||
return (r);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** ISSUEINVERT -- issue a query, but invert the qualification
|
||||
**
|
||||
** This routine is similar to 'issue', except that it issues
|
||||
** a query with the qualification inverted. The inversion
|
||||
** (and subsequent tree normalization) is done on a duplicate
|
||||
** of the tree.
|
||||
**
|
||||
** Parameters:
|
||||
** root -- the root of the tree to issue.
|
||||
**
|
||||
** Returns:
|
||||
** pointer to retcode struct.
|
||||
*/
|
||||
struct retcode *issueinvert(root)
|
||||
QTREE *root;
|
||||
{
|
||||
register QTREE *t;
|
||||
extern QTREE *tree();
|
||||
extern QTREE *treedup();
|
||||
extern QTREE *trimqlend();
|
||||
extern QTREE *norml();
|
||||
register struct retcode *r;
|
||||
extern struct retcode *issue();
|
||||
|
||||
/* make duplicate of tree */
|
||||
t = treedup(root);
|
||||
|
||||
/* prepend NOT node to qualification */
|
||||
t->right = tree((QTREE *) 0, t->right, UOP, OP_SIZ, opNOT);
|
||||
|
||||
/* normalize and issue */
|
||||
t->right = norml(trimqlend(t->right));
|
||||
r = issue(EXEC_DECOMP, 0, t);
|
||||
|
||||
# ifdef xQTR3
|
||||
/* check for valid return */
|
||||
if (!r)
|
||||
AAsyserr(19040);
|
||||
# endif
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** PIPETRWR -- write tree to W_down pipe
|
||||
**
|
||||
** Acts like a 'wrpipe' call, with some arguments included
|
||||
** implicitly.
|
||||
**
|
||||
** Parameters:
|
||||
** val -- the value to write.
|
||||
** len -- the length.
|
||||
**
|
||||
** Returns:
|
||||
** same as wrpipe.
|
||||
*/
|
||||
pipetrwr(val, len)
|
||||
register char *val;
|
||||
register int len;
|
||||
{
|
||||
return (wrpipe(P_NORM, &Outpipe, W_down, val, len));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** NULLSYNC -- send null query to sync EQL program
|
||||
**
|
||||
** On a RETRIEVE to terminal, EQL is left reading the data
|
||||
** pipe by the time we get to this point; on an error (which
|
||||
** will prevent the running of the original query) we must
|
||||
** somehow unhang it. The solution is to send a completely
|
||||
** null query, as so:
|
||||
**
|
||||
** ROOT
|
||||
** / \
|
||||
** TREE QLEND
|
||||
**
|
||||
** This will cause OVQP to send a sync back to the EQL program,
|
||||
** incuring an incredible amount of overhead in the process
|
||||
** (but it was his own fault!).
|
||||
**
|
||||
** Side Effects:
|
||||
** A query is sent.
|
||||
*/
|
||||
struct retcode *nullsync()
|
||||
{
|
||||
register QTREE *t;
|
||||
extern struct retcode *issue();
|
||||
register struct retcode *rc;
|
||||
extern QTREE *tree();
|
||||
|
||||
t = tree(tree((QTREE *) 0, (QTREE *) 0, TREE, 0), tree((QTREE *) 0, (QTREE *) 0, QLEND, 0), ROOT, 0);
|
||||
rc = issue(EXEC_DECOMP, '0', t);
|
||||
return (rc);
|
||||
}
|
||||
Loading…
Reference in New Issue