CDDTable *CRUCache::GetDDIUDLogTableByName(CDDSchema *pddSch, 
									const CDSString& logName)
{
	CDDTable *pddTable = pddSch->GetIUDLogTable(logName);

	if (NULL == pddTable) // try public schema if necessary
  {
    CDDSchema *pddSchP = GetPublicSchema();
    if (pddSchP)
    {
      pddTable = pddSch->GetIUDLogTable(logName);
      if (pddTable)
      { // if can be found in the public schema
        // update the catalog and schema
        CRUOptions &options = CRUGlobals::GetInstance()->GetOptions();  	  
        options.SetCatalogName(pddSchP->GetCatName());
        options.SetSchemaName(pddSchP->GetName());
      }
    }
  }

	if (NULL == pddTable)
	{
		// Table does not exist, metadata inconsistency
		CRUException e;
		e.SetError(IDS_RU_INCONSISTENT_CAT);
		throw e;
	}

	return pddTable;
}
//--------------------------------------------------------------------------//
//	CRURefreshTaskExecutor::VerifyForceTblListCorrectness()
//
// Check that the user did not refered to a un-existing base table
//--------------------------------------------------------------------------//
void CRURefreshTaskExecutor::VerifyForceTblListCorrectness()
{
	const CRUMVForceOptions &forceOption =
		*GetRefreshTask()->GetRootMV().GetMVForceOption();

	const CRUTableForceOptionsList &tblList = forceOption.GetTableForceList();

	DSListPosition pos = tblList.GetHeadPosition();

	while (NULL != pos) 
	{
		CRUTableForceOptions* forceOpt = tblList.GetNext(pos);
		
		CRUTbl *pTbl = GetRefreshTask()->GetRootMV().GetUsedTableByName(forceOpt->GetFullName());

		if(NULL == pTbl)
		{
			CRUException ex;
			ex.SetError(IDS_RU_FORCE_FILE_TABLE_NOT_EXISTS);
			ex.AddArgument(GetRefreshTask()->GetRootMV().GetFullName());
			ex.AddArgument(forceOpt->GetFullName());
			throw ex;
		}
	}
}
void CRUCache::FetchMVsInGroup(CDDSchema *pddSch, const CDSString& mvgName)
{
	CDDMVGroup *pddMVG = GetDDMVGroupByName(pddSch, mvgName);

	if (TRUE == pddMVG->IsEmpty()) 
	{
		// The source MVGROUP is empty
		CRUException e;
		e.SetError(IDS_RU_MVGROUP_EMPTY);
		e.AddArgument(pddMVG->GetFullName());
		throw e;
	}

	CDDUIDTripleList& uidList = pddMVG->GetAllMVs();
	DSListPosition pos = uidList.GetHeadPosition();

	while (NULL != pos) 
	{
		// Retrieve the DD object
		CDDUIDTriple uidt = uidList.GetNext(pos);

		CDDMV *pddMV = GetDDMVByUID(uidt);

		// Setup the CRUMV wrapper object
		FetchSingleInvolvedMV(pddMV);
	}
}
CDDMVGroup *CRUCache::GetDDMVGroupByName(CDDSchema *pddSch, const CDSString& mvgName)
{
	CDDMVGroup *pddMVG = pddSch->GetMVGroup(mvgName);

	if (NULL == pddMVG) // try public schema if necessary
  {
    CDDSchema *pddSchP = GetPublicSchema();
    if (pddSchP)
    {
      pddMVG = pddSchP->GetMVGroup(mvgName);
      if (pddMVG)
      { // if can be found in the public schema
        // update the catalog and schema
        CRUOptions &options = CRUGlobals::GetInstance()->GetOptions();  	  
        options.SetCatalogName(pddSchP->GetCatName());
        options.SetSchemaName(pddSchP->GetName());
      }
    }
  }

	if (NULL == pddMVG)
	{
		// Source MV group does not exist
		CRUException e;
		
		e.SetError(IDS_RU_INVALID_MVGROUP_NAME);
		CDSString fname = pddSch->GetFullName() + "." + mvgName;
		e.AddArgument(fname.c_string());
		throw e;	
	}

	return pddMVG;
}
void CRURangeCollection::InsertRangeBoundary(const CRUIUDLogRecord *pRec)
{
	RUASSERT(FALSE == pRec->IsSingleRowOp());

	// The scan order guarantees that the last record has the greatest CK.
	pMaxCKRecord_ = pRec;

	TInt32 ep = pRec->GetEpoch();
	UpdateMinEpoch(ep);

	if (FALSE == pRec->IsBeginRange())
	{
		balanceCounter_--;
		if (balanceCounter_ < 0)
		{
			// Incorrent (unbalanced) logging - should never happen
			CRUException ex;
			ex.SetError(IDS_RU_UNBALANCED_LOGGING);
			throw ex;
		}

		// Find the open range which has a Begin-range record
		// that matches this End-range record 
		LocateMatchForER(pRec);
	}
	else
	{
		balanceCounter_++;

		// Open a new range
		CRURange *pNewRange = new CRURange();
		pNewRange->SetBRRecord(pRec);
		rangeList_.AddTail(pNewRange);
	}
}
void CRURangeCollection::LocateMatchForER(const CRUIUDLogRecord *pRec)
{
	CRURange *pMatchingRange = NULL;

	if (CDDObject::eMANUAL == rlType_)
	{
		DSListPosition pos = rangeList_.GetHeadPosition();
		while (NULL != pos)
		{
			CRURange *pRange = rangeList_.GetNext(pos);
			if (NULL == pRange->GetERRecord())
			{
				pMatchingRange = pRange;
				break;
			}
		}
	}
	else
	{
		TInt64 erSyskey = pRec->GetSyskey();

		DSListPosition pos = rangeList_.GetHeadPosition();
		TInt64 matchingSyskey = 0;

		while (NULL != pos)
		{
			CRURange *pRange = rangeList_.GetNext(pos);
			
			if (NULL != pRange->GetERRecord())
			{
				continue;	// This one is already matched
			}

			TInt64 brSyskey = pRange->GetBRRecord()->GetSyskey();
			if (brSyskey > erSyskey) 
			{
				continue;	// This cannot match for sure
			}

			if (NULL == pMatchingRange
				||
				brSyskey > matchingSyskey)
			{
				pMatchingRange = pRange;
				matchingSyskey = brSyskey;
			}
		}
	}

	if (NULL == pMatchingRange)
	{
		// Incorrent (unbalanced) logging - should never happen
		CRUException ex;
		ex.SetError(IDS_RU_UNBALANCED_LOGGING);
		throw ex;
	}

	pMatchingRange->SetERRecord(pRec);
}
void CRURangeCollection::VerifyBalance()
{
	if (balanceCounter_ != 0)
	{
		// Incorrent (unbalanced) logging - should never happen
		CRUException ex;
		ex.SetError(IDS_RU_UNBALANCED_LOGGING);
		throw ex;
	}
}
CDDTable *CRUCache::GetDDTableByUID(const CDDUIDTriple &uidt)
{
	CDDSchema *pddSch = GetDDSchemaByUID(uidt.catUID, uidt.schUID);
	CDDTable *pddTbl = pddSch->GetTable(uidt.objUID);

	if (NULL == pddTbl)
	{
		// Table does not exist, metadata inconsistency
		CRUException e;
		e.SetError(IDS_RU_INCONSISTENT_CAT);
		throw e;
	}

	return pddTbl;
}
CDDMV *CRUCache::GetDDMVByUID(const CDDUIDTriple &uidt)
{
	CDDSchema *pddSch = GetDDSchemaByUID(uidt.catUID, uidt.schUID);
	CDDMV *pddMV = pddSch->GetMV(uidt.objUID);

	if (NULL == pddMV)
	{
		// MV does not exist, metadata inconsistency
		CRUException e;
		e.SetError(IDS_RU_INCONSISTENT_CAT);
		throw e;
	}

	return pddMV;
}
void CRUCache::FetchCascadedMVs(CDDSchema *pddSch, const CDSString& mvName)
{
	CDDMV *pddRootMV = GetDDMVByName(pddSch, mvName);

	if (CDDMV::eON_STATEMENT == pddRootMV->GetRefreshType())
	{
		// The CASCADE option is not allowed for ON STATEMENT MVs
		CRUException e;
		e.SetError(IDS_RU_ILLEGAL_CASCADE);
		e.AddArgument(pddRootMV->GetFullName());
		throw e;
	}

	// Start the recursive seacrh
	RecursiveFetchCascadedMVs(pddRootMV);
}
void CRURefreshTaskExecutor::CheckSingleDeltaRestriction()
{
	CRUMV &rootMV = GetRootMV();
	CRUTblList &tblList = rootMV.GetFullySyncTablesUsedByMe();

	DSListPosition pos = tblList.GetHeadPosition();
	while (NULL != pos)
	{
		CRUTbl *pTbl = tblList.GetNext(pos);
		RUASSERT (TRUE == pTbl->IsFullySynchronized());

		if (TRUE == pTbl->IsEmptyDeltaNeeded()
			&&
			TRUE == rootMV.IsDeltaNonEmpty(*pTbl))
		{
			CRUException errDesc;
			errDesc.SetError(IDS_RU_INCONSISTENT_JOIN);
			errDesc.AddArgument(rootMVName_);
			throw errDesc;
		}
	}
}
CDDSchema *CRUCache::GetDDSchemaByUID(TInt64 catUid, TInt64 schUid)
{
	CDDCatalog *pddCat = sqlNode_.GetCatalog(catUid);
	if (NULL == pddCat) 
	{
		// Catalog does not exist, metadata inconsistency
		CRUException e;	
		e.SetError(IDS_RU_INCONSISTENT_CAT);
		throw e;
	}
	
	CDDSchema *pddSch = pddCat->GetSchema(schUid);
	if (NULL == pddSch) 
	{
		// Schema does not exist, metadata inconsistency
		CRUException e;
		e.SetError(IDS_RU_INCONSISTENT_CAT);
		throw e;	
	}

	return pddSch;
}
void CRUCache::CheckLogCleanupApplicability()
{
	switch (lcType_)
	{
	case CRUOptions::WITHOUT_LC:
		break;	// Nothing to check

	case CRUOptions::DONTCARE_LC:
		{
			lcType_ = (TRUE == IsOnRequestMVInvolved()) ?
				CRUOptions::WITH_LC :
				CRUOptions::WITHOUT_LC;

			CRUOptions &options = CRUGlobals::GetInstance()->GetOptions();
			options.SetLogCleanupType(lcType_);

			break;
		}

	case CRUOptions::WITH_LC:
	case CRUOptions::DO_ONLY_LC:
		{
			if (FALSE == IsOnRequestMVInvolved())
			{
				// No candidate for log cleanup
				CRUException ex;

				ex.SetError(IDS_RU_EMPTY_CLEANUP_LIST);
				throw ex;
			}
			break;
		}

	default: RUASSERT(FALSE);
	}
}
CDDSchema *CRUCache::GetDDSchemaByName(const CDSString& catName,
									   const CDSString& schName)
{
  // check for DEFAULT_SCHEMA_ACCESS_ONLY
  // get default catalog & schema
  CRUOptions &options = CRUGlobals::GetInstance()->GetOptions();  	  
  CDSString curCatSch = catName + "." + schName;
  if (CDDControlQueryDefault::ViolateDefaultSchemaAccessOnly(
        options.GetDefaultSchema(), curCatSch))
  {
    CRUException e;
    e.SetError(IDS_RU_SCHEMA_ACCESS_VIOLATION);
    throw e;
  }

  CDDCatalog *pddCat = sqlNode_.GetCatalog(catName);
	if (NULL == pddCat) 
	{
		// Source catalog does not exist
		CRUException e;
						
		e.SetError(IDS_RU_INVALID_CATALOG_NAME);
		e.AddArgument(catName.c_string());
		throw e;
	}
	
	CDDSchema *pddSch = pddCat->GetSchema(schName, TRUE);

	if (NULL == pddSch) 
	{
		// Source schema does not exist
		CRUException e;
						
		e.SetError(IDS_RU_INVALID_SCHEMA_NAME);
		CDSString fname = catName + "." + schName;
		e.AddArgument(fname.c_string());
		throw e;	
	}

	return pddSch;
}