MCPcopy Create free account
hub / github.com/LadybugDB/ladybug / createRecursiveQueryRel

Method createRecursiveQueryRel

src/binder/bind/bind_graph_pattern.cpp:355–498  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

353}
354
355std::shared_ptr<RelExpression> Binder::createRecursiveQueryRel(const parser::RelPattern& relPattern,
356 const std::vector<TableCatalogEntry*>& entries, std::shared_ptr<NodeExpression> srcNode,
357 std::shared_ptr<NodeExpression> dstNode, RelDirectionType directionType) {
358 auto catalog = Catalog::Get(*clientContext);
359 auto transaction = transaction::Transaction::Get(*clientContext);
360 table_catalog_entry_set_t nodeEntrySet;
361 for (auto entry : entries) {
362 auto& relGroupEntry = entry->constCast<RelGroupCatalogEntry>();
363 for (auto id : relGroupEntry.getSrcNodeTableIDSet()) {
364 nodeEntrySet.insert(catalog->getTableCatalogEntry(transaction, id));
365 }
366 for (auto id : relGroupEntry.getDstNodeTableIDSet()) {
367 nodeEntrySet.insert(catalog->getTableCatalogEntry(transaction, id));
368 }
369 }
370 auto nodeEntries = std::vector<TableCatalogEntry*>{nodeEntrySet.begin(), nodeEntrySet.end()};
371 auto recursivePatternInfo = relPattern.getRecursiveInfo();
372 auto prevScope = saveScope();
373 scope.clear();
374 // Bind intermediate node.
375 auto node = createQueryNode(recursivePatternInfo->nodeName, nodeEntries, {}, {});
376 addToScope(node->toString(), node);
377 auto nodeFields = getBaseNodeStructFields();
378 auto nodeProjectionList = bindRecursivePatternNodeProjectionList(*recursivePatternInfo, *node);
379 bindProjectionListAsStructField(nodeProjectionList, nodeFields);
380 node->setDataType(LogicalType::NODE(std::move(nodeFields)));
381 auto nodeCopy = createQueryNode(recursivePatternInfo->nodeName, nodeEntries, {}, {});
382 // Bind intermediate rel
383 auto rel = createNonRecursiveQueryRel(recursivePatternInfo->relName, entries,
384 nullptr /* srcNode */, nullptr /* dstNode */, directionType, {});
385 addToScope(rel->toString(), rel);
386 auto relProjectionList = bindRecursivePatternRelProjectionList(*recursivePatternInfo, *rel);
387 auto relFields = getBaseRelStructFields();
388 relFields.emplace_back(InternalKeyword::ID, LogicalType::INTERNAL_ID());
389 bindProjectionListAsStructField(relProjectionList, relFields);
390 rel->setDataType(LogicalType::REL(std::move(relFields)));
391 // Bind predicates in {}, e.g. [e* {date=1999-01-01}]
392 std::shared_ptr<Expression> relPredicate = nullptr;
393 for (auto& [propertyName, rhs] : relPattern.getPropertyKeyVals()) {
394 auto boundLhs = expressionBinder.bindNodeOrRelPropertyExpression(*rel, propertyName);
395 auto boundRhs = expressionBinder.bindExpression(*rhs);
396 boundRhs = expressionBinder.implicitCastIfNecessary(boundRhs, boundLhs->dataType);
397 auto predicate = expressionBinder.createEqualityComparisonExpression(boundLhs, boundRhs);
398 relPredicate = expressionBinder.combineBooleanExpressions(ExpressionType::AND, relPredicate,
399 predicate);
400 }
401 // Bind predicates in (r, n | WHERE )
402 bool emptyRecursivePattern = false;
403 std::shared_ptr<Expression> nodePredicate = nullptr;
404 if (recursivePatternInfo->whereExpression != nullptr) {
405 expressionBinder.config.disableLabelFunctionLiteralRewrite = true;
406 auto wherePredicate = bindWhereExpression(*recursivePatternInfo->whereExpression);
407 expressionBinder.config.disableLabelFunctionLiteralRewrite = false;
408 for (auto& predicate : wherePredicate->splitOnAND()) {
409 auto collector = DependentVarNameCollector();
410 collector.visit(predicate);
411 auto dependentVariableNames = collector.getVarNames();
412 auto dependOnNode = dependentVariableNames.contains(node->getUniqueName());

Callers

nothing calls this directly

Calls 15

getBaseNodeStructFieldsFunction · 0.85
getBaseRelStructFieldsFunction · 0.85
NativeGraphEntryClass · 0.85
constructFunction · 0.85
getSrcNodeTableIDSetMethod · 0.80
getTableCatalogEntryMethod · 0.80
getDstNodeTableIDSetMethod · 0.80
getRecursiveInfoMethod · 0.80

Tested by

no test coverage detected