Exemplo n.º 1
0
// compress the histograms based on query predicates on this table
void TableDesc::compressHistogramsForCurrentQuery()
{

    // if there are some column statistics
    if ((colStats_.entries() != 0) &&
            (table_) &&
            (table_->getExtendedQualName().getSpecialType() == ExtendedQualName::NORMAL_TABLE))
    {   // if 1
        // check if query analysis info is available
        if(QueryAnalysis::Instance()->isAnalysisON())
        {   // if 2
            // get a handle to the query analysis
            QueryAnalysis* queryAnalysis = QueryAnalysis::Instance();

            // get a handle to the table analysis
            const TableAnalysis * tableAnalysis = getTableAnalysis();

            if(!tableAnalysis)
                return;

            // iterate over statistics for each column
            for(CollIndex i = 0; i < colStats_.entries(); i++)
            {   // for 1
                // Get a handle to the column's statistics descriptor
                ColStatDescSharedPtr columnStatDesc = colStats_[i];

                // get a handle to the ColStats
                ColStatsSharedPtr colStats = columnStatDesc->getColStats();

                // if this is a single column, as opposed to a multicolumn
                if(colStats->getStatColumns().entries() == 1)
                {   // if 3
                    // get column's value id
                    const ValueId columnId = columnStatDesc->getColumn();

                    // get column analysis
                    ColAnalysis* colAnalysis = queryAnalysis->getColAnalysis(columnId);

                    if(!colAnalysis) continue;

                    ValueIdSet predicatesOnColumn =
                        colAnalysis->getReferencingPreds();

                    // we can compress this column's histogram if there
                    // is a equality predicate against a constant

                    ItemExpr *constant = NULL;

                    NABoolean colHasEqualityAgainstConst =
                        colAnalysis->getConstValue(constant);

                    // if a equality predicate with a constant was found
                    // i.e. predicate of the form col = 5
                    if (colHasEqualityAgainstConst)
                    {   // if 4
                        if (constant)
                            // compress the histogram
                            columnStatDesc->compressColStatsForQueryPreds(constant,constant);
                    } // if 4
                    else { // else 4

                        // since there is no equality predicates we might still
                        // be able to compress the column's histogram based on
                        // range predicates against a constant. Following are
                        // examples of such predicates
                        // * col > 1 <-- predicate defines a lower bound
                        // * col < 3 <-- predicate defines a upper bound
                        // * col >1 and col < 30 <-- window predicate, define both bounds
                        ItemExpr * lowerBound = NULL;
                        ItemExpr * upperBound = NULL;

                        // Extract predicates from range spec and add it to the
                        // original predicate set otherwise isARangePredicate() will
                        // return FALSE, so histgram compression won't happen.
                        ValueIdSet rangeSpecPred(predicatesOnColumn);
                        for (ValueId predId= rangeSpecPred.init();
                                rangeSpecPred.next(predId);
                                rangeSpecPred.advance(predId))
                        {
                            ItemExpr * pred = predId.getItemExpr();
                            if ( pred->getOperatorType() == ITM_RANGE_SPEC_FUNC )
                            {
                                ValueIdSet vs;
                                ((RangeSpecRef *)pred)->getValueIdSetForReconsItemExpr(vs);
                                // remove rangespec vid from the original set
                                predicatesOnColumn.remove(predId);
                                // add preds extracted from rangespec to the original set
                                predicatesOnColumn.insert(vs);
                            }
                        }

                        // in the following loop we iterate over all the predicates
                        // on this column. If there is a range predicate e.g. a > 2
                        // or a < 3, then we use that to define upper and lower bounds.
                        // Given predicate a > 2, we get a lower bound of 2.
                        // Given predicate a < 3, we get a upper bound of 3.
                        // The bound are then passed down to the histogram
                        // compression methods.

                        // iterate over predicates to see if any of them is a range
                        // predicate e.g. a > 2
                        for (ValueId predId= predicatesOnColumn.init();
                                predicatesOnColumn.next(predId);
                                predicatesOnColumn.advance(predId))
                        {   // for 2
                            // check if this predicate is a range predicate
                            ItemExpr * predicateOnColumn = predId.getItemExpr();
                            if (predicateOnColumn->isARangePredicate())
                            {   // if 5

                                // if a predicate is a range predicate we need to find out more
                                // information regarding the predicate to see if it can be used
                                // to compress the columns histogram. We look for the following:
                                // * The predicate is against a constant e.g. a > 3 and not against
                                //   another column e.g. a > b
                                // Also give a predicate we need to find out what side is the column
                                // and what side is the constant. Normally people write a range predicate
                                // as a > 3, but the same could be written as 3 < a.
                                // Also either on of the operands of the range predicate might be
                                // a VEG, if so then we need to dig into the VEG to see where is
                                // the constant and where is the column.

                                // check the right and left children of this predicate to
                                // see if one of them is a constant
                                ItemExpr * leftChildItemExpr = (ItemExpr *) predicateOnColumn->getChild(0);
                                ItemExpr * rightChildItemExpr = (ItemExpr *) predicateOnColumn->getChild(1);

                                // by default assume the literal is at right i.e. predicate of
                                // the form a > 2
                                NABoolean columnAtRight = FALSE;

                                // check if right child of predicate is a VEG
                                if ( rightChildItemExpr->getOperatorType() == ITM_VEG_REFERENCE)
                                {   // if 6
                                    // if child is a VEG
                                    VEGReference * rightChildVEG = (VEGReference *) rightChildItemExpr;

                                    // check if the VEG contains the current column
                                    // if it does contain the current column then
                                    // the predicate has the column on right and potentially
                                    // a constant on the left.
                                    if(rightChildVEG->getVEG()->getAllValues().contains(columnId))
                                    {   // if 7
                                        // column is at right i.e. predicate is of the form
                                        // 2 < a
                                        columnAtRight = TRUE;
                                    } // if 7
                                } // if 6
                                else { // else 6
                                    // child is not a VEG
                                    if ( columnId == rightChildItemExpr->getValueId() )
                                    {   // if 8
                                        // literals are at left i.e. predicate is of the form
                                        // (1,2) < (a, b)
                                        columnAtRight = TRUE;
                                    } // if 8
                                } // else 6

                                ItemExpr * potentialConstantExpr = NULL;

                                // check if the range predicate is against a constant
                                if (columnAtRight)
                                {   // if 9
                                    // the left child is potentially a constant
                                    potentialConstantExpr = leftChildItemExpr;
                                } // if 9
                                else { // else 9
                                    // the right child is potentially a constant
                                    potentialConstantExpr = rightChildItemExpr;
                                } // else 9

                                // initialize constant to NULL before
                                // looking for next constant
                                constant = NULL;

                                // check if potentialConstantExpr contains a constant.
                                // we need to see if this range predicate is a predicate
                                // against a constant e.g col > 1 and not a predicate
                                // against another column e.g. col > anothercol

                                // if the expression is a VEG
                                if ( potentialConstantExpr->getOperatorType() == ITM_VEG_REFERENCE)
                                {   // if 10

                                    // expression is a VEG, dig into the VEG to
                                    // get see if it contains a constant
                                    VEGReference * potentialConstantExprVEG =
                                        (VEGReference *) potentialConstantExpr;

                                    potentialConstantExprVEG->getVEG()->\
                                    getAllValues().referencesAConstValue(&constant);
                                } // if 10
                                else { // else 10

                                    // express is not a VEG, it is a constant
                                    if ( potentialConstantExpr->getOperatorType() == ITM_CONSTANT )
                                        constant = potentialConstantExpr;
                                } // else 10

                                // if predicate involves a constant, does the constant imply
                                // a upper bound or lower bound
                                if (constant)
                                {   // if 11
                                    // if range predicate has column at right e.g. 3 > a
                                    if (columnAtRight)
                                    {   // if 12
                                        if ( predicateOnColumn->getOperatorType() == ITM_GREATER ||
                                                predicateOnColumn->getOperatorType() == ITM_GREATER_EQ)
                                        {   // if 13
                                            if (!upperBound)
                                                upperBound = constant;
                                        } // if 13
                                        else
                                        {   // else 13
                                            if (!lowerBound)
                                                lowerBound = constant;
                                        } // else 13
                                    } // if 12
                                    else { // else 12
                                        // range predicate has column at left e.g. a < 3
                                        if ( predicateOnColumn->getOperatorType() == ITM_LESS ||
                                                predicateOnColumn->getOperatorType() == ITM_LESS_EQ)
                                        {   // if 14
                                            if (!upperBound)
                                                upperBound = constant;
                                        } // if 14
                                        else
                                        {   // else 14
                                            if (!lowerBound)
                                                lowerBound = constant;
                                        } // else 14
                                    } // else 12
                                } // if 11
                            } // if 5
                        } // for 2

                        // if we found a upper bound or a lower bound
                        if (lowerBound || upperBound)
                        {
                            // compress the histogram based on range predicates
                            columnStatDesc->compressColStatsForQueryPreds(lowerBound, upperBound);
                        }
                    } // else 4
                } // if 3
            } // for 1
        } // if 2
    } // if 1
    // All histograms compressed. Set the histCompressed flag to TRUE
    histsCompressed(TRUE);
}