4.1cBSD/usr/src/ucb/ingres/source/parser/tree.c

Compare this file to the similar file:
Show the results in this format:

# 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);
}