const BaseTableDetailsPtr MVCandidate::getQueryTableForMvID(const NAString& id, NABoolean assertOnFailure) { QRJoinSubGraphMapPtr mvMap = getMvSubGraphMap(); if (!mvMap->contains(id)) { if (assertOnFailure) { assertLogAndThrow(CAT_MVCAND, LL_MVQR_FAIL, FALSE, QRLogicException, "Matching Query table not found in JoinGraphMap."); } return NULL; } Int32 hashKeyIndex = mvMap->getIndexForTable(id); if (hashKeyIndex == -1) { assertLogAndThrow(CAT_MVCAND, LL_MVQR_FAIL, assertOnFailure, QRLogicException, "Matching Query table not found in JoinGraphMap."); return NULL; } const JoinGraphTablePtr queryTable = getQuerySubGraphMap()->getTableForIndex(hashKeyIndex); if (queryTable == NULL) { assertLogAndThrow(CAT_MVCAND, LL_MVQR_FAIL, assertOnFailure, QRLogicException, "Matching Query table not found in JoinGraphMap."); return NULL; } return queryTable->getBaseTable(); }
void QRGroupLattice::remove(QRJoinSubGraphMapPtr map) { QRTRACER("QRGroupLattice::remove()"); const QRJBBPtr jbb = map->getMVDetails()->getJbbDetails()->getJbbDescriptor(); LatticeKeyList keyList; NABoolean ok = getGroupingLatticeKeys(keyList, map, map->getMVDetails(), jbb, FALSE, TRUE); assertLogAndThrow(CAT_GRP_LATTCE_INDX, LL_ERROR, ok, QRLogicException, "getGroupingLatticeKeys() failed in Insert mode (Inserting a multi-JBB MV?)."); lattice_->removeMV(keyList, map->getMVDetails()); dumpLattice("2"); }
void MVCandidatesForJBBSubset::setSubGraphMap(QRJoinSubGraphMapPtr querySubGraphMap) { querySubGraphMap_ = querySubGraphMap; // Mark that this subGraph is being used for rewrite instructions, so that // it will not be deleted when the HubIterator is deleted. querySubGraphMap->getSubGraph()->setStillUsed(TRUE); }
MVPair::MVPair(const QRJoinSubGraphMapPtr firstMV, const QRJoinSubGraphMapPtr otherMV, ADD_MEMCHECK_ARGS_DECL(CollHeap* heap)) : MVCandidate(otherMV->getMVDetails(), firstMV->getMVDetails(), firstMV->getMVDetails()->getJbbDetails()->getJbbDescriptor(), NULL, ADD_MEMCHECK_ARGS_PASS(heap)) ,querySubGraphMap_(firstMV) ,mvSubGraphMap_(otherMV) ,rangePredList_(heap) ,residualPredList_(heap) { QRRangePredListPtr rangePredList = getMvDetails()->getJbbDetails()->getJbbDescriptor()->getHub()->getRangePredList(); if (rangePredList) rangePredList_.insert(rangePredList->getList()); QRResidualPredListPtr residualPredList = getMvDetails()->getJbbDetails()->getJbbDescriptor()->getHub()->getResidualPredList(); if (residualPredList) residualPredList_.insert(residualPredList->getList()); }
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; }
//***************************************************************************** //***************************************************************************** NABoolean MVCandidate::CheckAnExtraHubTable(const NAString* tableID, QRJoinSubGraphMapPtr mvSubGraphMap, QRJoinSubGraphMapPtr querySubGraphMap, NABoolean& extraHubTableWasAdded) { QRJoinSubGraphPtr mvSubGraph = mvSubGraphMap->getSubGraph(); QRJoinSubGraphPtr querySubGraph = querySubGraphMap->getSubGraph(); const QRTablePtr queryTableElement = getQueryDetails()->getElementForID(*tableID)->downCastToQRTable(); const JoinGraphTablePtr queryGraphTable = querySubGraph->getParentGraph()->getTableByID(queryTableElement->getID()); // If this extra-hub table is not directly connected to the rest of // the subgraph, skip it for now. if (queryGraphTable->isConnectedTo(querySubGraph) == FALSE) { // Add additional needed extra-hub tables here... return TRUE; } // Find the corresponding MV table const QRTablePtr mvTableElement = getMvDetails()->getTableFromName(queryTableElement->getTableName()); const JoinGraphTablePtr mvGraphTable = mvSubGraph->getParentGraph()->getTableByID(mvTableElement->getID()); if (matchPredsFromTableToSubGraph(mvSubGraph, querySubGraph, mvGraphTable, queryGraphTable) == FALSE) { // Match failed. // Release the sandbox subgraphs and disqualify the MVCandidate. deletePtr(mvSubGraphMap); deletePtr(querySubGraphMap); logMVWasDisqualified1("Extra hub table %s is needed but cannot be matched.", queryTableElement->getTableName().data()); return FALSE; } // Add the table to both MV and query subgraphs. querySubGraph->addTable(queryGraphTable); mvSubGraph->addTable(mvGraphTable); // To make sure that Pass 2 matching and result desxcriptor generation will // work correctly, add the tables to the SubGraphMaps (they will have the same index). CollIndex index = querySubGraph->entries(); querySubGraphMap->addTable(index, queryGraphTable); mvSubGraphMap->addTable(index, mvGraphTable); // We are done with this table, remove it from the list. extraHubTables_.remove(tableID); extraHubTableWasAdded = TRUE; QRLogger::log(CAT_MVCAND, LL_DEBUG, "ExtraHub table %s was matched for MV %s.", queryTableElement->getTableName().data(), mvDetails_->getMVName().data()); return TRUE; } // MVCandidate::CheckAnExtraHubTable()
NABoolean MVCandidate::CheckExtraHubTables() { if (extraHubTables_.entries() == 0) return TRUE; // Allocate a new subGraph and subGraphMap for the MV - the one we have is from MVMemo, // so its considered read-only. QRJoinSubGraphMapPtr mvSubGraphMap = new(heap_) QRJoinSubGraphMap(*getMvSubGraphMap(), ADD_MEMCHECK_ARGS(heap_)); // The query subGraph is shared between the MVCandidates that were found // in the same MVMemo group, so work on a copy. QRJoinSubGraphMapPtr querySubGraphMap = new(heap_) QRJoinSubGraphMap(*getJbbSubset()->getQuerySubGraphMap(), ADD_MEMCHECK_ARGS(heap_)); // Loop over the list, each time picking an extra-hub table that is // directly connected to a table already in the matched sub-graph, // until all the tables are checked. do { NABoolean extraHubTableWasAdded = FALSE; // Do the loop backwards because we remove checked extra-hub tables from the list. for (Int32 i=(CollIndex)extraHubTables_.entries()-1; i>=0; i--) { if (CheckAnExtraHubTable(extraHubTables_[i], mvSubGraphMap, // IN/OUT querySubGraphMap, // IN/OUT extraHubTableWasAdded) == FALSE) return FALSE; } // for // Keep looping as long as there are extra-hub tables that are not connected, // and as long as we keep adding them. if (!extraHubTableWasAdded && extraHubTables_.entries() > 0) { logMVWasDisqualified1("Extra hub table %s is needed but cannot be matched.", extraHubTables_[0]->data()); return FALSE; } // assertLogAndThrow(extraHubTableWasAdded, QRLogicException, // "Extra-hub table is not connected to the hub."); } while (extraHubTables_.entries() > 0); // Update the MV new subGraphMap mvSubGraphMap_ = mvSubGraphMap; // We have added at least one extra-hub table - // now we need to reorg the JBBSubsets accordingly. MVCandidatesForJBBPtr jbb = getJbbSubset()->getJbbCandidates(); MVCandidatesForJBBSubsetPtr newJbbSubset = NULL; QRJoinSubGraphPtr querySubGraph = querySubGraphMap->getSubGraph(); if (jbb->contains(querySubGraph)) { // The JBBSubset with the new extra-hub tables already exists. newJbbSubset = jbb->getJbbSubsetFor(querySubGraph); } else { // Need to create a new JBBSubset. newJbbSubset = new (heap_) MVCandidatesForJBBSubset(jbb, ADD_MEMCHECK_ARGS(heap_)); newJbbSubset->setSubGraphMap(querySubGraphMap); // Add the new JbbSubset to the JBB. jbb->insert(newJbbSubset); } // Move the candidate from the current JbbSubset to the new one. getJbbSubset()->remove(this); newJbbSubset->insert(this); setJbbSubset(newJbbSubset); return TRUE; } // CheckExtraHubTables()