// Add to the RETDesc of the current BindScope new columns, 
// each with the information found by lookupTableName(), but with the refName
// as a correlation name to the table.
void TableRefName::bindRefColumns(BindWA *bindWA) const
{
	if (getColumnList() == NULL)
		return;    // REFERENCING an unused transition name.

	RETDesc *currentRETDesc = bindWA->getCurrentScope()->getRETDesc();
	// Create a new CorrName for the table, with the refName as a correllation
	// name. Since it's the same table for all columns, take the table name
	// from the first column.
	const ColumnDesc *firstCol = getColumnList()->at(0);
	CorrName updatedCorrName(firstCol->getColRefNameObj().getCorrNameObj());
	updatedCorrName.setCorrName(getRefName());

	// Insert this CorrName into the XTNM of the current BindScope.
//	bindWA->getCurrentScope()->getXTNM()->insertNames(bindWA,updatedCorrName);
	
	for (CollIndex i=0; i<getColumnList()->entries(); i++) 
	{
		// For each column of the table
		const ColumnDesc *currentCol = getColumnList()->at(i);			
		// Create a new column ref, with the updated corellation name.
		ColRefName renamedColumn(currentCol->getColRefNameObj().getColName(), 
								 updatedCorrName);

		// Add it to the RETDesc of the current scope.
		currentRETDesc->addColumn(bindWA, 
								  renamedColumn, 
								  currentCol->getValueId(), 
								  USER_COLUMN, 
								  currentCol->getHeading());
	}
}
// Find the table names in the specified RETDesc.
// Returns TRUE if found.
NABoolean TableRefName::lookupTableName(RETDesc *retDesc)
{
	if (retDesc == NULL)
		return FALSE;

	if (getColumnList() != NULL)    // Have we already found this one?
		return FALSE;
									// Lookup the table name in the RETDesc
	ColumnDescList *columnList = retDesc->getQualColumnList(getTableCorr());
	if (columnList == NULL)
		return FALSE;

	setColumnList(columnList);      // Save the pointer to the ColumnDescList
	return TRUE;                    // One reference less to find.
}
// -----------------------------------------------------------------------
// Statistics stuff
// -----------------------------------------------------------------------
const ColStatDescList &TableDesc::getTableColStats()
{
    // HIST_NO_STATS_UEC can never be greater than HIST_NO_STATS_ROWCOUNT.
    // If the customer has done an illegal setting, ignore that, and set
    // it to maximum permissible value

    if (CURRSTMT_OPTDEFAULTS->defNoStatsUec() > CURRSTMT_OPTDEFAULTS->defNoStatsRowCount())
    {
        CURRSTMT_OPTDEFAULTS->setNoStatsUec(CURRSTMT_OPTDEFAULTS->defNoStatsRowCount());
    }

    if (colStats_.entries() > 0)
    {
        if (!areHistsCompressed() && (CmpCommon::getDefault(COMP_BOOL_18) != DF_ON) )
        {
            // compress histograms based on query predicates
            compressHistogramsForCurrentQuery();
        }
        return colStats_;
    }

    // For each ColStat, create a ColStat descriptor.
    StatsList &stats = ((NATable *)table_)->getStatistics() ;

    // if for some reason, no histograms were returned by update statistics
    // generate fake histograms for the table

    if ( stats.entries() == 0 )
        stats = ((NATable *)table_)->generateFakeStats();

    const NAColumnArray &columnList = ((NATable *)table_)->getNAColumnArray();
    const ValueIdList & tableColList = getColumnList();
    colStats_.insertByPosition(stats, columnList, tableColList);

    // done creating a ColStatDesc for each ColStats;
    // ==> now store the multi-column uec information
    MultiColumnUecList * groupUecs = new (CmpCommon::statementHeap())
    MultiColumnUecList (stats, getColumnList()) ;
    CostScalar rowcount = stats[0]->getRowcount();
    groupUecs->initializeMCUecForUniqueIndxes(*this, rowcount);

    colStats_.setUecList (groupUecs) ;

    if (CmpCommon::getDefault(USTAT_COLLECT_MC_SKEW_VALUES) == DF_ON)
    {
        MultiColumnSkewedValueLists* mcSkewedValueLists= new (CmpCommon::statementHeap())
        MultiColumnSkewedValueLists(stats, getColumnList()) ;
        colStats_.setMCSkewedValueLists (mcSkewedValueLists) ;
    }

    // -------------------------------------------------------------
    // set the UpStatsNeeded flag
    CostScalar needStatsRowcount =
        CostPrimitives::getBasicCostFactor(HIST_ROWCOUNT_REQUIRING_STATS) ;
    if (CURRSTMT_OPTDEFAULTS->ustatAutomation()) needStatsRowcount = 1;

    CMPASSERT ( colStats_.entries() > 0 ) ;  // must have at least one histogram!
    CostScalar tableRowcount = colStats_[0]->getColStats()->getRowcount() ;

    if ( ( tableRowcount >= needStatsRowcount ) &&
            !(isSpecialObj()) )  // UpStatsNeeded flag is used for 6007 warning,
        // we do not want to give this warning for
        // smdTables, umdTables, MVUmd tables and other special tables
    {
        for ( CollIndex i = 0 ; i < colStats_.entries() ; i++ )
            colStats_[i]->getColStatsToModify()->setUpStatsNeeded (TRUE) ;
    }
    // -------------------------------------------------------------

    // ENFORCE ROWCOUNT!  When we read them in, all stats from the same
    // table should report the same rowcount.  Currently there's a
    // problem with SYSKEY histograms having a default rowcount value --
    // which brings up the following question: are SYSKEY histograms
    // ever used in histogram synthesis?
    NABoolean printNoStatsWarning;
    if (isSpecialObj() )
        printNoStatsWarning = FALSE;
    else
        printNoStatsWarning = TRUE;
    colStats_.enforceInternalConsistency(0,colStats_.entries(), printNoStatsWarning) ;

    /*  Estimate index levels based on row count, row size and key size of the index.
    Estimation will be based upon the following assumptions:

    a. There is no slack in data blocks. Slack is  the percentage in the  data block
    that is  kept empty for future inserts into  the block. For  sequential inserts
    DP2  does not leave  any slack in data blocks  but inserts in between  rows
    causes DP2 to  move following rows in the block into a new block.

    b. DP2 encodes and optimizes key storage. Basically it will keeps the portion of
    the key that is  necessary to distinguish the  blocks in next level  of index or
    data blocks. We will assume that the whole key is being used.

    c.  Data is  uniformly distributed  among all  the partitions.  Obviously it  is
    possible that one the partitions has more data thus more data blocks leading  to
    more index level than the other ones.
    */

    // compress histograms based on query predicates
    if (CmpCommon::getDefault(COMP_BOOL_18) != DF_ON)
        compressHistogramsForCurrentQuery();

    return colStats_;
}