| 278 | } |
| 279 | |
| 280 | std::shared_ptr<RelExpression> Binder::createNonRecursiveQueryRel(const std::string& parsedName, |
| 281 | const std::vector<TableCatalogEntry*>& entries, std::shared_ptr<NodeExpression> srcNode, |
| 282 | std::shared_ptr<NodeExpression> dstNode, RelDirectionType directionType, |
| 283 | const std::vector<std::string>& originalLabels) { |
| 284 | auto uniqueName = getUniqueExpressionName(parsedName); |
| 285 | // Bind properties |
| 286 | auto structFields = getBaseRelStructFields(); |
| 287 | std::vector<std::shared_ptr<PropertyExpression>> propertyExpressions; |
| 288 | if (entries.empty()) { |
| 289 | structFields.emplace_back(InternalKeyword::ID, LogicalType::INTERNAL_ID()); |
| 290 | } else { |
| 291 | for (auto& propertyName : getPropertyNames(entries)) { |
| 292 | auto property = createPropertyExpression(propertyName, uniqueName, parsedName, entries); |
| 293 | structFields.emplace_back(property->getPropertyName(), property->getDataType().copy()); |
| 294 | propertyExpressions.push_back(std::move(property)); |
| 295 | } |
| 296 | } |
| 297 | auto queryRel = std::make_shared<RelExpression>(LogicalType::REL(std::move(structFields)), |
| 298 | uniqueName, parsedName, entries, std::move(srcNode), std::move(dstNode), directionType, |
| 299 | QueryRelType::NON_RECURSIVE); |
| 300 | queryRel->setAlias(parsedName); |
| 301 | if (entries.empty()) { |
| 302 | queryRel->addPropertyExpression( |
| 303 | construct(LogicalType::INTERNAL_ID(), InternalKeyword::ID, *queryRel)); |
| 304 | } else { |
| 305 | for (auto& property : propertyExpressions) { |
| 306 | queryRel->addPropertyExpression(property); |
| 307 | } |
| 308 | } |
| 309 | // Bind internal expressions. |
| 310 | if (directionType == RelDirectionType::BOTH) { |
| 311 | queryRel->setDirectionExpr(expressionBinder.createVariableExpression(LogicalType::BOOL(), |
| 312 | queryRel->getUniqueName() + InternalKeyword::DIRECTION)); |
| 313 | } |
| 314 | auto input = function::RewriteFunctionBindInput(clientContext, &expressionBinder, {queryRel}); |
| 315 | queryRel->setLabelExpression(function::LabelFunction::rewriteFunc(input)); |
| 316 | // Store original labels for ANY graphs |
| 317 | if (!originalLabels.empty()) { |
| 318 | queryRel->setOriginalLabels(originalLabels); |
| 319 | } |
| 320 | return queryRel; |
| 321 | } |
| 322 | |
| 323 | static void bindProjectionListAsStructField(const expression_vector& projectionList, |
| 324 | std::vector<StructField>& fields) { |
no test coverage detected