|
|
Initial revision
# include <ingres.h>
# include <aux.h>
# include <tree.h>
# include <pv.h>
# include "parser.h"
# include <symbol.h>
# include <sccs.h>
SCCSID(@(#)tree.c 7.1 2/5/81)
/*
** TREE
** FUNCTION TO ADD NODE TO QUERY TREE
** RETURN VALUE IS POINTER TO NODE JUST CREATED
*/
QTREE *
tree(lptr, rptr, typ, len, valu, attnum)
QTREE *lptr;
QTREE *rptr;
char typ;
int len;
register int valu;
register struct atstash *attnum;
{
register QTREE *tptr;
extern char Trfrmt;
extern char Trfrml;
extern char *need();
extern QTREE *norm();
extern int Err_current;
# ifdef xPTR3
tTfp(55, 0, "tree type(%d), len(%d), value(%d).\n", typ, len, valu);
# endif
if (Err_current)
return (NULL);
/* Following is a hack. Sorry about that John. */
if (typ == AND)
len = sizeof (struct rootnode) - sizeof (short);
tptr = (QTREE *) need(Qbuf, QT_HDR_SIZ + len);
tptr->left = lptr;
tptr->right = rptr;
tptr->sym.type = typ;
tptr->sym.len = len;
switch (typ)
{
case VAR:
tptr->sym.value.sym_var.varno = valu & I1MASK;
tptr->sym.value.sym_var.attno = attnum->atbid;
tptr->sym.value.sym_var.varfrmt = attnum->atbfrmt;
tptr->sym.value.sym_var.varfrml = attnum->atbfrml;
tptr->sym.value.sym_var.valptr = NULL;
break;
case ROOT:
case AGHEAD:
tptr->sym.value.sym_root.rootuser = valu;
break;
case TREE:
case BYHEAD:
case AND:
case OR:
case QLEND:
break;
case UOP:
case BOP:
tptr->sym.value.sym_op.opno = valu;
format(tptr);
break;
case COP:
if ((tptr->sym.value.sym_op.opno = getcop(valu)) == BADCOP)
{
/* bad const operator */
par_error(BADCONSTOP, WARN, valu, 0);
return(NULL);
}
break;
case AOP:
format(tptr->right);
tptr->sym.value.sym_op.agfrmt = Trfrmt;
tptr->sym.value.sym_op.agfrml = Trfrml;
case RESDOM:
tptr->sym.value.sym_resdom.resno = valu;
format(tptr);
tptr->sym.value.sym_resdom.resfrmt = Trfrmt;
tptr->sym.value.sym_resdom.resfrml = Trfrml;
break;
default:
/* INT, FLOAT, CHAR */
bmove(valu, &tptr->sym.value, len & I1MASK);
break;
}
return (tptr);
}
/*
** WINDUP
** assign resno's to resdoms of an agg fcn
*/
windup(ptr)
QTREE *ptr;
{
register int tot;
register int kk;
register QTREE *t;
/* COUNT THE RESDOM'S OF THIS TARGET LIST */
kk = 1;
for (t = ptr; t; t = t->left)
kk++;
tot = 1;
for (t=ptr; t;t = t->left)
t->sym.value.sym_resdom.resno = kk - tot++;
}
/*
** ADDRESDOM - makes a new entry for the target list
**
** Trname must contain the name of the resdom to
** use for the header, create and Rsdmno for append, replace
**
** the parameters are pointers to the subtrees to be
** suspended from the node
*/
QTREE *
addresdom(lptr, rptr)
QTREE *lptr, *rptr;
{
register QTREE *rtval;
register struct atstash *aptr;
char buf[10]; /* buffer type and length in ascii for dbu */
extern int Opflag;
extern int Rsdmno;
extern int Equel;
extern int Resrng;
extern char Trfrmt;
extern char Trfrml;
extern char *Trname;
extern PARRNG Parrng[];
extern QTREE *tree();
extern struct atstash *attlookup();
int temp;
switch (Opflag)
{
case mdRETR:
case mdRET_UNI:
case mdVIEW:
Rsdmno++;
if (Rsdmno >= MAXDOM)
/* too many resdoms */
par_error(RESXTRA, FATAL, 0);
rtval = tree(lptr, rptr, RESDOM, sizeof (struct resdomnode), Rsdmno);
if (!Equel || Resrng)
{
/* buffer info for header or CREATE */
setp(PV_STR, Trname);
buf[0] = Trfrmt & I1MASK;
smove(iocv(Trfrml & I1MASK), &buf[1]);
setp(PV_STR, buf);
}
break;
default:
/*
** for append and replace, the result domain
** number is determined by the location of
** the attribute in the result relation
*/
if (sequal(Trname, "tid"))
/* attrib not found */
par_error(NOATTRIN, WARN, Trname,
trim_relname(Parrng[Resrng].vardesc.reldum.relid), 0);
# ifdef DISTRIB
if (sequal(Trname, "sid"))
/* attrib not found */
par_error(NOATTRIN, WARN, Trname,
trim_relname(Parrng[Resrng].vardesc.reldum.relid), 0);
# endif
aptr = attlookup(Resrng, Trname);
Rsdmno = aptr->atbid;
rtval = tree(lptr, rptr, RESDOM, sizeof (struct resdomnode), Rsdmno);
if (Opflag != mdPROT) /* INTEGRITY not possible here */
attcheck(aptr);
break;
}
return (rtval);
}
/*
** GETCOP
** routine to lookup 'string' in constant operators table
** constant table is declared in tables.y
** structure is defined in ../parser.h
*/
getcop(string)
char *string;
{
register struct constop *cpt;
register char *sptr;
extern struct constop Coptab[];
sptr = string;
for (cpt = Coptab; cpt->copname; cpt++)
if (sequal(sptr, cpt->copname))
return (cpt->copnum);
return (BADCOP);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.