LatticeIndexablePtr QRGroupLattice::elementToKey(const QRElementPtr      element, 
                                                 QRJoinSubGraphMapPtr    map,
						 DescriptorDetailsPtr    queryDetails, 
                                                 NABoolean               insertMode,
                                                 NABoolean               isRecursive)
{
  QRElementPtr elem = element->getReferencedElement();
  QRColumnPtr col = NULL;
  if (elem->getElementType() == ET_Column)
  {
    col = elem->downCastToQRColumn();
    if (queryDetails->isFromJoin(col) && !isRecursive)
    {
    // This groupby element is a join pred.
    // During insert, this loop inserts the first column.
    // During search, try each equality set element until we find one that 
    // appears in our array.
      const QRJoinPredPtr eqSet = queryDetails->getJoinPred(col);
      const ElementPtrList& equalityList = eqSet->getEqualityList();

      if (insertMode)
      {
        // Insert mode - pick the first column of the equality set.
        col = equalityList[0]->downCastToQRColumn();
      }
      else
      {
        // Search mode - pick the first equality set entry that is found in this LatticeIndex.
        for (CollIndex i=0; i<equalityList.entries(); i++)
        {
          QRElementPtr entry = equalityList[i]->getReferencedElement();
          // Call recursively for each join pred column.
          LatticeIndexablePtr entryKey = elementToKey(entry, map, queryDetails, insertMode, TRUE);
          if (entryKey == NULL)
            continue;

          if (lattice_->contains(entryKey))
          {
            // Found it in the lattice index.
            col = entry->downCastToQRColumn();
            break;
          }
        } // for ( )

        // If none of the entries was found - give up now.
        if (col == NULL)
          return NULL;

      }  // if insert mode
    }  // if JoinPred
  } // if Column

  NAString* key = NULL;
  if (col != NULL)
  {
    col = col->getReferencedElement()->downCastToQRColumn();
    const NAString& tableID = col->getTableID();
    Int32 Inx = map->getIndexForTable(tableID);
    if (Inx == -1)
    {
      assertLogAndThrow(CAT_GRP_LATTCE_INDX, LL_ERROR,
                        !insertMode, QRLogicException, 
		        "Table index not found in Insert mode (Inserting a multi-JBB MV?).");
      return NULL;
    }

    char buffer[4096+5];
    sprintf(buffer, "%d.%s", Inx, col->getColumnName().data() );

    key = new(heap_) NAString(buffer, heap_);
  }
  else
  {
    // This is an expression.
    // TBD We still do not handle expressions using columns from self-join tables.
    key = new(heap_) NAString(element->getSortName(), heap_);
  }

  // The reverseKeyHash should always use the most recent MV inserted.
  if (insertMode)
  {
    reverseKeyHash_.remove(key);
    reverseKeyHash_.insert(key, element);
  }
  return key;
}