// 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_; }