ING_DB
This commit is contained in:
parent
86f59923cd
commit
801ae802cb
|
|
@ -0,0 +1,133 @@
|
|||
# include "gen.h"
|
||||
# include "../h/dbs.h"
|
||||
# include "../h/tree.h"
|
||||
# include "../h/symbol.h"
|
||||
|
||||
|
||||
struct proctemplate
|
||||
{
|
||||
char *proc_name;
|
||||
int proc_code;
|
||||
char proc_exec;
|
||||
char proc_func;
|
||||
};
|
||||
|
||||
static struct proctemplate Proc_template[] =
|
||||
{
|
||||
"copy", (int) mdCOPY, 0, 0,
|
||||
"create", (int) mdCREATE, 0, 0,
|
||||
"destroy", (int) mdDESTROY, 0, 0,
|
||||
"display", (int) mdDISPLAY, 0, 0,
|
||||
"help", (int) mdHELP, 0, 0,
|
||||
"index", (int) mdINDEX, 0, 0,
|
||||
"modify", (int) mdMODIFY, 0, 0,
|
||||
"print", (int) mdPRINT, 0, 0,
|
||||
"save", (int) mdSAVE, 0, 0,
|
||||
"update", (int) mdUPDATE, 0, 0,
|
||||
"resetrel", (int) mdRESETREL, 0, 0,
|
||||
"remqm", (int) mdREMQM, 0, 0,
|
||||
(char *) 0
|
||||
};
|
||||
|
||||
|
||||
init_proctab(proc, my_id)
|
||||
char *proc;
|
||||
char my_id;
|
||||
|
||||
/*
|
||||
** Initialize from the run time process table
|
||||
**
|
||||
** Each entry in the proctable is seached for in the
|
||||
** runtime process table. If an entry isn't found it
|
||||
** is considered a AAsyserr. If an entry is found the
|
||||
** first one which has an exec_id of "my_id" is taken.
|
||||
** Otherwise, the very first entry given will be used.
|
||||
*/
|
||||
|
||||
{
|
||||
register struct proctemplate *pt;
|
||||
register char *p;
|
||||
register char *name;
|
||||
char *found;
|
||||
int i;
|
||||
|
||||
# ifdef xZTR1
|
||||
AAtTfp(0, 0, "INIT_PTAB:\n");
|
||||
# endif
|
||||
|
||||
for (pt = Proc_template; name = pt->proc_name; pt++)
|
||||
{
|
||||
i = AAlength(name);
|
||||
p = proc;
|
||||
found = (char *) 0;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (AAbequal(p, name, i))
|
||||
{
|
||||
/* found a match. skip past the colon */
|
||||
while (*p++ != ':')
|
||||
continue;
|
||||
|
||||
/* look for an alias in this dbu */
|
||||
found = p;
|
||||
do
|
||||
{
|
||||
if (*p == my_id)
|
||||
{
|
||||
found = p;
|
||||
break; /* found one */
|
||||
}
|
||||
p++;
|
||||
p++;
|
||||
} while (*p++ == ',');
|
||||
|
||||
# ifdef xZTR1
|
||||
AAtTfp(0, 1, "%s: %.2s\n", name, found);
|
||||
# endif
|
||||
|
||||
pt->proc_exec = *found++;
|
||||
pt->proc_func = *found;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* skip to next */
|
||||
while (*p++ != '\n')
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
AAsyserr(11017, name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
get_proctab(code, exec, func)
|
||||
int code;
|
||||
char *exec;
|
||||
char *func;
|
||||
|
||||
/*
|
||||
** Find the correct exec & func for a given code
|
||||
*/
|
||||
|
||||
{
|
||||
register struct proctemplate *p;
|
||||
register int i;
|
||||
|
||||
i = code;
|
||||
for (p = Proc_template; p->proc_name; p++)
|
||||
{
|
||||
if (i == p->proc_code)
|
||||
{
|
||||
/* found entry */
|
||||
*exec = p->proc_exec;
|
||||
*func = p->proc_func;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* entry not there */
|
||||
AAsyserr(11018, i);
|
||||
}
|
||||
|
|
@ -0,0 +1,484 @@
|
|||
# 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 "decomp.h"
|
||||
|
||||
/*
|
||||
** DECISION -- This file contains code related to deciding how to
|
||||
** process the remaining query. The main routine is decision()
|
||||
** and the other routines are called only by decision. The routine
|
||||
** in this file include:
|
||||
**
|
||||
** Decision -- Decides how to process a query.
|
||||
**
|
||||
** Fixtl -- Determines the target list for each component.
|
||||
**
|
||||
** Fixresult -- Determines the result relation for the next query
|
||||
**
|
||||
** Fixrange -- Adjust the range table after a query
|
||||
**
|
||||
** Fixovlap -- Fixes trees in cases where reduction is used
|
||||
**
|
||||
** Rmovlap -- Restores trees in cases where reduction was used.
|
||||
**
|
||||
** Listcomp -- Debugging routine.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
decision(root, qmode, result_num, buf)
|
||||
QTREE *root;
|
||||
int qmode;
|
||||
int result_num;
|
||||
char *buf;
|
||||
|
||||
/*
|
||||
** Decision is given a subquery and decides how to process it.
|
||||
** The choices are:
|
||||
** Disjoint pieces -- The original query had disjoint components.
|
||||
** Do each component separately.
|
||||
** Reduction -- The query is joined by a single variable.
|
||||
** Reduce the query on that joining variable
|
||||
** and do each component separately.
|
||||
** Substitution -- The query is neither disjoint nor reducible.
|
||||
** Process by tuple substitution.
|
||||
**
|
||||
** Notice that decision() is recursive and will call itself on each
|
||||
** subcomponent it decides to do. Decision calls various support
|
||||
** routines in the file "reduction.c".
|
||||
*/
|
||||
|
||||
{
|
||||
register QTREE **qp;
|
||||
register struct complist *clist;
|
||||
register int ovlapvar;
|
||||
register struct complist *cp;
|
||||
int i;
|
||||
int onepiece;
|
||||
int qtrue;
|
||||
int map;
|
||||
int mark;
|
||||
int mark1;
|
||||
int cand_map;
|
||||
register QTREE *tree;
|
||||
register QTREE *newtree;
|
||||
QTREE *qlist[MAXRANGE];
|
||||
int newqmode;
|
||||
int ovlaprelnum;
|
||||
int newr;
|
||||
int locrange[MAXRANGE];
|
||||
extern struct complist *buildlist();
|
||||
extern struct complist *order();
|
||||
extern QTREE *copy_ands();
|
||||
extern QTREE *construct();
|
||||
|
||||
# ifdef xDTR1
|
||||
AAtTfp(15, -1, "DECISION root=0%o,vc=%d,res=%d\n",
|
||||
root, ((ROOT_NODE *) root)->tvarc, result_num);
|
||||
# endif
|
||||
mark = markbuf(buf);
|
||||
if (((ROOT_NODE *) root)->tvarc < 3)
|
||||
{
|
||||
/* setup to do as one single piece */
|
||||
onepiece = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* break the query apart if possible */
|
||||
|
||||
/* build component list */
|
||||
clist = buildlist(root, buf);
|
||||
# ifdef xDTR1
|
||||
if (AAtTf(15, 2))
|
||||
listcomp(clist, "Original Comp");
|
||||
# endif
|
||||
|
||||
/* is query completely connected or disjoint */
|
||||
map = ((ROOT_NODE *) root)->lvarm | ((ROOT_NODE *) root)->rvarm;
|
||||
onepiece = algorithm(clist, map);
|
||||
# ifdef xDTR1
|
||||
AAtTfp(15, 1, "Orig query %s\n", onepiece ? "connected" : "disjoint");
|
||||
# endif
|
||||
/* assume there is no joining variable */
|
||||
ovlapvar = -1;
|
||||
|
||||
if (onepiece)
|
||||
{
|
||||
/*
|
||||
** Try to reduce a single connected piece.
|
||||
** In turn each variable will be logically
|
||||
** removed from the query and a test will
|
||||
** be made to see if the query is still
|
||||
** connected.
|
||||
*/
|
||||
|
||||
cand_map = map;
|
||||
for (i = 1; cand_map; i <<= 1)
|
||||
{
|
||||
if ((cand_map & i) == 0)
|
||||
continue;
|
||||
cand_map &= ~i;
|
||||
freebuf(buf, mark);
|
||||
clist = buildlist(root, buf);
|
||||
if (algorithm(clist, map & ~i) == 0)
|
||||
{
|
||||
ovlapvar = bitpos(i);
|
||||
ovlaprelnum = Rangev[ovlapvar].relnum;
|
||||
onepiece = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
# ifdef xDTR1
|
||||
if (AAtTf(15, 1))
|
||||
{
|
||||
if (ovlapvar < 0)
|
||||
printf("Query not reducible\n");
|
||||
else
|
||||
{
|
||||
printf("Query Reducible on %d\n", ovlapvar);
|
||||
if (AAtTf(15, 3))
|
||||
listcomp(clist, "After reduct");
|
||||
}
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
** If query is more than one piece, build trees
|
||||
** for each piece.
|
||||
*/
|
||||
|
||||
if (!onepiece)
|
||||
{
|
||||
/* order pieces */
|
||||
clist = order(clist, ovlapvar);
|
||||
# ifdef xDTR1
|
||||
if (AAtTf(15, 4))
|
||||
listcomp(clist, "After ordering");
|
||||
# endif
|
||||
cp = clist;
|
||||
qp = qlist;
|
||||
do
|
||||
{
|
||||
*qp++ = construct(root, cp, buf);
|
||||
} while (cp = cp->nextcomp);
|
||||
*qp++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** The query is now either the one original piece or
|
||||
** is in multiple pieces. The information in clist
|
||||
** is no longer needed and now the ordered pieces
|
||||
** will be processed.
|
||||
*/
|
||||
|
||||
if (onepiece)
|
||||
{
|
||||
freebuf(buf, mark);
|
||||
qtrue = decompy(root, qmode, result_num, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the query is in pieces. prepare to process */
|
||||
|
||||
newquery(locrange); /* save state of range table */
|
||||
|
||||
/* determine the target list for each piece of the query */
|
||||
for (qp = qlist; tree = *qp++; )
|
||||
fixtl(tree, qp, ovlapvar, buf);
|
||||
|
||||
/* adjust refs to ovlapvar since domain #'s could have changed */
|
||||
fixovlap(qlist, ovlapvar, buf);
|
||||
|
||||
|
||||
/* now process each component */
|
||||
mark1 = markbuf(buf);
|
||||
for (qp = qlist; tree = *qp++; )
|
||||
{
|
||||
|
||||
# ifdef xDTR1
|
||||
if (AAtTf(15, 6))
|
||||
printree(tree, "Next piece");
|
||||
# endif
|
||||
|
||||
/* determine result relation name */
|
||||
newr = fixresult(root, tree, &newqmode, qmode, result_num);
|
||||
|
||||
/*
|
||||
** Run the query. If reduction is being
|
||||
** performed, the actual tree given to
|
||||
** the decision routine must be a copy
|
||||
** to protect from the recursive call changing
|
||||
** the tree. Any work done at this level,
|
||||
** must be to the original tree
|
||||
*/
|
||||
newtree = tree;
|
||||
if (ovlapvar != -1)
|
||||
{
|
||||
freebuf(buf, mark1);
|
||||
newtree = copy_ands(tree, buf);
|
||||
}
|
||||
qtrue = decision(newtree, newqmode, newr, buf);
|
||||
|
||||
/* fix up the range table */
|
||||
fixrange(root, tree, ovlapvar, ovlaprelnum, newr);
|
||||
|
||||
/* if last piece was false then done */
|
||||
if (!qtrue)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* restore the trees */
|
||||
rmovlap(qlist, ovlapvar);
|
||||
|
||||
/* restore range table back to original */
|
||||
endquery(locrange, TRUE); /* reopen previous range */
|
||||
|
||||
/* return any buffer space used */
|
||||
freebuf(buf, mark);
|
||||
}
|
||||
|
||||
/* all done with query */
|
||||
return (qtrue);
|
||||
}
|
||||
|
||||
|
||||
fixresult(root, tree1, newmode, origmode, resnum)
|
||||
QTREE *root;
|
||||
QTREE *tree1;
|
||||
int *newmode;
|
||||
int origmode;
|
||||
int resnum;
|
||||
|
||||
/*
|
||||
** Fixresult -- Determine result relation for 'tree' query.
|
||||
** If 'tree' is the original target list piece then use the
|
||||
** original relation and mode.
|
||||
** If 'tree' is a reduction piece then create a temporary relation
|
||||
** for it.
|
||||
** If 'tree' is a disjoint piece then there is no target list nor
|
||||
** result relation.
|
||||
**
|
||||
** Return:
|
||||
** result relation number
|
||||
** Side Effects:
|
||||
** *newmode is set to the query mode of the next piece
|
||||
*/
|
||||
|
||||
{
|
||||
register QTREE *tree;
|
||||
register int newresult;
|
||||
|
||||
tree = tree1;
|
||||
*newmode = (int) mdRETR;
|
||||
if (tree->left->sym.type != TREE)
|
||||
{
|
||||
if (tree != root)
|
||||
{
|
||||
/* make new result for reduction step */
|
||||
newresult = mak_t_rel(tree, "r", -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* final piece with original result and mode */
|
||||
newresult = resnum;
|
||||
*newmode = origmode;
|
||||
}
|
||||
}
|
||||
else
|
||||
newresult = NORESULT;
|
||||
return (newresult);
|
||||
}
|
||||
|
||||
|
||||
fixrange(root, tree, ovlapvar, reductnum, newrelnum)
|
||||
QTREE *root;
|
||||
QTREE *tree;
|
||||
int ovlapvar;
|
||||
int reductnum;
|
||||
int newrelnum;
|
||||
|
||||
/*
|
||||
** Update range table after a reduction has been processed.
|
||||
** Only the intermiediate reductions will affect the range
|
||||
** table. The last piece does not.
|
||||
*/
|
||||
|
||||
{
|
||||
register int old;
|
||||
register int i;
|
||||
|
||||
if (root != tree)
|
||||
{
|
||||
/* this is an intermediate piece */
|
||||
i = ovlapvar;
|
||||
|
||||
if (newrelnum >= 0)
|
||||
{
|
||||
old = new_range(i, newrelnum);
|
||||
if (old != reductnum)
|
||||
dstr_rel(old);
|
||||
openr1(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fixovlap(qlist, ovlapvar, buf)
|
||||
QTREE *qlist[];
|
||||
int ovlapvar;
|
||||
char *buf;
|
||||
|
||||
/*
|
||||
** Fixovlap -- Adjust subsequent trees which reference the reduction var
|
||||
**
|
||||
** If the first query in list redefines the reduction variable
|
||||
** (if any) then each subsequent query which references the
|
||||
** reduction variable is adjusted.
|
||||
** Since there may be multiple pieces,
|
||||
** subsequence redefinitions are done without
|
||||
** reallocating buffer space.
|
||||
**
|
||||
*/
|
||||
|
||||
{
|
||||
register QTREE **qp;
|
||||
register QTREE *piece;
|
||||
register QTREE **qp1;
|
||||
register QTREE *next;
|
||||
register int ovmap;
|
||||
|
||||
ovmap = 1 << ovlapvar;
|
||||
|
||||
/* for each piece, if it redefines ovlapvar, then fix up rest */
|
||||
for (qp = qlist; piece = *qp++; )
|
||||
{
|
||||
if (((ROOT_NODE *) piece)->lvarm & ovmap)
|
||||
{
|
||||
for (qp1 = qp; next = *qp1++; )
|
||||
{
|
||||
if ((((ROOT_NODE *) next)->lvarm | ((ROOT_NODE *) next)->rvarm) & ovmap)
|
||||
{
|
||||
tempvar(next, mksqlist(piece, ovlapvar), buf);
|
||||
buf = (char *) 0; /* do not allocate on subsequent refs */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rmovlap(qlist, ovlapvar)
|
||||
QTREE *qlist[];
|
||||
int ovlapvar;
|
||||
|
||||
/*
|
||||
** Rmovlap -- Restore query trees back to their original state.
|
||||
**
|
||||
** Rmovlap undoes the effect of fixovlap(). Any references
|
||||
** to the reduction variable which were adjusted are now
|
||||
** reverted back to the original reference. Note that the
|
||||
** first piece is not effected by fixovlap.
|
||||
*/
|
||||
|
||||
{
|
||||
register QTREE **qp;
|
||||
register QTREE *tree;
|
||||
|
||||
if (1 << ovlapvar)
|
||||
{
|
||||
/* for each piece, remove any tempvars */
|
||||
for (qp = &qlist[1]; tree = *qp++; )
|
||||
origvar(tree, mksqlist(tree, ovlapvar));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fixtl(tree1, qp1, ovlapvar, buf)
|
||||
QTREE *tree1;
|
||||
QTREE *qp1[];
|
||||
int ovlapvar;
|
||||
char *buf;
|
||||
|
||||
/*
|
||||
** Fixtl -- Determine what the target list of each tree should be.
|
||||
**
|
||||
** Fixtl takes each query which references the reduction variable
|
||||
** and looks for references to that variable in subsequent queries.
|
||||
** Dfind will build a target list which includes every domain
|
||||
** which will later be referenced.
|
||||
*/
|
||||
|
||||
{
|
||||
register QTREE *tree;
|
||||
register QTREE **qp;
|
||||
register QTREE *next;
|
||||
register int var;
|
||||
register int map;
|
||||
|
||||
tree = tree1;
|
||||
var = ovlapvar;
|
||||
map = 1 << var;
|
||||
|
||||
/*
|
||||
** if the last tree referenced the overlap variable then
|
||||
** try to fix next tree
|
||||
*/
|
||||
if (((ROOT_NODE *) tree)->rvarm & map)
|
||||
{
|
||||
qp = qp1;
|
||||
while (next = *qp++)
|
||||
{
|
||||
if ((((ROOT_NODE *) next)->lvarm | ((ROOT_NODE *) next)->rvarm) & map)
|
||||
dfind(next, buf, mksqlist(tree, var));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
# ifdef xDTR1
|
||||
listcomp(list, mesg)
|
||||
struct complist *list;
|
||||
char *mesg;
|
||||
|
||||
/*
|
||||
** This is strictly a debuggin routine used for
|
||||
** printing component lists.
|
||||
*/
|
||||
|
||||
{
|
||||
register struct complist *c;
|
||||
register struct complist *cl;
|
||||
register int i;
|
||||
|
||||
if (AAtTfp(15, 14, "%s\n", mesg))
|
||||
{
|
||||
i = -1;
|
||||
for (cl = list; cl; cl = cl->nextcomp)
|
||||
{
|
||||
i++;
|
||||
printf("Component %d:map=0%o\n", i, cl->bitmap);
|
||||
for (c = cl; c; c = c->linkcomp)
|
||||
{
|
||||
printf("0%o, ", c->clause);
|
||||
if (AAtTf(15, 15))
|
||||
{
|
||||
printree(c->clause->left, "");
|
||||
writenod(c->clause);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
# endif
|
||||
Loading…
Reference in New Issue