validate a relation-pattern
| 746 | |
| 747 | // validate a relation-pattern |
| 748 | static VISITOR_STRATEGY _Validate_rel_pattern |
| 749 | ( |
| 750 | const cypher_astnode_t *n, // ast-node (rel-pattern)s |
| 751 | bool start, // first traversal |
| 752 | ast_visitor *visitor // visitor |
| 753 | ) { |
| 754 | validations_ctx *vctx = AST_Visitor_GetContext(visitor); |
| 755 | if(!start) { |
| 756 | return VISITOR_CONTINUE; |
| 757 | } |
| 758 | |
| 759 | const cypher_astnode_t *range = cypher_ast_rel_pattern_get_varlength(n); |
| 760 | if(vctx->clause == CYPHER_AST_CREATE) { |
| 761 | // validate that the relation alias is not bound |
| 762 | if(_ValidateCreateRelation(n, vctx->defined_identifiers) == AST_INVALID) { |
| 763 | return VISITOR_BREAK; |
| 764 | } |
| 765 | |
| 766 | // Validate that each relation has exactly one type |
| 767 | uint reltype_count = cypher_ast_rel_pattern_nreltypes(n); |
| 768 | if(reltype_count != 1) { |
| 769 | ErrorCtx_SetError("Exactly one relationship type must be specified for CREATE"); |
| 770 | return VISITOR_BREAK; |
| 771 | } |
| 772 | |
| 773 | // Validate that each relation being created is directed |
| 774 | if(cypher_ast_rel_pattern_get_direction(n) == CYPHER_REL_BIDIRECTIONAL) { |
| 775 | ErrorCtx_SetError("Only directed relationships are supported in CREATE"); |
| 776 | return VISITOR_BREAK; |
| 777 | } |
| 778 | |
| 779 | // Validate that each relation being created is not variable length relationship |
| 780 | if(range) { |
| 781 | ErrorCtx_SetError("Variable length relationships cannot be used in CREATE"); |
| 782 | return VISITOR_BREAK; |
| 783 | } |
| 784 | } |
| 785 | |
| 786 | if(_ValidateInlinedProperties(cypher_ast_rel_pattern_get_properties(n)) == AST_INVALID) { |
| 787 | return VISITOR_BREAK; |
| 788 | } |
| 789 | |
| 790 | if(vctx->clause == CYPHER_AST_MERGE && |
| 791 | _ValidateMergeRelation(n, vctx->defined_identifiers) == AST_INVALID) { |
| 792 | return VISITOR_BREAK; |
| 793 | } |
| 794 | |
| 795 | const cypher_astnode_t *alias_node = cypher_ast_rel_pattern_get_identifier(n); |
| 796 | if(!alias_node && !range) { |
| 797 | return VISITOR_RECURSE; // Skip unaliased, single-hop entities. |
| 798 | } |
| 799 | |
| 800 | // If this is a multi-hop traversal, validate it accordingly |
| 801 | if(range && _ValidateMultiHopTraversal(n, range) == AST_INVALID) { |
| 802 | return VISITOR_BREAK; |
| 803 | } |
| 804 | |
| 805 | if(alias_node) { |
nothing calls this directly
no test coverage detected