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