//--------------------------------------------------------------------------//
//	CRURefreshTaskExecutor::ComposeMDAMStatements()
//
//--------------------------------------------------------------------------//
void CRURefreshTaskExecutor::ComposeMDAMStatements()
{
	BOOL hasActiveCQS = FALSE;
	
	CRURefreshSQLComposer myComposer(GetRefreshTask());
	
	CRUMV &rootMV = GetRefreshTask()->GetRootMV();
	const CRUMVForceOptions* pForceOption = rootMV.GetMVForceOption();

	// Even if there are no force options, we still force mdam for tables
	// with more than two columns.
	ComposeControlTableStmtForUsedTables();

	// MV base tables force options
	// LCOV_EXCL_START :rfi
	if (NULL != pForceOption &&
		CRUForceOptions::MDAM_NO_FORCE != pForceOption->GetMDAMoption())
	{
		// Compose CONTROL TABLE mv_name MDAM option
		myComposer.ComposeCntrlTableMDAMText(pForceOption->GetMDAMoption(), 
											 &rootMV.GetFullName());
		pRefreshTEDynamicContainer_->SetStatementText(MV_MDAM_STAT, myComposer.GetSQL());
					
		forceFlags_ |= FORCE_MV_MDAM;
	}

	// Compose reset MDAMs
	if (forceFlags_ & FORCE_MV_MDAM || 	forceFlags_ & FORCE_TABLE_MDAM)
	{
		// Compose CONTROL TABLE * MDAM 'RESET'
		myComposer.ComposeResetCntrlTableMDAMText();
		pRefreshTEDynamicContainer_->SetStatementText(RESET_MDAM_STAT, myComposer.GetSQL());
	}
	// LCOV_EXCL_STOP
}
void CRUSimpleRefreshSQLComposer::AddDeltaDefListClause()
{
	RUASSERT(GetRefreshTask().GetDeltaDefList().GetCount() > 0);

	sql_ += "\n FROM ";
	sql_ += (TRUE == GetRefreshTask().IsSingleDeltaRefresh()) ? 
		"SINGLEDELTA " : "MULTIDELTA ";

	DSListPosition pos = GetRefreshTask().GetDeltaDefList().GetHeadPosition();

	for (;;)
	{
		CRUDeltaDef *pDdef = GetRefreshTask().GetDeltaDefList().GetNext(pos);

		CDSString fromEpoch(TInt32ToStr(pDdef->fromEpoch_)) ;
		CDSString toEpoch(TInt32ToStr(pDdef->toEpoch_));

		AddDeltaDefClause(pDdef,fromEpoch,toEpoch);

		if (NULL == pos)
		{
			break;	// The last clause
		}
		else
		{
			sql_ += ", ";
		}
	}	
	if (FALSE == GetRefreshTask().IsSingleDeltaRefresh())
	{
		AddPhaseParam();
	}
}
//--------------------------------------------------------------------------//
//	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 CRURefreshTaskExecutor::GenClosureMessage(CDSString &msg) 
{
	CRURefreshTask &task = *GetRefreshTask();

	if (task.GetMVList().GetCount() > 1)
	{
		if (FALSE == GetRefreshTask()->NeedToExecuteInternalRefresh())
		{
			msg += RefreshDiags[2];
			task.DumpNamesOfAllMVs(msg);
			msg += RefreshDiags[6];
		}
		else
		{
			msg += RefreshDiags[2];
			task.DumpNamesOfAllMVs(msg);
			msg += RefreshDiags[7];
		}
	}
	else
	{
		if (FALSE == GetRefreshTask()->NeedToExecuteInternalRefresh())
		{
			msg += RefreshDiags[3];
			task.DumpNamesOfAllMVs(msg);
			msg += RefreshDiags[8];
		}
		else
		{
			msg += RefreshDiags[3];
			task.DumpNamesOfAllMVs(msg);
			msg += RefreshDiags[9];
		}
	}
}
void CRURefreshTaskExecutor::ComposeMySql()
{
	CRURefreshSQLComposer myComposer(GetRefreshTask());

	CRUMV &rootMV = GetRefreshTask()->GetRootMV();

	numOfStmtInContainer_ = rootMV.GetTablesUsedByMe().GetCount() + FIRST_TBL_STAT;

	pRefreshTEDynamicContainer_ = 
#pragma nowarn(1506)   // warning elimination 
		new CRUSQLDynamicStatementContainer(numOfStmtInContainer_);
#pragma warn(1506)  // warning elimination 

	ComposeForceStatements();
}
void CRUAuditRefreshTaskExecutor::Epilogue()
{
	RUASSERT(FALSE == IsTransactionOpen());

        EndTimer();

        BeginTransaction();

	// if this is the first refresh, the MV status can be
        // changed to initialized
	if( TRUE == GetRefreshTask()->NeedToExecuteInternalRefresh() )
	{
        	if (CDDObject::eON_STATEMENT == GetRootMVType())
		{
			EpilogueHandleOnStatementMV();
		}		
		ResetObjectsAvailable();	
	}		

	FinalMetadataUpdate();

	CommitTransaction();

	TESTPOINT2(CRUGlobals::TESTPOINT131, GetRootMVName());
	
	LogClosureMessage();

	SetState(EX_COMPLETE);
}
//--------------------------------------------------------------------------//
//	CRURefreshTaskExecutor::ComposeControlTableStmtForUsedTables()
//
// Compose the Control MDAM option for all base tables for forced tables
//--------------------------------------------------------------------------//
// LCOV_EXCL_START :rfi
void CRURefreshTaskExecutor::ComposeControlTableStmtForUsedTables() 
{
	CRUMV &rootMV = GetRefreshTask()->GetRootMV();

	const CRUMVForceOptions* pForceOption = rootMV.GetMVForceOption();

	CRUForceOptions::MdamOptions mdamOpt = CRUForceOptions::MDAM_NO_FORCE;

	Int32 stmtIndex = FIRST_TBL_STAT;

	if (NULL != pForceOption)
	{
		VerifyForceTblListCorrectness();

		if (pForceOption->IsTableStarUsed())
		{
			mdamOpt = pForceOption->GetTableStarOption();
		}
	}

	CRUTblList &tblList = rootMV.GetTablesUsedByMe();
	
	DSListPosition pos = tblList.GetHeadPosition();

	while (NULL != pos)
	{
		CRUTbl *pTbl = tblList.GetNext(pos);
		RUASSERT(NULL != pTbl);
		ComposeControlTableStmtForUsedTable(*pTbl,stmtIndex,mdamOpt);
	}
}
CRUTableForceOptions* CRURefreshTaskExecutor::GetForceOptionForTable(const CDSString &name) 
{
	CRUMV &rootMV = GetRefreshTask()->GetRootMV();

	const CRUMVForceOptions* pForceOption = rootMV.GetMVForceOption();

	if (NULL == pForceOption)
	{
		return NULL;
	}

	const CRUTableForceOptionsList &tblList = pForceOption->GetTableForceList();

	DSListPosition pos = tblList.GetHeadPosition();

	while (NULL != pos) 
	{
		CRUTableForceOptions* forceOpt = tblList.GetNext(pos);
		if (name == forceOpt->GetFullName())
		{
			return forceOpt;
		}
	}
	return NULL;
}
void CRUUnAuditRefreshTaskExecutor::Epilogue()
{
	EndTimer();

	BeginTransaction();

	if (TRUE == GetRefreshTask()->NeedToExecuteInternalRefresh())
	{
		if (CDDObject::eON_STATEMENT == GetRootMVType())
		{
			EpilogueHandleOnStatementMV();
		}
		
		// Set the MV(s)/indexes back available
		ResetObjectsAvailable();

	}

	FinalMetadataUpdate();
	
	CommitTransaction();

	TESTPOINT2(CRUGlobals::TESTPOINT107, GetRootMVName());
	
	LogClosureMessage();

	SetState(EX_COMPLETE);
}
void CRURefreshSQLComposer::AddPipeLineClause()
{
	CRUMVList &mvList = GetRefreshTask().GetMVList();
	RUASSERT(mvList.GetCount() > 1);

	DSListPosition pos = mvList.GetHeadPosition();
	mvList.GetNext(pos);	// Skip the root MV
	
	// Generate root clause
	CRUMV *pTopMV = mvList.GetNext(pos);

	sql_ += " PIPELINE " ;
	sql_ += "(" + pTopMV->GetFullName() + ")";

	// Continue with the upper mv's
	while (NULL != pos)
	{
		sql_ += pTopMV->GetFullName();
		
		// Retrieve the next MV from the list
		pTopMV = mvList.GetNext(pos);

		sql_ += " PIPELINE " ;
		sql_ += "(" + pTopMV->GetFullName() + ")";

		if (NULL != pos)
		{
			sql_ += ",";
		}
		else
		{
			return;
		}
	}
}
void CRUAuditRefreshTaskExecutor::ResetObjectsAvailable()
{
        CRUMVList &mvList = GetRefreshTask()->GetMVList();
	DSListPosition pos = mvList.GetHeadPosition();
	while (NULL != pos)
	{
		CRUMV *pMV = mvList.GetNext(pos);
                BOOL  mvUpdated = FALSE;
		
		// if hasn't been set to initialized, initialize it
                if( CDDObject::eINITIALIZED != pMV->GetMVStatus() )
                {
			pMV->SetMVStatus(CDDObject::eINITIALIZED);
                        mvUpdated = TRUE;
                }

                if (mvUpdated)
                {
			pMV->SaveMetadata();
                }

	}        

        if (TRUE == isPopindex_ && 0 < numOfIndexes_)
	{                
		// Turn all indexes to available state
		ExecuteIndexStatmenents(*pAuditAvailableIndeXdynamicContainer_,
					IDS_RU_INDEXSTATUS_FAILED);
	}	
}
void CRURefreshTaskExecutor::UpdateRootMVStatistics(TInt32 currDuration)
{
	CRURefreshTask &task = *GetRefreshTask();
	if (FALSE == task.NeedToExecuteInternalRefresh())
	{
		return;
	}

	CRUDeltaDefList &deltaDefList = task.GetDeltaDefList();

	TInt32 prevDuration, nextDuration;
	CRUMV &rootMV = GetRootMV();

	if (TRUE == IsRecompute())
	{
		prevDuration = rootMV.GetRecomputeDurationEstimate();
		nextDuration = EvaluateHeuristic(currDuration, prevDuration);
		rootMV.SetRecomputeDurationEstimate(nextDuration);
		return;
	}

	switch(deltaDefList.GetCount())
	{
		case 0:
		{
			// This cannot happen 
			// (NeedToExecuteInternalRefresh() must have returned FALSE).
			RUASSERT(FALSE);
		}
		case 1:
		{
			CRUDeltaDef *pDdef = deltaDefList.GetAt(0);
			// A special case: update the refresh duration,
			// and (optionally) the delta size.
			UpdateSingleDeltaStatistics(pDdef, currDuration);
			break;
		}
		case 2:
		{
			prevDuration = rootMV.GetRefreshDurationEstimateWith_2_Deltas();
			nextDuration = EvaluateHeuristic(currDuration, prevDuration);
			rootMV.SetRefreshDurationEstimateWith_2_Deltas(nextDuration);
			break;
		}
		case 3:
		{
			prevDuration = rootMV.GetRefreshDurationEstimateWith_3_Deltas();
			nextDuration = EvaluateHeuristic(currDuration, prevDuration);
			rootMV.SetRefreshDurationEstimateWith_3_Deltas(nextDuration);
			break;
		}
		default:
		{
			prevDuration = rootMV.GetRefreshDurationEstimateWith_N_Deltas();
			nextDuration = EvaluateHeuristic(currDuration, prevDuration);
			rootMV.SetRefreshDurationEstimateWith_N_Deltas(nextDuration);
			break;
		}
	}
}
void CRURefreshTaskExecutor::ComposeControlTableStmtForUsedTable(CRUTbl &tbl,
																 Int32 &stmtIndex,
																 CRUForceOptions::MdamOptions mdamOpt)
{
   	CRURefreshSQLComposer myComposer(GetRefreshTask());
	

	if (CRUForceOptions::MDAM_NO_FORCE == mdamOpt)
	{
		CRUTableForceOptions *forceOpt = GetForceOptionForTable(tbl.GetFullName());
		
		if (NULL == forceOpt)
		{
			mdamOpt = GetDefaultMdamOptForTable(tbl);
		}
		else
		{
			mdamOpt = forceOpt->GetMdamOptions();
		}
	}

	if (CRUForceOptions::MDAM_NO_FORCE != mdamOpt)
	{
		// Compose CONTROL TABLE table_name MDAM option
		myComposer.ComposeCntrlTableMDAMText(mdamOpt, &(tbl.GetFullName()));
		pRefreshTEDynamicContainer_->SetStatementText
#pragma nowarn(1506)   // warning elimination 
			(stmtIndex++, myComposer.GetSQL());
#pragma warn(1506)  // warning elimination 
		
		forceFlags_ |= FORCE_TABLE_MDAM;
	}

}
void CRURefreshTaskExecutor::FinalMetadataUpdate()
{
	CRURefreshTask *pParentTask = GetRefreshTask();
	RUASSERT (NULL != pParentTask);


	TInt32 currDuration = 0;
        TInt64 ts = CalculateTimeStamp();

	if (TRUE == pParentTask->NeedToExecuteInternalRefresh())
	{
		currDuration = GetTimerDuration();
	}
	
	CRUMV *pPrevMV, *pCurrMV = NULL;
	CRUMVList &mvList = pParentTask->GetMVList();
	DSListPosition pos = mvList.GetHeadPosition();

	while (NULL != pos)
	{
		pPrevMV = pCurrMV;
		pCurrMV = mvList.GetNext(pos);

		// Update the MV's REFRESHED_AT timestamp
		pCurrMV->SetTimestamp(ts);

                // publish the refresh event to the PUBLISH table
           NABoolean isRecomputePublish = (IsRecompute() == TRUE);
           pCurrMV->PublishMVRefresh(isRecomputePublish);
   
	   if (CDDObject::eON_STATEMENT != pCurrMV->GetRefreshType())
           {
		if (NULL == pPrevMV)
		{
			// This is the Root MV (the first in the list)
			if (CDDObject::eON_REQUEST == pCurrMV->GetRefreshType())
			{
				// For every table T used by MV, 
				// set MV.EPOCH[T]<--T.CURRENT_EPOCH.
				UpdateRootMVCurrentEpochVector();
			}
			
			UpdateRootMVStatistics(currDuration);
		}
		else
		{
			UpdateNonRootMVStatistics(pCurrMV, pPrevMV, currDuration);
		}
	   }
		
		pCurrMV->SaveMetadata();
	}

        if (CDDObject::eON_STATEMENT != GetRootMV().GetRefreshType())
        {
	IncrementTopMvCurrentEpoch();
        }
}
//--------------------------------------------------------------------------//
//	CRURefreshTaskExecutor::ComposeCQSStatements()
//
//--------------------------------------------------------------------------//
void CRURefreshTaskExecutor::ComposeCQSStatements()
{
	BOOL hasActiveCQS = FALSE;
	
	CRURefreshSQLComposer myComposer(GetRefreshTask());
	
	CRUMV &rootMV = GetRefreshTask()->GetRootMV();
	const CRUMVForceOptions* pForceOption = rootMV.GetMVForceOption();

	if (NULL == pForceOption)
	{
		return;
	}

	// MV force options
	// LCOV_EXCL_START :rfi
	if ((CRUForceOptions::GB_NO_FORCE != pForceOption->GetGroupByoption() ||
	    CRUForceOptions::JOIN_NO_FORCE !=   pForceOption->GetJoinoption()))
	{
		// Compose Control query shape for internal refresh stmt
		myComposer.ComposeControlQueryShape();
		pRefreshTEDynamicContainer_->SetStatementText(CQS_STAT, myComposer.GetSQL());
		forceFlags_ = forceFlags_ | FORCE_CQS;
		hasActiveCQS = TRUE;
	}

	// Deal with a specific user CQS
	if (FALSE == pForceOption->GetCQSStatment().IsEmpty())
	{
		pRefreshTEDynamicContainer_->SetStatementText
			(USER_CQS_FORCE, pForceOption->GetCQSStatment());
		forceFlags_ = forceFlags_ | FORCE_USER_CQS;
		hasActiveCQS = TRUE;
	}

	if (TRUE == hasActiveCQS)
	{
		myComposer.ComposeControlQueryShapeCut();
		pRefreshTEDynamicContainer_->SetStatementText(CQS_CUT_STAT, myComposer.GetSQL());
	}
	// LCOV_EXCL_STOP
}
void CRUSimpleRefreshSQLComposer::ComposeRefresh()
{
	StartInternalRefresh();

	AddDeltaDefListClause();
	
	if (GetRefreshTask().GetMVList().GetCount() > 1)
	{
		AddPipeLineClause();
	}
}
void CRURefreshTaskExecutor::ComposeForceStatements()
{
	CRUMV &rootMV = GetRefreshTask()->GetRootMV();
	const CRUMVForceOptions* pForceOption = rootMV.GetMVForceOption();
	CRURefreshSQLComposer myComposer(GetRefreshTask());

	// Deal with explain data
	// LCOV_EXCL_START :rfi
	if (NULL != pForceOption &&
		CRUForceOptions::EXPLAIN_ON == pForceOption->GetExplainOption())
	{
		forceFlags_ = forceFlags_ | FORCE_SHOW_EXPLAIN; 
		myComposer.ComposeShowExplain();
		pRefreshTEDynamicContainer_->SetStatementText(SHOW_EXPLAIN, myComposer.GetSQL());
	}
	// LCOV_EXCL_STOP

	ComposeCQSStatements();
	
	ComposeMDAMStatements();
}
void CRURefreshTaskExecutor::IncrementTopMvCurrentEpoch()
{
	CRUMV &mv = GetRefreshTask()->GetTopMV();

	if (TRUE == mv.IsInvolvedTbl())
	{
		CRUTbl *pTbl = mv.GetTblInterface();
		
		pTbl->IncrementCurrentEpoch(TRUE /* through DDOL */);
		pTbl->SaveMetadata();
		
		pTbl->SetTimestamp(mv.GetTimestamp());
	}
}
void CRUUnAuditRefreshTaskExecutor::ComposeMySql()
{
	CRURefreshTask *pTask = GetRefreshTask();
	CRUMV &mv = pTask->GetRootMV();

	CRUSimpleRefreshSQLComposer myComposer(pTask);

	// UNLOCK TABLE statement
	myComposer.ComposeUnLock(GetRootMVName());
	
	unAuditRefreshTEDynamicContainer_.SetStatementText
				(RU_UNLOCK_TABLE, myComposer.GetSQL());

	// POPINDEX CatApi request
	if (TRUE == isPopindex_)
	{
		numOfIndexes_ = mv.GetIndexList().GetCount();
		
		if (0 < numOfIndexes_)
		{
			ComposeIndexesSql();
		}
	}

	// Compose the LOCK TABLE sql statements for locking all tables 
	// in the on statement MV initialization 
	if (CDDObject::eON_STATEMENT == GetRootMVType())
	{	
		CRUTblList &tblList = mv.GetTablesUsedByMe();
		
		DSListPosition pos = tblList.GetHeadPosition();
		
		pLockTablesTEDynamicContainer_ = 
			new CRUSQLDynamicStatementContainer((short)tblList.GetCount());
		
		Int32 i=0;
		
		while (NULL != pos)
		{
			CRUTbl *pTbl = tblList.GetNext(pos);
			myComposer.ComposeLock(pTbl->GetFullName(), FALSE /*shared*/);
			pLockTablesTEDynamicContainer_->SetStatementText
#pragma nowarn(1506)   // warning elimination 
				(i,myComposer.GetSQL());
#pragma warn(1506)  // warning elimination 
			i++;
		}
	}
}
void CRUUnAuditRefreshTaskExecutor::Start()
{
	LogOpeningMessage();

	StartTimer();
	
	if (FALSE == GetRefreshTask()->NeedToExecuteInternalRefresh())
	{
		SetState(EX_EPILOGUE);
	}
	else
	{
		SetState(EX_PROLOGUE);
	}
}
void CRUAuditRefreshTaskExecutor::Init()
{
	inherited::Init();
	
	RUASSERT(TRUE == HasWork());

	if (FALSE == GetRefreshTask()->NeedToExecuteInternalRefresh())
	{
		return;
	}

        Lng32 refreshPattern = GetRootMV().GetRefreshPatternMap();
	isPurgedata_ = (0 != (refreshPattern & CRUMV::PURGEDATA));
	isPopindex_ = (0 != (refreshPattern & CRUMV::POPINDEX));

	CRUMV &mv = GetRootMV();
	if (mv.GetCommitNRows() != 0 && 
		TRUE == GetRootMV().IsMultiTxnContext())
	{
		RUASSERT(TRUE == GetRefreshTask()->IsRecompute());

		// We need to drop multi-txn context table
		// becuase we are recomputing a multi-txn mv
		isDeleteMultiTxnContext_ = TRUE;
	}

	// We must synchronize between the table and the mv, so we need to 
	// lock the table partitions
	// Here we copy the partitions file names in order to allow access to 
	// the files in the remote process when DDOL is not built
	tableLockProtocol_ = new CRUTableLockProtocol();
	tableLockProtocol_->Init(mv.GetTablesUsedByMe(), 
				 GetRefreshTask()->GetDeltaDefList());

	ComposeMySql();
}
void CRUAuditRefreshTaskExecutor::ComposeMySql()
{
	CRUSimpleRefreshSQLComposer myComposer(GetRefreshTask());
	CRUMV &rootMV = GetRootMV();        	

	if (TRUE == isDeleteMultiTxnContext_)
	{
		myComposer.ComposeDeleteContextLogTable();

		auditRefreshTEDynamicContainer_.SetStatementText
			(DELETE_MULT_TXN_CTX_TBL,myComposer.GetSQL());
	}

        // POPINDEX CatApi request
	if (TRUE == isPopindex_)
	{
		numOfIndexes_ = rootMV.GetIndexList().GetCount();
		              
		if (0 < numOfIndexes_)
		{
			ComposeIndexesSql();
		}
	}

	// Compose the LOCK TABLE sql statements for locking all tables 
	// in the on statement MV initialization 
	if (CDDObject::eON_STATEMENT == GetRootMVType())
	{	
		CRUTblList &tblList = rootMV.GetTablesUsedByMe();
		
		DSListPosition pos = tblList.GetHeadPosition();
		
		pLockTablesTEDynamicContainer_ = 
			new CRUSQLDynamicStatementContainer((short)tblList.GetCount());
		
		Int32 i=0;
		
		while (NULL != pos)
		{
			CRUTbl *pTbl = tblList.GetNext(pos);
			myComposer.ComposeLock(pTbl->GetFullName(), FALSE /*shared*/);
			pLockTablesTEDynamicContainer_->SetStatementText
				(i,myComposer.GetSQL());
			i++;
		}
	}
}
void CRUUnAuditRefreshTaskExecutor::SetObjectsUnavailable()
{
	if (TRUE == isPopindex_ && 0 < numOfIndexes_)
	{
		// Turn all indexes to unavailable state
		ExecuteIndexStatmenents(*pUnAuditUnavailableIndeXdynamicContainer_,
								IDS_RU_INDEXSTATUS_FAILED);
	} 

	CRUMVList &mvList = GetRefreshTask()->GetMVList();

	DSListPosition pos = mvList.GetHeadPosition();
	while (NULL != pos)
	{
		CRUMV *pMV = mvList.GetNext(pos);
		if (CDDObject::eNO_AUDIT_ON_REFRESH == pMV->GetAuditType()
			// || 
			// CDDObject::eAUDIT == pMV->GetAuditType()
			// DO NOT TURN THE AUDITED MV'S TABLE TO NON-AUDITED
			// UNTIL THE BUG WITH TURNING THE AUDIT ATTRIBUTE IS FIXED !!!
			// Right now, we assume that the MV's table is initially
			// non-audited if this task executor is picked up.
			)
		{
		  // Alter table audit uses "ALTER TABLE" syntax
		  // and it cannot be performed if there is a DDL lock.
		  // Due to the transaction protection , for any other transaction
		  // the ddl locks will preserve continuity.
		  pMV->ReleaseDDLLock();
		  pMV->SetMVTableAudit(FALSE);
		  pMV->SaveMetadata();
		  pMV->CreateDDLLock();
		  
		}
		
		pMV->SetMVStatus(CDDObject::eUNAVAILABLE);
		pMV->SaveMetadata();
	} 

        // Since the mv ddl lock was released and recreated, the popindex
        // sql statements need to be recomposed
        if( TRUE == isPopindex_ && 0 < numOfIndexes_ )
        {
        	ComposeIndexesSql();
        }
}
void CRURefreshTaskExecutor::GenOpeningMessage(CDSString &msg) 
{
	CRURefreshTask &task = *GetRefreshTask();

	if (task.GetMVList().GetCount() > 1)
	{
		msg += RefreshDiags[2];
		task.DumpNamesOfAllMVs(msg);
		msg += RefreshDiags[4];
	}
	else
	{
		msg += RefreshDiags[3];
		task.DumpNamesOfAllMVs(msg);
		msg += RefreshDiags[5];
	}
}
void CRUAuditRefreshTaskExecutor::Start()
{
	RUASSERT(FALSE == IsTransactionOpen());

	LogOpeningMessage();

	StartTimer();

	TESTPOINT2(CRUGlobals::TESTPOINT130, GetRootMVName())

	if (FALSE == GetRefreshTask()->NeedToExecuteInternalRefresh())
	{
		// There is no delta , we only need to update the metadata 
		SetState(EX_EPILOGUE);
	}
	else
	{		 
		SetState(EX_PROLOGUE);
	}
}
void CRUUnAuditRefreshTaskExecutor::Init()
{
	inherited::Init();

	RUASSERT(TRUE == HasWork());

	if (FALSE == GetRefreshTask()->NeedToExecuteInternalRefresh())
	{
		return;
	}

	Lng32 refreshPattern = GetRootMV().GetRefreshPatternMap();
	isPurgedata_ = (0 != (refreshPattern & CRUMV::PURGEDATA));
	isPopindex_ = (0 != (refreshPattern & CRUMV::POPINDEX));

	// Compose the INTERNAL REFRESH 
	// + (optionally) the PopIndex CatApi request statements
	// + (optionally) the LOCK TABLE statements for ON STATEMENT MV
	ComposeMySql();
}
void CRUAuditRefreshTaskExecutor::SetObjectsUnavailable()
{
	if (TRUE == isPopindex_ && 0 < numOfIndexes_)
	{
		// Turn all indexes to unavailable state
		ExecuteIndexStatmenents(*pAuditUnavailableIndeXdynamicContainer_,
					IDS_RU_INDEXSTATUS_FAILED);
	} 

        // first turn the audit flag ON for the MV table
        // and set the MV to unavailable
	CRUMVList &mvList = GetRefreshTask()->GetMVList();
	DSListPosition pos = mvList.GetHeadPosition();
	while (NULL != pos)
	{
		CRUMV *pMV = mvList.GetNext(pos);

		// Alter table audit uses "ALTER TABLE" syntax
		// and it cannot be performed if there is a DDL lock.
		// Due to the transaction protection , for any other transaction
		// the ddl locks will preserve continuity.
		pMV->ReleaseDDLLock();
		pMV->SetMVTableAudit(TRUE);               
		pMV->SaveMetadata();
		pMV->CreateDDLLock();
		
		// if hasn't been set to initialized, initialize it
                if( CDDObject::eINITIALIZED != pMV->GetMVStatus() )
                {
			pMV->SetMVStatus(CDDObject::eUNAVAILABLE);
			pMV->SaveMetadata();                
                }
	}        

        // Since the mv ddl lock was released and recreated, the popindex
        // sql statements need to be recomposed
        if( TRUE == isPopindex_ && 0 < numOfIndexes_ )
        {
        	ComposeIndexesSql();
        }
}
void CRURefreshTaskExecutor::
UpdateNonRootMVStatistics(CRUMV *pCurrMV, 
						  CRUMV *pPrevMV,
						  TInt32 currDuration)
{
	if (FALSE == GetRefreshTask()->NeedToExecuteInternalRefresh())
	{
		return;
	}

	TInt64 tblUid = pPrevMV->GetUID();

	TInt32 prevDuration = 
		pCurrMV->GetRefreshDurationEstimate(tblUid);

	TInt32 nextDuration = 
		EvaluateHeuristic(currDuration, prevDuration);

	pCurrMV->SetRefreshDurationEstimate(tblUid, prevDuration);
	pCurrMV->SetDeltaSizeEstimate(tblUid, 0);
}
void CRURefreshTaskExecutor::Init()
{
	inherited::Init(); 

	CRUMV &rootMV = GetRefreshTask()->GetRootMV();

	SetRecompute(rootMV.WillBeRecomputed());

	rootMVName_   = rootMV.GetFullName();
	rootMVSchema_ = rootMV.GetCatName() + "." + rootMV.GetSchName();
	rootMVCatalog_ = rootMV.GetCatName();

	rootMVType_   = rootMV.GetRefreshType();
	rootMVUID_	  = rootMV.GetUID();

	// Runtime consistency check.
	// Check requirement that the regular table's deltas 
	// are empty (if they must be).
	CheckSingleDeltaRestriction();

	ComposeMySql();
} 
//--------------------------------------------------------------------------//
//	CRURefreshTaskExecutor::GetDefaultMdamOptForTable()
//
// If the table has more then two key columns and the range log is not empty
// then mdam must be forced on the table unless the user forced otherwise
//--------------------------------------------------------------------------//
CRUForceOptions::MdamOptions CRURefreshTaskExecutor::GetDefaultMdamOptForTable(CRUTbl &tbl)
{
	Int32 numTableKeyCol = tbl.GetKeyColumnList().GetCount();

	if (numTableKeyCol < 2)
	{
		return CRUForceOptions::MDAM_NO_FORCE;
	}

	if (FALSE == GetRefreshTask()->IsSingleDeltaRefresh())
	{
		return CRUForceOptions::MDAM_NO_FORCE;
	}

	const CRUDeltaDef *pDdef = GetRootMV().GetDeltaDefByUid(tbl.GetUID());
	
	if (NULL != pDdef && TRUE == pDdef->isRangeLogNonEmpty_)
	{
		return CRUForceOptions::MDAM_ON;
	}

	return CRUForceOptions::MDAM_NO_FORCE;
}