/*
**	Reset each relation until limit.
**	Reset will remove all tuples from the
**	relation but not destroy the relation.
**	The descriptor for the relation will be removed
**	from the cache.
**
**	The original relation is returned to
**	the range table.
**
**	If limit is -1 then all relations are done.
*/
void
reset_sq(qtree_t **sqlist, int *locrang, int limit)
{
	register qtree_t	*sq;
	register int	i, lim;
	int		old, reset;

	lim = limit == -1 ? MAX_RANGES : limit;
	reset = FALSE;
	initp();

	for (i = 0; i < lim; i++)
		if ((sq = sqlist[i]) && sq->left->sym.type != TREE) {
			old = new_range(i, locrang[i]);
			setp(PV_STR, rnum_convert(old), 0);
			specclose(old);
			reset = TRUE;
		}

	if (reset) {
		/*
		** Guarantee that OVQP will not reuse old
		** page of relation being reset
		*/
		De.de_newr = TRUE;
		call_dbu(mdRESETREL, FALSE);
	}
	else
		resetp();
}
/*
**	Check the range table to see if any
**	relations changed since the last call
**	to newquery. If so, they were caused
**	by reformat. Restore back the orig relation
**	Reopen it if reopen == TRUE.
*/
void
endquery(int *locrang, int reopen)
{
	register struct rang_tab	*rp;
	register int			*ip, i;
	int				old;
	bool				dstr_flag;

	rp = De.de_rangev;
	ip = locrang;

	dstr_flag = FALSE;
	initp();
	for (i = 0; i < MAX_RANGES; i++) {
		if (rp->relnum != *ip) {
#ifdef xDTR1
			if (tTf(63, -1))
			printf("reformat or reduct changed var %d (%d,%d)\n", i, *ip, rp->relnum);
#endif

			old = new_range(i, *ip);
			dstr_flag |= dstr_mark(old);
			if (reopen)
				openr1(i);
		}

		ip++;
		rp++;
	}

	if (dstr_flag)
		call_dbu(mdDESTROY, FALSE);
	else
		resetp();
}
/*
**  UNDO_SQ
**
**	Undo the effects of one variable detachment on
**	the range table. The two parameters "limit" and
**	"maxlimit" describe how far down the list of
**	subqueries were processed.  Maxlimit represents
**	the furthest every attained and limit represents
**	the last variable processed the last time.
**
**	Trace Flags:
**		36
*/
void
undo_sq(qtree_t **sqlist, int *locrang, int *sqrange, int limit, int maxlimit, int reopen)
{
	register qtree_t	*sq;
	register int	i, lim;
	bool		dstr_flag;

	dstr_flag = 0;
#ifdef xDTR1
	if (tTf(36, 0))
		printf("UNDO_SQ--\n");
#endif

	initp();	/* setup parm vector for destroys */
	lim = limit == -1 ? MAX_RANGES : limit;
	if (maxlimit == -1)
		maxlimit = MAX_RANGES;

	for (i = 0; i < MAX_RANGES; i++)
		if ((sq = sqlist[i]) != 0) {
			if (sq->left->sym.type != TREE) {
				if (i < lim) {
					/* The query was run. Close the temp rel */
					closer1(i);
				}

				/* mark the temporary to be destroyed */
				dstr_mark(sqrange[i]);
				dstr_flag = TRUE;

				/* reopen the original relation. If maxlimit
				** never reached the variable "i" then the
				** original relation was never closed and thus
				** doesn't need to be reopened.
				*/
				rstrang(locrang, i);
				if (reopen && i < maxlimit)
					openr1(i);
			}
		}
	/* Only call destroy if there's something to destroy */
	if (dstr_flag)
		call_dbu(mdDESTROY, FALSE);
	else
		resetp();

}
Exemple #4
0
qryproc()
{
	register QTREE			*root;
	register QTREE			*q;
	register int			i;
	register int			mode;
	register int			result_num;
	register int			retr_uniq;
	extern long			AAccuread;
	extern long			AAccuwrite;
	extern long			AAccusread;
	extern int			derror();
	extern QTREE			*trbuild();
	extern QTREE			*readqry();

#	ifdef xDTM
	if (AAtTf(76, 1))
		timtrace(23, 0);
#	endif
#	ifdef xDTR1
	if (AAtTf(50, 0))
		AAccuread = AAccusread = AAccuwrite = 0;
#	endif

	/* initialize query buffer */
	initbuf(Qbuf, QBUFSIZ, QBUFFULL, derror);

	/* init various variables in decomp for start of this query */
	startdecomp();

	/* Read in query, range table and mode */
	root = readqry();
	mode = Qmode;

	/* Initialize relation descriptors */
	initdesc(mode);

	/* re-build the tree */
	root = trbuild(root);
	if (!root)
		derror(STACKFULL);


	/* locate pointers to QLEND and TREE nodes */
	for (q = root->right; q->sym.type != QLEND; q = q->right)
		continue;
	Qle = q;

	for (q = root->left; q->sym.type != TREE; q = q->left)
		continue;
	Tr = q;


	/* map the complete tree */
	mapvar(root, 0);

	/* set logical locks */
	lockit(root, Resultvar);

	/* If there is no result variable then this must be a retrieve to the terminal */
	Qry_mode = Resultvar < 0 ? (int) mdRETTERM : mode;

	/* if the mode is retrieve_unique, then make a result rel */
	retr_uniq = mode == (int) mdRET_UNI;
	if (retr_uniq)
	{
		mk_unique(root);
		mode = (int) mdRETR;
	}

	/* get id of result relation */
	if (Resultvar < 0)
		result_num = NORESULT;
	else
		result_num = Rangev[Resultvar].relnum;

	/* evaluate aggregates in query */
	aggregate(root);

	/* decompose and process aggregate free query */
	decomp(root, mode, result_num);

	/* If this is a retrieve unique, then retrieve results */
	if (retr_uniq)
		pr_unique(root, Resultvar);

	if (mode != (int) mdRETR)
		i = ACK;
	else
		i = NOACK;
	i = endovqp(i);

	/* call update processor if batch mode */
	if (i == UPDATE)
	{
		initp();
		call_dbu(mdUPDATE, -1);
	}


	/*
	** send eop back to parser to indicate completion
	** if UPDATE then return block comes from dbu else
	** return block comes from decomp
	*/
	writeback(i == UPDATE ? -1 : 1);

#	ifdef xDTM
	if(AAtTf(76, 1))
		timtrace(24, 0);
#	endif
#	ifdef xDTR1
	AAtTfp(50, 1, "DECOMP read %ld pages,%ld catalog pages,wrote %ld pages\n",
		AAccuread, AAccusread, AAccuwrite);
#	endif

	/* clean decomp */
	reinit();

	/* return */
}