MCPcopy Create free account
hub / github.com/RedisGraph/RedisGraph / AR_TOPATH

Function AR_TOPATH

src/arithmetic/path_funcs/path_funcs.c:24–93  ·  view source on GitHub ↗

Creates a path from a given sequence of graph entities. * The first argument is the ast node represents the path. * Arguments 2...n are the sequence of graph entities combines the path. * The sequence is always in odd length and defined as: * Odd indices members are always representing the value of a single node. * Even indices members are either representing the value of a single edge, * or

Source from the content-addressed store, hash-verified

22 * Even indices members are either representing the value of a single edge,
23 * or an sipath, in case of variable length traversal. */
24SIValue AR_TOPATH(SIValue *argv, int argc, void *private_data) {
25 const cypher_astnode_t *ast_path = argv[0].ptrval;
26 uint nelements = cypher_ast_pattern_path_nelements(ast_path);
27 ASSERT(argc == (nelements + 1));
28
29 uint n = 0;
30 uint path_elements = 0;
31 SIValue arr[nelements];
32 // collect path elements
33 // and calculate how much space needed for the returned path
34 for(uint i = 0; i < nelements; i++) {
35 SIValue element = argv[i + 1];
36 if(SI_TYPE(element) == T_NULL) {
37 // if any element of the path does not exist
38 // the entire path is invalid
39 return SI_NullVal();
40 }
41
42 if(i % 2 == 0) {
43 path_elements++;
44 } else {
45 // edges and paths are in odd positions
46 // element type can be either edge, or path
47 if(SI_TYPE(element) == T_EDGE) {
48 path_elements++;
49 } else { // if element is not an edge, it is a path
50 // path with 0 edges should not be appended
51 // their source and destination nodes are the same
52 // and the source node already appended.
53 size_t len = SIPath_Length(element);
54 if(len == 0) {
55 i++;
56 continue;
57 }
58 // len - 1 nodes and len edges from this path
59 // will be added to the returned path
60 path_elements += len * 2 - 1;
61 }
62 }
63 arr[n++] = element;
64 }
65
66 SIValue path = SIPathBuilder_New(path_elements);
67 for(uint i = 0; i < n; i++) {
68 SIValue element = arr[i];
69
70 if(i % 2 == 0) {
71 // nodes are in even position
72 SIPathBuilder_AppendNode(path, element);
73 } else {
74 // edges and paths are in odd positions
75 const cypher_astnode_t *ast_rel_pattern = cypher_ast_pattern_path_get_element(ast_path, i);
76 bool RTL_pattern = cypher_ast_rel_pattern_get_direction(ast_rel_pattern) == CYPHER_REL_INBOUND;
77 // element type can be either edge, or path
78 if(SI_TYPE(element) == T_EDGE) {
79 SIPathBuilder_AppendEdge(path, element, RTL_pattern);
80 } else { // if element is not an edge, it is a path
81 // the build should continue to the next edge/path value

Callers

nothing calls this directly

Calls 6

SI_NullValFunction · 0.85
SIPath_LengthFunction · 0.85
SIPathBuilder_NewFunction · 0.85
SIPathBuilder_AppendNodeFunction · 0.85
SIPathBuilder_AppendEdgeFunction · 0.85
SIPathBuilder_AppendPathFunction · 0.85

Tested by

no test coverage detected