コード例 #1
0
//*****************************************************************************
// Add a table to the Self-Join analysis.
// This method, together with doneAddingTables(), implement a state machine
// with the following states:
//   ST_START:    The start state. No open segments.
//   ST_SINGLE:   Got the first table of a new segment, don't know segment type yet.
//   ST_UNIQUE:   Last two tables were different.
//   ST_SELFJOIN: Last two tables were the same.
//   ST_END:      We are done.
// The full state machine diagram is in the MVQR IS document.
//*****************************************************************************
void SelfJoinHandler::addTable(JoinGraphTablePtr table)
{
  const NAString& newTable = table->getName(); 
  // This is the current table index.
  UInt32 currentIndex = table->getTempNumber();
  if (currentIndex == -1)
  {
    // This subgraph generation was not yet started, 
    // This must be the initial self-join check.
    currentIndex = table->getOrdinalNumber();
  }

  // Is this table the same as the last one?
  // Skip the string comparison if the table is unique in the full join graph.
  NABoolean isDifferent = !table->isSelfJoinTable() || newTable != *lastTable_;

  // Which state in the state machine are we in?
  switch (state_)
  {
    case ST_START:
      segmentStart_ = currentIndex;
      state_ = ST_SINGLE;
      break;

    case ST_SINGLE:
      if (isDifferent)
        state_ = ST_UNIQUE;
      else
        state_ = ST_SELFJOIN;
      break;

    case ST_SELFJOIN:
      if (isDifferent)
      {
        // We have an open selfjoin segment and got a different table.
        // The selfjoin segment ends with the previous table, and the next
        // segment (which can be either type) starts with this table.
        addSegment(SelfJoinSegment::SELF_JOIN_SEGMENT);
        segmentStart_ = currentIndex;
        state_ = ST_SINGLE;
      }
      else
      {
        // do nothing.
      }
      break;

    case ST_UNIQUE:
      if (isDifferent)
      {
        // do nothing.
      }
      else
      {
        // OK, we have an open unique segment, and the new table is the same 
        // as the last one. So actually, the open unique segment ended with the
        // table before the prevous one, and the new self-join segment started 
        // with the previous table.
        segmentEnd_--;
        addSegment(SelfJoinSegment::UNIQUE_TABLE_SEGMENT);
        segmentStart_ = currentIndex-1;
        state_ = ST_SELFJOIN;
      }
      break;

    case ST_END:
      assertLogAndThrow(CAT_MVMEMO_JOINGRAPH, LL_MVQR_FAIL,
                        FALSE, QRLogicException, 
		        "Adding a table to SelfJoinHandler in ST_END state.");
      break;
  }

  lastTable_ = &table->getName();
  segmentEnd_ = currentIndex;
}
コード例 #2
0
QRJbbSubsetPtr MVCandidatesForJBBSubset::generateDescriptor(CollHeap* heap)
{
  // No candidates - no work.
  if (candidateList_.entries() == 0)
    return NULL;

  // Construct the new QRJbbSubset object.
  QRJbbSubsetPtr resultDesc = new(heap) QRJbbSubset(ADD_MEMCHECK_ARGS(heap));
  resultDesc->setGroupBy(hasGroupBy_);
  if (hasGroupBy_)
  {
    // Add a reference to the query NodeID of the GroupBy node.
    const NAString& groupbyID = 
      getJbbCandidates()->getQueryJbb()->getGroupBy()->getID();
    resultDesc->setRef(groupbyID);
  }

  // For each table included in the subgraph
  QRJoinSubGraphPtr   subGraph = querySubGraphMap_->getSubGraph();
  for(subGraph->reset(); subGraph->hasNext(); subGraph->advance())
  {
    JoinGraphTablePtr table = subGraph->getCurrent();

    // Add it to the JBBSubset descriptor.
    QRTablePtr tableDesc = new(heap) QRTable(heap);
    tableDesc->setTableName(table->getName());
    tableDesc->setRef(table->getID());
    resultDesc->addTable(tableDesc);
  }

  // If candidates are disqualified during the loop itself,
  // Don't remove them from the list.
  isLoopingOnCandidates_ = TRUE;

  // Now add the MVCandidates.
  CollIndex maxEntries = candidateList_.entries();
  for (CollIndex i=0; i<maxEntries; i++)
  {
    MVCandidatePtr candidate = candidateList_[i];
    if (candidate == NULL)
    {
      // The candidate was disqualified.
      continue;
    }

    QRCandidatePtr candidateXml;
    try
      {
        candidateXml = candidate->generateDescriptor();
      }
    catch (...)
      {
        candidate->logMVWasDisqualified("an exception was thrown.");
        candidate->disqualify();  // Propagate the Info element to the result descriptor.

        candidateXml = NULL;
      }

    if (candidateXml == NULL)
    {
      // The candidate was disqualified when generating the descriptor.
      continue;
    }
    resultDesc->addCandidate(candidateXml);
  }

  if (resultDesc->getCandidateList()->entries() == 0)
  {
    // None of the candidates survived the result descriptor generation.
    deletePtr(resultDesc);
    return NULL;
  }

  return resultDesc;
}  // MVCandidatesForJBBSubset::generateDescriptor()