| 152 | } |
| 153 | |
| 154 | std::pair<CSRNodeGroupScanSource, row_idx_t> RelTableData::findMatchingRow(Transaction* transaction, |
| 155 | ValueVector& boundNodeIDVector, const ValueVector& relIDVector) const { |
| 156 | DASSERT(boundNodeIDVector.state->getSelVector().getSelSize() == 1); |
| 157 | DASSERT(relIDVector.state->getSelVector().getSelSize() == 1); |
| 158 | const auto boundNodePos = boundNodeIDVector.state->getSelVector()[0]; |
| 159 | const auto relIDPos = relIDVector.state->getSelVector()[0]; |
| 160 | const auto boundNodeOffset = boundNodeIDVector.getValue<nodeID_t>(boundNodePos).offset; |
| 161 | const auto relOffset = relIDVector.getValue<nodeID_t>(relIDPos).offset; |
| 162 | const auto nodeGroupIdx = StorageUtils::getNodeGroupIdx(boundNodeOffset); |
| 163 | |
| 164 | DataChunk scanChunk(1); |
| 165 | // RelID output vector. |
| 166 | scanChunk.insert(0, std::make_shared<ValueVector>(LogicalType::INTERNAL_ID())); |
| 167 | std::vector columnIDs = {REL_ID_COLUMN_ID, ROW_IDX_COLUMN_ID}; |
| 168 | std::vector<const Column*> columns{getColumn(REL_ID_COLUMN_ID), nullptr}; |
| 169 | auto scanState = std::make_unique<RelTableScanState>(*mm, &boundNodeIDVector, |
| 170 | std::vector{&scanChunk.getValueVectorMutable(0)}, scanChunk.state, true /*randomLookup*/); |
| 171 | scanState->setToTable(transaction, &table, columnIDs, {}, direction); |
| 172 | scanState->initState(transaction, getNodeGroup(nodeGroupIdx)); |
| 173 | row_idx_t matchingRowIdx = INVALID_ROW_IDX; |
| 174 | auto source = CSRNodeGroupScanSource::NONE; |
| 175 | const auto scannedIDVector = scanState->outputVectors[0]; |
| 176 | while (true) { |
| 177 | const auto scanResult = scanState->nodeGroup->scan(transaction, *scanState); |
| 178 | if (scanResult == NODE_GROUP_SCAN_EMPTY_RESULT) { |
| 179 | break; |
| 180 | } |
| 181 | for (auto i = 0u; i < scanState->outState->getSelVector().getSelSize(); i++) { |
| 182 | const auto pos = scanState->outState->getSelVector()[i]; |
| 183 | if (scannedIDVector->getValue<internalID_t>(pos).offset == relOffset) { |
| 184 | const auto rowIdxPos = scanState->rowIdxVector->state->getSelVector()[i]; |
| 185 | matchingRowIdx = scanState->rowIdxVector->getValue<row_idx_t>(rowIdxPos); |
| 186 | source = scanState->nodeGroupScanState->cast<CSRNodeGroupScanState>().source; |
| 187 | break; |
| 188 | } |
| 189 | } |
| 190 | if (matchingRowIdx != INVALID_ROW_IDX) { |
| 191 | break; |
| 192 | } |
| 193 | } |
| 194 | return {source, matchingRowIdx}; |
| 195 | } |
| 196 | |
| 197 | bool RelTableData::checkIfNodeHasRels(Transaction* transaction, |
| 198 | ValueVector* srcNodeIDVector) const { |
nothing calls this directly
no test coverage detected