コード例 #1
0
// ***************************************************************************
// Initialize the hash of tables in the descriptor.
// For every table in the JBBC list of the Hub as well as the extraHub, 
// insert an entry into the hash table, using the table's name as the hash key.
// ***************************************************************************
void MVDetails::initTables(const QRJBBPtr jbb, CollHeap* heap)
{
  // Map all the table names
  // Start with the Hub tables.
  const ElementPtrList& hubTables = jbb->getHub()->getJbbcList()->getList();
  for (CollIndex i=0; i<hubTables.entries(); i++)
  {
    QRElementPtr element = hubTables[i];

    // Ignore JBBCs that are not tables - they must be child-JBB references,
    // so we will get to them when looping over the JBB list.
    if (element->getElementType() == ET_Table)
    {
      const QRTablePtr table = element->downCastToQRTable();
      const NAString& name = table->getTableName();
      tableByNameHash_.insert(&name, table);
    }
  }

  // Continue with the extra-hub tables.
  const QRExtraHubPtr extraHub = jbb->getExtraHub();
  if (extraHub != NULL)
  {
    QRTableListPtr extraHubTables = extraHub->getTableList();
    if (extraHubTables != NULL)
    {
      for (CollIndex j=0; j<extraHubTables->entries(); j++)
      {
	QRTablePtr table = (*extraHubTables)[j];
	const NAString& name = table->getTableName();
	tableByNameHash_.insert(&name, table);    
      }
    }
  }
}
コード例 #2
0
// ***************************************************************************
// ***************************************************************************
void MVDetails::addEqualitySet(QRJoinPredPtr joinPredElement, 
                               NABoolean     isFromExpr, 
                               QROutputPtr   output, 
                               CollHeap*     heap)
{
  const ElementPtrList& equalitySet = joinPredElement->getEqualityList();

  for (CollIndex i=0; i<equalitySet.entries(); i++)
  {
    const QRElementPtr halfPred = equalitySet[i];

    // Now lets look at the equality set members
    // Ignore members that are not simple columns.
    if (halfPred->getElementType() != ET_Column)
      continue;

    const QRColumnPtr eqSetColumn = halfPred->getReferencedElement()->downCastToQRColumn();

    // If this JoinPred element is a column of an LOJ table,
    // skip it because it is not really equal to the others.
    const QRElementPtr tableElem = getElementForID(eqSetColumn->getTableID());
    if (tableElem->downCastToQRTable()->hasLOJParent())
      continue;

    // Compute the "ID Qualified" column name as the key.
    const NAString* idQualifiedColName = 
      calcIDQualifiedColumnName(eqSetColumn->getTableID(),  eqSetColumn->getColumnName(), heap);

    // Insert into the hash table.
    if (isFromExpr)
      outputByInputColumns_.insert(idQualifiedColName, output);
    else
      outputByColumnName_.insert(idQualifiedColName, output);
  }
} // MVDetails::addEqualitySet
コード例 #3
0
// ***************************************************************************
// Get the table element (from the JBBC list) with this name (or NULL if not found).
// This method must NOT be used to find a specific table instance, because
// with self-joins, multiple tables have the same name. 
// Use MVCandidate::getMvTableForQueryID() instead.
// ***************************************************************************
const QRTablePtr MVDetails::getTableFromName(const NAString& name)
{
  QRElementPtr table = tableByNameHash_.getFirstValue(&name);
  if (table == NULL)
    return NULL;
  
  return table->downCastToQRTable();
}
コード例 #4
0
// ***************************************************************************
// Is this column from a table that has an LOJ parent?
// ***************************************************************************
NABoolean DescriptorDetails::isColumnFromLojTable(const QRColumnPtr col)
{
  const NAString& tableID = col->getTableID();
  const QRElementPtr tableElem = getElementForID(tableID);
  assertLogAndThrow(CAT_MATCHTST_MVDETAILS, LL_MVQR_FAIL,
                    tableElem, QRLogicException, 
		    "Table not found in JBB.");
  const QRTablePtr table = tableElem->downCastToQRTable();
  return table->hasLOJParent();
}
コード例 #5
0
// ***************************************************************************
// ***************************************************************************
const NAString& DescriptorDetails::getTableNameFromColumn(QRColumnPtr colElem)
{
  static const NAString empty("");

  const NAString& tableID = colElem->getReferencedElement()->downCastToQRColumn()->getTableID();
  const QRElementPtr tableElem = getElementForID(tableID);
  if (tableElem==NULL)
  {
    // This table is in a JBB that was ommitted from the query descriptor.
    // Return an empty table name.
    return empty;
  }

  const QRTablePtr table = tableElem->downCastToQRTable();
  return table->getTableName();
}
コード例 #6
0
// ***************************************************************************
// ***************************************************************************
void JBBDetails::initBaseTables(CollHeap* heap)
{
  // Create BaseTableDetails objects for the JBB hub tables.
  const ElementPtrList& hubTables = jbbDesc_->getHub()->getJbbcList()->getList();
  for (CollIndex i=0; i<hubTables.entries(); i++)
  {
    const QRElementPtr jbbc = hubTables[i];
    if (jbbc->getElementType() != ET_Table)
      continue; // Skip reference to other JBBs.

    const QRTablePtr table = jbbc->downCastToQRTable();
    if (table->hasLOJParent())
      hasLOJs_ = TRUE;

    // Rest of the stuff only needed for MVs.
    if (!isAnMV_)
      continue;

    BaseTableDetailsPtr tableDetails = new(heap) 
      BaseTableDetails(table, TRUE, ADD_MEMCHECK_ARGS(heap));
    baseTablesByID_.insert(&tableDetails->getID(), tableDetails);
  }

  // Now do the same for the extra-hub tables.
  const QRTableListPtr extraHubTables = jbbDesc_->getExtraHub()->getTableList();
  if (extraHubTables != NULL)
  {
    for (CollIndex j=0; j<extraHubTables->entries(); j++)
    {
      const QRTablePtr table = (*extraHubTables)[j];
      if (table->hasLOJParent())
        hasLOJs_ = TRUE;

      // Rest of the stuff only needed for MVs.
      if (!isAnMV_)
        continue;

      BaseTableDetailsPtr tableDetails = new(heap) 
	BaseTableDetails(table, FALSE, ADD_MEMCHECK_ARGS(heap));
      baseTablesByID_.insert(&tableDetails->getID(), tableDetails);
    }
  }
}
コード例 #7
0
// ***************************************************************************
// Initialize the several hash tables that map output list elements:
//    outputByIDHash_	      - Using the ID of the output item as the key.
//    outputByColumnName_     - Using the "ID Qualified" column name as the key.
//    outputByExprText_	      - Using the expression text as the key.
//    outputByInputColumns_   - Using the name of expression input column as the key.
// ***************************************************************************
void MVDetails::initOutputs(const QRJBBPtr jbb, CollHeap* heap)
{
  // Match the output elements with their names.
  const QROutputListPtr outputList = jbb->getOutputList();

  assertLogAndThrow(CAT_MATCHTST_MVDETAILS, LL_MVQR_FAIL,
                    outputList != NULL, QRLogicException,
                    "Output list is null.");

  // For each output list element
  for (CollIndex i=0; i<outputList->entries(); i++)
  {
    QROutputPtr output = (*outputList)[i];
    // Set the ordinal number of the output element.
    output->setColPos(i+1);

    // Get the output item (column or expression).
    QRElementPtr outputItem = output->getOutputItem()->getReferencedElement();
    const NAString& id = outputItem->getID();
    // Insert the ID of the output item (whatever it is) into the ID hash.
    outputByIDHash_.insert(&id, output);

    // OK, now lets check what type of output item it is.
    switch (outputItem->getElementType())
    {
      case ET_Column:
      {
	// If its an output column, add it to the output column by name hash.
	const QRColumnPtr col = outputItem->downCastToQRColumn();

        const QRElementPtr tableElem = getElementForID(col->getTableID());
        NABoolean hasLOJParent = tableElem->downCastToQRTable()->hasLOJParent();

        if (!isFromJoin(col) || hasLOJParent)
        {
	  // Compute the "ID Qualified" column name as the key.
	  const NAString* idQualifiedColName = 
	    calcIDQualifiedColumnName(col->getTableID(),  col->getColumnName(), heap);

	  // Insert into the hash table.
	  outputByColumnName_.insert(idQualifiedColName, output);
        }
        else
        {
	  // If its an equality set, insert all the participating columns
	  // as pointing to the same MV output column.
          const QRJoinPredPtr jp = getJoinPred(col);
	  const QRJoinPredPtr joinPredElement = jp->downCastToQRJoinPred();
          addEqualitySet(joinPredElement, FALSE, output, heap);
        }
	break;
      }

      case ET_JoinPred:
      {
        assertLogAndThrow(CAT_MATCHTST_MVDETAILS, LL_MVQR_FAIL,
                          (outputItem->getElementType() == ET_JoinPred), QRLogicException, 
			  "Unexpected JoinPred element.");

	// If its an equality set, insert all the participating columns
	// as pointing to the same MV output column.
	const QRJoinPredPtr joinPredElement = outputItem->downCastToQRJoinPred();
        addEqualitySet(joinPredElement, FALSE, output, heap);
	break;
      }

      case ET_Expr:
      {
	// This is an expression. Insert the expression text into the expression hash.
	const QRExprPtr expr = outputItem->downCastToQRExpr();
        const NAString& exprText = expr->getExprText(); 
	outputByExprText_.insert(&exprText, output);
        QRLogger::log(CAT_MATCHTST_MVDETAILS, LL_DEBUG,
          "Adding output expression: %s.", exprText.data());

	// Also map the expressions's input columns to it.
	// This call to getInitColumns() also inits the input list using the 
	// right heap.
	const ElementPtrList& inputs = expr->getInputColumns(heap);
	if (inputs.entries() > 0)
	{
	  for (CollIndex j=0; j<inputs.entries(); j++)
	  {
            QRElementPtr inputElem = inputs[j]->getReferencedElement();
            if (inputElem->getElementType() == ET_Column)
            {
	      QRColumnPtr inputCol = inputElem->downCastToQRColumn();

	      // Compute the "ID Qualified" column name as the key.
	      const NAString* idQualifiedColName = 
	        calcIDQualifiedColumnName(inputCol->getTableID(),  inputCol->getColumnName(), heap);

	      outputByInputColumns_.insert(idQualifiedColName, output);
	    }
            else
            {
              QRJoinPredPtr inputJoinPred = inputElem->downCastToQRJoinPred();
              addEqualitySet(inputJoinPred, TRUE, output, heap);
            }
          }
	}

        // Check if this is the COUNT(*) function.
        QRExplicitExprPtr rootExpr = expr->getExprRoot();
        if (rootExpr->getElementType() == ET_Function)
        {
          QRFunctionPtr func = rootExpr->downCastToQRFunction();
          if (func->getAggregateFunc() == QRFunction::AFT_COUNTSTAR)
          {
            // Found it, now remember it for later use.
            // If a COUNT(*) equivalent function has already been found 
            // (see below) - overwrite it.
            countStar_ = output;
          }
          else if (countStar_ == NULL &&
                   func->isCountStarEquivalent(heap) )
          {
            // Well, we didn't find a COUNT(*) yet, but we found a COUNT(a)
            // and the input column is NOT NOLL, we can use it as a COUNT(*) column.
            countStar_ = output;
          }
        }
      } // end of case ET_Expr
      break;
    }  // switch on element type
  }  // for on output list elements
}  //  MVDetails::initOutputs()