Beispiel #1
0
//---------------------------------------------------------------------------
//	@function:
//		CBinding::PexprExtract
//
//	@doc:
//		Extract a binding according to a given pattern;
//		Keep root node fixed;
//
//---------------------------------------------------------------------------
CExpression *
CBinding::PexprExtract
	(
	IMemoryPool *pmp,
	CGroupExpression *pgexpr,
	CExpression *pexprPattern,
	CExpression *pexprLast
	)
{
	GPOS_CHECK_ABORT;

	if (!pexprPattern->FMatchPattern(pgexpr))
	{
		// shallow matching fails
		return NULL;
	}
	
	// the previously extracted pattern must have the same root
	GPOS_ASSERT_IMP(NULL != pexprLast, pexprLast->Pgexpr() == pgexpr);

	COperator *popPattern = pexprPattern->Pop();
	if (popPattern->FPattern() && CPattern::PopConvert(popPattern)->FLeaf())
	{
		// return immediately; no deep extraction for leaf patterns
		pgexpr->Pop()->AddRef();
		return GPOS_NEW(pmp) CExpression(pmp, pgexpr->Pop(), pgexpr);
	}

	DrgPexpr *pdrgpexpr = NULL;
	ULONG ulArity = pgexpr->UlArity();
	if (0 == ulArity && NULL != pexprLast)
	{
		// no more bindings
		return NULL;
	}
	else
	{
		// attempt binding to children
		pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
		if (!FExtractChildren(pmp, pgexpr, pexprPattern, pexprLast, pdrgpexpr))
		{
			pdrgpexpr->Release();
			return NULL;
		}
	}					

	CExpression *pexpr = PexprFinalize(pmp, pgexpr, pdrgpexpr);
	GPOS_ASSERT(NULL != pexpr);
	
	return pexpr;
}
Beispiel #2
0
//---------------------------------------------------------------------------
//	@function:
//		CBinding::PexprExtract
//
//	@doc:
//		Extract a binding according to a given pattern;
//		If no appropriate child pattern can be matched advance the root node
//		until group is exhausted;
//
//---------------------------------------------------------------------------
CExpression *
CBinding::PexprExtract
	(
	IMemoryPool *pmp,
	CGroup *pgroup,
	CExpression *pexprPattern,
	CExpression *pexprLast
	)
{
	GPOS_CHECK_STACK_SIZE;
	GPOS_CHECK_ABORT;

	GPOS_ASSERT(NULL != pgroup);
	GPOS_ASSERT(NULL != pexprPattern);

	CGroupExpression *pgexpr = NULL;
	if (NULL != pexprLast)
	{
		pgexpr = pexprLast->Pgexpr();
	}
	else
	{
		// init cursor
		pgexpr = PgexprNext(pgroup, NULL);
	}
	GPOS_ASSERT(NULL != pgexpr);
	
	COperator *popPattern = pexprPattern->Pop();
	if (popPattern->FPattern() && CPattern::PopConvert(popPattern)->FLeaf())
	{
		// for leaf patterns, we do not iterate on group expressions
		if (NULL != pexprLast)
		{
			// if a leaf was extracted before, then group is exhausted
			return NULL;
		}

		return PexprExtract(pmp, pgexpr, pexprPattern, pexprLast);
	}

	// start position for next binding
	CExpression *pexprStart = pexprLast;
	do 
	{
		if (pexprPattern->FMatchPattern(pgexpr))
		{
			CExpression *pexprResult =
				PexprExtract(pmp, pgexpr, pexprPattern, pexprStart);
			if (NULL != pexprResult)
			{
				return pexprResult;
			}
		}
		
		// move cursor and reset start position
		pgexpr = PgexprNext(pgroup, pgexpr);
		pexprStart = NULL;

		GPOS_CHECK_ABORT;
	}
	while (NULL != pgexpr);

	// group exhausted
	return NULL;
}