コード例 #1
0
CostScalar AppliedStatMan::computeJoinReduction(
          const CANodeIdSet & leftChildren,
          const CANodeIdSet & rightChildren)
{
  CostScalar result = 0;

  // get stats for left
  EstLogPropSharedPtr leftCard =
    getStatsForCANodeIdSet(leftChildren);

  // get stats for right
  EstLogPropSharedPtr rightCard =
    getStatsForCANodeIdSet(rightChildren);

  CANodeIdSet jbbcsJoinedToRight;
  CANodeIdSet allPredecessors;
  CANodeIdSet allSuccessors;

  for( CANodeId rChild = rightChildren.init();
       rightChildren.next(rChild);
       rightChildren.advance(rChild))
  {
    JBBC * rChildJBBC = rChild.getNodeAnalysis()->getJBBC();
    jbbcsJoinedToRight += rChildJBBC->getJoinedJBBCs();
    jbbcsJoinedToRight += rChildJBBC->getPredecessorJBBCs();
    allPredecessors    += rChildJBBC->getPredecessorJBBCs();
    jbbcsJoinedToRight += rChildJBBC->getSuccessorJBBCs();
    allSuccessors      += rChildJBBC->getSuccessorJBBCs();
  }

  CANodeIdSet dependencyCausingNodesFromLeft = leftChildren;
  dependencyCausingNodesFromLeft.intersectSet(allPredecessors + allSuccessors);

  CANodeIdSet leftNodesJoinedToRight = leftChildren;
  leftNodesJoinedToRight.intersectSet(jbbcsJoinedToRight);

  if(!leftNodesJoinedToRight.entries())
  {
    result = rightCard->getResultCardinality();
    return result;
  }

  CANodeIdSet leftSetPredecessors;
  CANodeIdSet newNodes = leftNodesJoinedToRight;
  CANodeIdSet nodesConsidered;

  while(newNodes.entries())
  {
    for( CANodeId lChild = newNodes.init();
         newNodes.next(lChild);
         newNodes.advance(lChild))
    {
      JBBC * lChildJBBC = lChild.getNodeAnalysis()->getJBBC();
      leftSetPredecessors += lChildJBBC->getPredecessorJBBCs();
      nodesConsidered += lChild;
    }

    leftSetPredecessors.intersectSet(leftChildren);
    newNodes = leftSetPredecessors;
    newNodes -= nodesConsidered;
  }

  leftNodesJoinedToRight += leftSetPredecessors;

  // for a JBBSubset to be legal it has to have at least one
  // independent jbbc i.e. a jbbcs connect via a innerNonSemiNonTsjJoin
  // Assumption: leftChildren represents a legal JBBSubset
  CANodeIdSet independentJBBCsInLeftNodesJoinedToRight =
    QueryAnalysis::Instance()->getInnerNonSemiNonTSJJBBCs();

  independentJBBCsInLeftNodesJoinedToRight.intersectSet(leftNodesJoinedToRight);
  
  if(!independentJBBCsInLeftNodesJoinedToRight.entries())
    leftNodesJoinedToRight += 
      leftChildren.jbbcsToJBBSubset()->
        getJBBSubsetAnalysis()->
          getLargestIndependentNode();

  EstLogPropSharedPtr cardLeftNodesJoinedToRight =
    getStatsForCANodeIdSet(leftNodesJoinedToRight);

  // All nodes connected via a join
  CANodeIdSet connectedNodes(leftNodesJoinedToRight);
  connectedNodes += rightChildren;

  EstLogPropSharedPtr cardConnectedNodes =
    joinJBBChildren(leftNodesJoinedToRight,rightChildren);

  result = cardConnectedNodes->getResultCardinality() /
             cardLeftNodesJoinedToRight->getResultCardinality();

  return result;
}
コード例 #2
0
// This method forms the join expression for join on JBBC specified by jbbcId
// inputEstLogProp should not be cacheable
Join * AppliedStatMan::formJoinExprForJoinOnJBBC(
          CANodeIdSet jbbSubset,
          CANodeId    jbbcId,
          const ValueIdSet * jbbcLocalPreds,
          const ValueIdSet * joinPreds,
          const EstLogPropSharedPtr& inputEstLogProp,
          const NABoolean cacheable)
{

  NABoolean origInputIsCacheable = inputEstLogProp->isCacheable();
  if(origInputIsCacheable)
  {
    inputEstLogProp->setCacheableFlag(FALSE);
    CCMPASSERT("Expecting Non Cacheable Input");
  }
  
  RelExpr * jbbcExpr = getExprForCANodeId(jbbcId, inputEstLogProp, jbbcLocalPreds);
  jbbcExpr->getGroupAttr()->outputLogProp(inputEstLogProp);
  RelExpr * jbbSubsetExpr = jbbSubset.jbbcsToJBBSubset()->getPreferredJoin();
  
  if(!jbbSubsetExpr)
    if(jbbSubset.entries()==1)
      if(!inputEstLogProp->isCacheable())
      {
        inputEstLogProp->setCacheableFlag(TRUE);
        jbbSubsetExpr = getExprForCANodeId(jbbSubset.getFirst(), inputEstLogProp);
        inputEstLogProp->setCacheableFlag(FALSE);
      }
      else
        jbbSubsetExpr = getExprForCANodeId(jbbSubset.getFirst(), inputEstLogProp);
    else
    {
      CCMPASSERT("No Subset expression, need at least one entry in set");
    }


  RelExpr * leftChildExpr = jbbSubsetExpr;
  RelExpr * rightChildExpr = jbbcExpr;
  
  GroupAttributes * galeft = jbbSubsetExpr->getGroupAttr();
  GroupAttributes * garight = jbbcExpr->getGroupAttr();
  
  // xxx

  JBBC * jbbc = jbbcId.getNodeAnalysis()->getJBBC();
  Join * jbbcParentJoin = jbbc->getOriginalParentJoin();
  ValueIdSet leftOuterJoinFilterPreds;


  Join * joinExpr = NULL;
  
  if(jbbcParentJoin)
  {
      if(jbbcParentJoin->isSemiJoin())
        joinExpr = new STMTHEAP Join(leftChildExpr, rightChildExpr, REL_SEMIJOIN, NULL);

      if(jbbcParentJoin->isAntiSemiJoin())
        joinExpr = new STMTHEAP Join(leftChildExpr, rightChildExpr, REL_ANTI_SEMIJOIN, NULL);

      if(jbbcParentJoin->isLeftJoin())
      {
        joinExpr = new STMTHEAP Join(leftChildExpr, rightChildExpr, REL_LEFT_JOIN, NULL);
        leftOuterJoinFilterPreds += jbbc->getLeftJoinFilterPreds();
      }

      if(joinExpr)
      {
        joinExpr->setJoinPred(jbbc->getPredsWithPredecessors());

        joinExpr->nullInstantiatedOutput().insert(jbbc->nullInstantiatedOutput());
      }
  }

  if(!joinExpr)
  {
    // now form a JoinExpr with these left and right children.
    joinExpr = new STMTHEAP Join(leftChildExpr, rightChildExpr, REL_JOIN, NULL);
  }

  ValueIdSet selPredsAndLOJFilter = leftOuterJoinFilterPreds;
  selPredsAndLOJFilter += (*joinPreds);
  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;

  requiredOutputs.addSet(getPotentialOutputs(jbbSubset));

  requiredOutputs.addSet(getPotentialOutputs(jbbcId));

  gaJoin->setCharacteristicOutputs(requiredOutputs);

  // set JBBSubset for this group, if all estLogProps are cacheable.
  // Else JBBSubset is NULL

  CANodeIdSet combinedSet = jbbSubset;
  combinedSet += jbbcId;
  
  if (cacheable)
    gaJoin->getGroupAnalysis()->setLocalJBBView(combinedSet.jbbcsToJBBSubset());

  gaJoin->setMinChildEstRowCount(MINOF(garight->getMinChildEstRowCount(), galeft->getMinChildEstRowCount() ) );

  // 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);
  joinExpr->synthLogProp();
  inputEstLogProp->setCacheableFlag(origInputIsCacheable);
  return joinExpr;
} // AppliedStatMan::formJoinExprForJoinOnJBBC