// *************************************************************************** // Initialize internal data structures. // *************************************************************************** void DescriptorDetails::init(CollHeap* heap) { // Map all the IDs in the MV descriptor for easy access. // This call does a tree walk to initialize the idHash_ map of IDs to elements. MapIDsVisitorPtr visitor1 = new(heap) MapIDsVisitor(idHash_, ADD_MEMCHECK_ARGS(heap)); descriptor_->treeWalk(visitor1); deletePtr(visitor1); RefFinderVisitorPtr visitor2 = new(heap) RefFinderVisitor(this, ADD_MEMCHECK_ARGS(heap)); descriptor_->treeWalk(visitor2); deletePtr(visitor2); // Map all the JoinPreds to their participating columns. // This must be done before initializing outputs and other preds. initJoinPreds(); // Init the list of JBBDetails const NAPtrList<QRJBBPtr>& jbbs = descriptor_->getJbbList(); for (CollIndex i = 0; i < jbbs.entries(); i++) { QRJBBPtr jbb = jbbs[i]; JBBDetailsPtr jbbDetails = new(heap) JBBDetails(jbb, this, isAnMV_, ADD_MEMCHECK_ARGS(heap)); jbbDetails->init(heap); addJBBDetails(jbbDetails); } }
//***************************************************************************** // Calculate the needed size of the permutationMatrix, allocate it, // and initialize it. // The permutationMatrix has a column for each SelfJoin segment, and a row // for each permutation. //***************************************************************************** void SelfJoinHandler::preparePermutationMatrix() { totalPermutations_ = 1; CollIndex segments = segmentArray_.entries(); UInt32 matrixWidth = 0; // The permVector holds for each SelfJoin segment its number of permutations. UInt32* permVector = new (heap_) UInt32[segments]; ShiftMatrixFactoryPtr factory = ShiftMatrixFactory::getInstance(heap_); // Go over each segment in the array. for (CollIndex i=0; i<segments; i++) { SelfJoinSegmentPtr segment = segmentArray_[i]; if (segment->isSelfJoinSegment()) { totalPermutations_ *= segment->getPermutations(); segment->setMatrixIndex(matrixWidth); permVector[matrixWidth] = segment->getPermutations(); matrixWidth++; segment->setShiftMatrix(factory->getMatrixForSize(segment->getSize())); } } // Allocate the permutationMatrix. permMatrix_ = new(heap_) Array2D(matrixWidth, totalPermutations_, 9999, ADD_MEMCHECK_ARGS(heap_)); // And initialize it. initPermutationMatrix(permVector); }
// *************************************************************************** // *************************************************************************** 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); } } }
//***************************************************************************** // Create and initialize a ShiftMatrix of size size. //***************************************************************************** ShiftMatrix::ShiftMatrix(Int32 size, ADD_MEMCHECK_ARGS_DECL(CollHeap* heap)) : NAIntrusiveSharedPtrObject(ADD_MEMCHECK_ARGS_PASS(heap)), theMatrix_(NULL), elements_(size), combinations_(factorial(elements_)), // The number of permutations is size! heap_(heap) { // Allocate the array of permutations theMatrix_ = new(heap) Array2D(combinations_, elements_, 9999, ADD_MEMCHECK_ARGS(heap)); // Initialize the matrix. init(); }
//***************************************************************************** // Get a ShiftMatrix for a specific size. //***************************************************************************** const ShiftMatrixPtr ShiftMatrixFactory::getMatrixForSize(Int32 size) { // Did we already build a ShiftMatrix for this size? if (matrixSizeArray_.used(size)) { // Yes - return it. return matrixSizeArray_[size]; } else { // No - build one now. ShiftMatrixPtr newMatrix = new (heap_) ShiftMatrix(size, ADD_MEMCHECK_ARGS(heap_)); // And keep the pointer in the array. matrixSizeArray_.insertAt(size, newMatrix); return newMatrix; } }
MVCandidatesForJBBSubsetPtr QRGroupLattice::search(QRJBBPtr queryJbb, MVCandidatesForJBBPtr mvCandidates, QRJoinSubGraphMapPtr map, ElementPtrList* minimizedGroupingList) { QRTRACER("QRGroupLattice::search()"); DescriptorDetailsPtr queryDetails = mvCandidates->getAllCandidates()->getQueryDetails(); LatticeKeyList keyList(heap_); if (minimizedGroupingList) { if (!elementListToKeyList(*minimizedGroupingList, keyList, map, queryDetails, FALSE)) return NULL; } else { // Get the grouping columns of the passed query JBB, and create a key list // from them. Return now if there are no grouping items -- a query without a // Group By can't match an MV that has one. QRGroupByPtr groupBy = queryJbb->getGroupBy(); if (!groupBy) return NULL; // An aggregate query with no GroupBy has an empty key list. if (!getGroupingLatticeKeys(keyList, map, queryDetails, queryJbb, TRUE, FALSE)) return NULL; } // Create the search node, disallowing the addition of any new keys to the hash // table used by the lattice; if the key isn't already used, the node can have // no supersets. QRLatticeIndexSearchNode searchNode(keyList, lattice_, TRUE, heap_); if (!searchNode.isValid()) // because a key wasn't added return NULL; NAString keysText; searchNode.dumpNode(keysText, *lattice_->getKeyArr()); QRLogger::log(CAT_GRP_LATTCE_INDX, LL_DEBUG, "Searching LatticeIndex for: %s.", keysText.data()); // Find the supersets of the query's group-by list in the MV group lattice // index. For each lattice index node returned, create an MVCandidate // corresponding to each MV represented by that node, and add it to the // candidate list passed by the caller. NAPtrList<QRLatticeIndexNodePtr> nodes; lattice_->findSupersets(searchNode, nodes); if (nodes.entries() == 0) { QRLogger::log(CAT_GRP_LATTCE_INDX, LL_DEBUG, "No match found."); return NULL; } MVCandidatesForJBBSubsetPtr jbbSubset = new(heap_) MVCandidatesForJBBSubset(mvCandidates, ADD_MEMCHECK_ARGS(heap_)); jbbSubset->setSubGraphMap(map); jbbSubset->setGroupBy(TRUE); if (minimizedGroupingList != NULL) jbbSubset->setMinimizedGroupingList(minimizedGroupingList); for (CollIndex i=0; i<nodes.entries(); i++) { QRLatticeIndexNodePtr thisNode = nodes[i]; const SubGraphMapList& matchingMVs = thisNode->getMVs(); NABoolean isPreferred = (*thisNode == searchNode); // preferred if exact match GroupingList* extraGroupingColumns = new(heap_) GroupingList(heap_); if (!isPreferred) { // For preferred match modes, there are no extraGroupingColumns. LatticeKeySubArray* diff = thisNode->computeDiff(searchNode, heap_); for(CollIndex i = 0; diff->nextUsed(i); i++) { LatticeIndexablePtr key = diff->element(i); QRElementPtr elem = keyToElement(key, map); extraGroupingColumns->insert(elem); } delete diff; } for (CollIndex j=0; j<matchingMVs.entries(); j++) { MVDetailsPtr mv = matchingMVs[j]->getMVDetails(); QRLogger::log(CAT_GRP_LATTCE_INDX, LL_DEBUG, "Found MV: %s!", mv->getMVName().data() ); jbbSubset->insert(mv, queryJbb, isPreferred, extraGroupingColumns, NULL, heap_); } } return jbbSubset; } // QRGroupLattice::search()
//***************************************************************************** // Add a segment to the segment array. //***************************************************************************** void SelfJoinHandler::addSegment(SelfJoinSegment::SegmentType type) { SelfJoinSegmentPtr newSegment = new (heap_) SelfJoinSegment(type, segmentStart_, segmentEnd_, ADD_MEMCHECK_ARGS(heap_)); segmentArray_.insertAt(segmentArray_.entries(), newSegment); }