// Get the scan expression for given jbbc // if jbbc is not a scan or predIdSet is NULL // then the original JBBC expression is returned RelExpr * AppliedStatMan::getExprForCANodeId( CANodeId jbbc, const EstLogPropSharedPtr &inLP, const ValueIdSet * predIdSet) { RelExpr * jbbcExpr = NULL; // should not happen but a check just in case CCMPASSERT(jbbc.getNodeAnalysis()); //if specified by the user apply those predicates, // else apply predicates in the original expr NodeAnalysis * jbbcNode = jbbc.getNodeAnalysis(); TableAnalysis * tableAnalysis = jbbcNode->getTableAnalysis(); if (tableAnalysis && predIdSet) { TableDesc * tableDesc = tableAnalysis->getTableDesc(); const CorrName& name = tableDesc->getNATable()->getTableName(); Scan *scanExpr = new STMTHEAP Scan(name, tableDesc, REL_SCAN, STMTHEAP); scanExpr->setBaseCardinality(MIN_ONE (tableDesc->getNATable()->getEstRowCount())) ; GroupAttributes * gaExpr = new STMTHEAP GroupAttributes(); scanExpr->setSelectionPredicates(*predIdSet); ValueIdSet requiredOutputs = jbbc.getNodeAnalysis()->\ getOriginalExpr()->getGroupAttr()->getCharacteristicOutputs(); gaExpr->setCharacteristicOutputs(requiredOutputs); ValueIdSet requiredInputs = jbbc.getNodeAnalysis()->\ getOriginalExpr()->getGroupAttr()->getCharacteristicInputs(); gaExpr->setCharacteristicInputs(requiredInputs); scanExpr->setGroupAttr(gaExpr); gaExpr->setLogExprForSynthesis(scanExpr); scanExpr->synthLogProp(); jbbcExpr = scanExpr; } else { NodeAnalysis * nodeAnalysis = jbbc.getNodeAnalysis(); RelExpr * relExpr = nodeAnalysis->getModifiedExpr(); if (relExpr == NULL) relExpr = nodeAnalysis->getOriginalExpr(); jbbcExpr = relExpr; } return jbbcExpr; } // getExprForCANodeId
// This method forms the join expression with the estLogProps. Join * AppliedStatMan::formJoinExprWithEstLogProps( const EstLogPropSharedPtr& leftEstLogProp, const EstLogPropSharedPtr& rightEstLogProp, const EstLogPropSharedPtr& inputEstLogProp, const ValueIdSet * setOfPredicates, const NABoolean cacheable, JBBSubset * combinedJBBSubset) { // Form a join expression with these estLogProps. // form the left child. Since the estLogProps of the left and the // right children exist, these can be treated as Scan expressions Scan * leftChildExpr = new STMTHEAP Scan(); GroupAttributes * galeft = new STMTHEAP GroupAttributes(); // set GroupAttr of the leftChild galeft->inputLogPropList().insert(inputEstLogProp); galeft->outputLogPropList().insert(leftEstLogProp); CANodeIdSet * leftNodeSet = leftEstLogProp->getNodeSet(); CANodeId nodeId; if (leftNodeSet) { if (leftNodeSet->entries() == 1) { nodeId = leftNodeSet->getFirst(); if(nodeId.getNodeAnalysis()->getTableAnalysis()) leftChildExpr->setTableAttributes(nodeId); } CostScalar minEstCard = leftNodeSet->getMinChildEstRowCount(); galeft->setMinChildEstRowCount(minEstCard); } leftChildExpr->setGroupAttr(galeft); galeft->setLogExprForSynthesis(leftChildExpr); // form the right child and set its groupAttr Scan * rightChildExpr = new STMTHEAP Scan(); GroupAttributes * garight = new STMTHEAP GroupAttributes(); garight->inputLogPropList().insert(inputEstLogProp); garight->outputLogPropList().insert(rightEstLogProp); CANodeIdSet * rightNodeSet = rightEstLogProp->getNodeSet(); // xxx JBBC * singleRightChild = NULL; Join * singleRightChildParentJoin = NULL; ValueIdSet leftOuterJoinFilterPreds; if (rightNodeSet) { if (rightNodeSet->entries() == 1) { nodeId = rightNodeSet->getFirst(); if(nodeId.getNodeAnalysis()->getTableAnalysis()) rightChildExpr->setTableAttributes(nodeId); if(nodeId.getNodeAnalysis()->getJBBC()) { singleRightChild = nodeId.getNodeAnalysis()->getJBBC(); if(singleRightChild) singleRightChildParentJoin = singleRightChild->getOriginalParentJoin(); } } CostScalar minEstCard = rightNodeSet->getMinChildEstRowCount(); garight->setMinChildEstRowCount(minEstCard); } rightChildExpr->setGroupAttr(garight); garight->setLogExprForSynthesis(rightChildExpr); Join * joinExpr = NULL; if(singleRightChild && singleRightChildParentJoin) { if(singleRightChildParentJoin->isSemiJoin()) joinExpr = new STMTHEAP Join(leftChildExpr, rightChildExpr, REL_SEMIJOIN, NULL); if(singleRightChildParentJoin->isAntiSemiJoin()) joinExpr = new STMTHEAP Join(leftChildExpr, rightChildExpr, REL_ANTI_SEMIJOIN, NULL); if(singleRightChildParentJoin->isLeftJoin()) { joinExpr = new STMTHEAP Join(leftChildExpr, rightChildExpr, REL_LEFT_JOIN, NULL); leftOuterJoinFilterPreds += singleRightChild->getLeftJoinFilterPreds(); } if(joinExpr) { joinExpr->setJoinPred(singleRightChild->getPredsWithPredecessors()); joinExpr->nullInstantiatedOutput().insert(singleRightChild-> nullInstantiatedOutput()); } } if(!joinExpr) { // now form a JoinExpr with these left and right children. joinExpr = new STMTHEAP Join(leftChildExpr, // left child rightChildExpr, // right child REL_JOIN, // join type NULL); // join predicates } ValueIdSet selPredsAndLOJFilter = leftOuterJoinFilterPreds; selPredsAndLOJFilter += (*setOfPredicates); joinExpr->setSelectionPredicates(selPredsAndLOJFilter); // set groupAttr of this Join expression GroupAttributes * gaJoin = new STMTHEAP GroupAttributes(); // set required outputs of Join as sum of characteristic // outputs of the left and the right children ValueIdSet requiredOutputs; if (leftNodeSet) requiredOutputs.addSet(getPotentialOutputs(*(leftNodeSet))); if (rightNodeSet) requiredOutputs.addSet(getPotentialOutputs(*(rightNodeSet))); gaJoin->setCharacteristicOutputs(requiredOutputs); // set JBBSubset for this group, if all estLogProps are cacheable. // Else JBBSubset is NULL if (cacheable) gaJoin->getGroupAnalysis()->setLocalJBBView(combinedJBBSubset); gaJoin->setMinChildEstRowCount(MINOF(garight->getMinChildEstRowCount(), galeft->getMinChildEstRowCount() ) ); joinExpr->setGroupAttr(gaJoin); // if there are some probes coming into the join // then join type = tsj. if ((inputEstLogProp->getResultCardinality() > 1) || (inputEstLogProp->getColStats().entries() > 1)) { if (cacheable) { CANodeIdSet inputNodeSet = *(inputEstLogProp->getNodeSet()); gaJoin->setCharacteristicInputs(getPotentialOutputs(inputNodeSet)); } } joinExpr->setGroupAttr(gaJoin); gaJoin->setLogExprForSynthesis(joinExpr); return joinExpr; } // AppliedStatMan::formJoinExprWithEstLogProps
EstLogPropSharedPtr AppliedStatMan::getStatsForCANodeId( CANodeId jbbc, const EstLogPropSharedPtr &inLP, const ValueIdSet * predIdSet) { EstLogPropSharedPtr inputLP = inLP; if(inputLP == (*GLOBAL_EMPTY_INPUT_LOGPROP)) inputLP = jbbc.getJBBInput(); EstLogPropSharedPtr outputEstLogProp = NULL; // 1. Try to find Logical Properties from cache if cacheable. // The estimate Logical Properties can be cacheable if all local // predicates are to be applied and if inNodeSet is provided, // or the inLP are cacheable if ((inputLP->isCacheable()) && (predIdSet == NULL) ) { CANodeIdSet combinedSet = jbbc; // get the nodeIdSet of the outer child, if not already given. This // along with the present jbbc is used as a key in the cache CANodeIdSet * inputNodeSet; inputNodeSet = inputLP->getNodeSet(); // if inLP are cacheable these should have a nodeSet attached CCMPASSERT(inputNodeSet != NULL); if (inputNodeSet) { combinedSet.insert(*inputNodeSet); // if estLogProp for all local predicates is required, // then it might already exist in the cache outputEstLogProp = getCachedStatistics(&combinedSet); } } if (outputEstLogProp == NULL) { // 2. properties do not exist in the cache, so synthesize them. //if specified by the user apply those predicates, // else apply predicates in the original expr NodeAnalysis * jbbcNode = jbbc.getNodeAnalysis(); TableAnalysis * tableAnalysis = jbbcNode->getTableAnalysis(); if (tableAnalysis && predIdSet) { TableDesc * tableDesc = tableAnalysis->getTableDesc(); const QualifiedName& qualName = tableDesc->getNATable()->getTableName(); CorrName name(qualName, STMTHEAP); Scan *scanExpr = new STMTHEAP Scan(name, tableDesc, REL_SCAN, STMTHEAP); Cardinality rc = tableDesc->getNATable()->getEstRowCount(); const CardinalityHint* cardHint = tableDesc->getCardinalityHint(); if ( cardHint ) rc = (cardHint->getScanCardinality()).getValue(); if ( !cardHint && tableDesc->getNATable()->isHbaseTable() ) { NATable* nt = (NATable*)(tableDesc->getNATable()); StatsList* statsList = nt->getColStats(); if ( statsList && statsList->entries() > 0 ) { ColStatsSharedPtr cStatsPtr = statsList->getSingleColumnColStats(0); if ( cStatsPtr ) rc = (cStatsPtr->getRowcount()).getValue(); } } scanExpr->setBaseCardinality(MIN_ONE (rc)); GroupAttributes * gaExpr = new STMTHEAP GroupAttributes(); scanExpr->setSelectionPredicates(*predIdSet); ValueIdSet requiredOutputs = jbbc.getNodeAnalysis()->\ getOriginalExpr()->getGroupAttr()->getCharacteristicOutputs(); gaExpr->setCharacteristicOutputs(requiredOutputs); scanExpr->setGroupAttr(gaExpr); gaExpr->setLogExprForSynthesis(scanExpr); EstLogPropSharedPtr nonCacheableInLP(new (HISTHEAP) EstLogProp (*inputLP)); nonCacheableInLP->setCacheableFlag(FALSE); scanExpr->synthLogProp(); outputEstLogProp = scanExpr->getGroupAttr()->outputLogProp(nonCacheableInLP); } else { NodeAnalysis * nodeAnalysis = jbbc.getNodeAnalysis(); RelExpr * relExpr = nodeAnalysis->getModifiedExpr(); if (relExpr == NULL) relExpr = nodeAnalysis->getOriginalExpr(); // synthesize and cache estLogProp for the given inLP. outputEstLogProp = relExpr->getGroupAttr()->outputLogProp(inputLP); } } return outputEstLogProp; } // getStatsForCANodeId