flowquery 1.0.18 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/.gitattributes +3 -0
  2. package/.github/workflows/python-publish.yml +56 -4
  3. package/.github/workflows/release.yml +26 -19
  4. package/.husky/pre-commit +26 -0
  5. package/README.md +37 -32
  6. package/dist/flowquery.min.js +1 -1
  7. package/dist/graph/data.d.ts +5 -4
  8. package/dist/graph/data.d.ts.map +1 -1
  9. package/dist/graph/data.js +38 -20
  10. package/dist/graph/data.js.map +1 -1
  11. package/dist/graph/node.d.ts +2 -0
  12. package/dist/graph/node.d.ts.map +1 -1
  13. package/dist/graph/node.js +23 -0
  14. package/dist/graph/node.js.map +1 -1
  15. package/dist/graph/node_data.js +1 -1
  16. package/dist/graph/node_data.js.map +1 -1
  17. package/dist/graph/pattern.d.ts.map +1 -1
  18. package/dist/graph/pattern.js +11 -4
  19. package/dist/graph/pattern.js.map +1 -1
  20. package/dist/graph/relationship.d.ts +6 -1
  21. package/dist/graph/relationship.d.ts.map +1 -1
  22. package/dist/graph/relationship.js +43 -5
  23. package/dist/graph/relationship.js.map +1 -1
  24. package/dist/graph/relationship_data.d.ts +2 -0
  25. package/dist/graph/relationship_data.d.ts.map +1 -1
  26. package/dist/graph/relationship_data.js +8 -1
  27. package/dist/graph/relationship_data.js.map +1 -1
  28. package/dist/graph/relationship_match_collector.js +2 -2
  29. package/dist/graph/relationship_match_collector.js.map +1 -1
  30. package/dist/graph/relationship_reference.d.ts.map +1 -1
  31. package/dist/graph/relationship_reference.js +2 -1
  32. package/dist/graph/relationship_reference.js.map +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/index.js +1 -1
  35. package/dist/parsing/parser.d.ts +6 -0
  36. package/dist/parsing/parser.d.ts.map +1 -1
  37. package/dist/parsing/parser.js +139 -72
  38. package/dist/parsing/parser.js.map +1 -1
  39. package/docs/flowquery.min.js +1 -1
  40. package/flowquery-py/misc/data/test.json +10 -0
  41. package/flowquery-py/misc/data/users.json +242 -0
  42. package/flowquery-py/notebooks/TestFlowQuery.ipynb +440 -0
  43. package/flowquery-py/pyproject.toml +48 -2
  44. package/flowquery-py/src/__init__.py +7 -5
  45. package/flowquery-py/src/compute/runner.py +14 -10
  46. package/flowquery-py/src/extensibility.py +8 -8
  47. package/flowquery-py/src/graph/__init__.py +7 -7
  48. package/flowquery-py/src/graph/data.py +38 -20
  49. package/flowquery-py/src/graph/database.py +10 -20
  50. package/flowquery-py/src/graph/node.py +50 -19
  51. package/flowquery-py/src/graph/node_data.py +1 -1
  52. package/flowquery-py/src/graph/node_reference.py +10 -11
  53. package/flowquery-py/src/graph/pattern.py +27 -37
  54. package/flowquery-py/src/graph/pattern_expression.py +13 -11
  55. package/flowquery-py/src/graph/patterns.py +2 -2
  56. package/flowquery-py/src/graph/physical_node.py +4 -3
  57. package/flowquery-py/src/graph/physical_relationship.py +5 -5
  58. package/flowquery-py/src/graph/relationship.py +62 -14
  59. package/flowquery-py/src/graph/relationship_data.py +7 -2
  60. package/flowquery-py/src/graph/relationship_match_collector.py +15 -10
  61. package/flowquery-py/src/graph/relationship_reference.py +4 -4
  62. package/flowquery-py/src/io/command_line.py +13 -14
  63. package/flowquery-py/src/parsing/__init__.py +2 -2
  64. package/flowquery-py/src/parsing/alias_option.py +1 -1
  65. package/flowquery-py/src/parsing/ast_node.py +21 -20
  66. package/flowquery-py/src/parsing/base_parser.py +7 -7
  67. package/flowquery-py/src/parsing/components/__init__.py +3 -3
  68. package/flowquery-py/src/parsing/components/from_.py +3 -1
  69. package/flowquery-py/src/parsing/components/headers.py +2 -2
  70. package/flowquery-py/src/parsing/components/null.py +2 -2
  71. package/flowquery-py/src/parsing/context.py +7 -7
  72. package/flowquery-py/src/parsing/data_structures/associative_array.py +7 -7
  73. package/flowquery-py/src/parsing/data_structures/json_array.py +3 -3
  74. package/flowquery-py/src/parsing/data_structures/key_value_pair.py +4 -4
  75. package/flowquery-py/src/parsing/data_structures/lookup.py +2 -2
  76. package/flowquery-py/src/parsing/data_structures/range_lookup.py +2 -2
  77. package/flowquery-py/src/parsing/expressions/__init__.py +16 -16
  78. package/flowquery-py/src/parsing/expressions/expression.py +16 -13
  79. package/flowquery-py/src/parsing/expressions/expression_map.py +9 -9
  80. package/flowquery-py/src/parsing/expressions/f_string.py +3 -3
  81. package/flowquery-py/src/parsing/expressions/identifier.py +4 -3
  82. package/flowquery-py/src/parsing/expressions/number.py +3 -3
  83. package/flowquery-py/src/parsing/expressions/operator.py +16 -16
  84. package/flowquery-py/src/parsing/expressions/reference.py +3 -3
  85. package/flowquery-py/src/parsing/expressions/string.py +2 -2
  86. package/flowquery-py/src/parsing/functions/__init__.py +17 -17
  87. package/flowquery-py/src/parsing/functions/aggregate_function.py +8 -8
  88. package/flowquery-py/src/parsing/functions/async_function.py +12 -9
  89. package/flowquery-py/src/parsing/functions/avg.py +4 -4
  90. package/flowquery-py/src/parsing/functions/collect.py +6 -6
  91. package/flowquery-py/src/parsing/functions/function.py +6 -6
  92. package/flowquery-py/src/parsing/functions/function_factory.py +31 -34
  93. package/flowquery-py/src/parsing/functions/function_metadata.py +10 -11
  94. package/flowquery-py/src/parsing/functions/functions.py +14 -6
  95. package/flowquery-py/src/parsing/functions/join.py +3 -3
  96. package/flowquery-py/src/parsing/functions/keys.py +3 -3
  97. package/flowquery-py/src/parsing/functions/predicate_function.py +8 -7
  98. package/flowquery-py/src/parsing/functions/predicate_sum.py +12 -7
  99. package/flowquery-py/src/parsing/functions/rand.py +2 -2
  100. package/flowquery-py/src/parsing/functions/range_.py +9 -4
  101. package/flowquery-py/src/parsing/functions/replace.py +2 -2
  102. package/flowquery-py/src/parsing/functions/round_.py +2 -2
  103. package/flowquery-py/src/parsing/functions/size.py +2 -2
  104. package/flowquery-py/src/parsing/functions/split.py +9 -4
  105. package/flowquery-py/src/parsing/functions/stringify.py +3 -3
  106. package/flowquery-py/src/parsing/functions/sum.py +4 -4
  107. package/flowquery-py/src/parsing/functions/to_json.py +2 -2
  108. package/flowquery-py/src/parsing/functions/type_.py +3 -3
  109. package/flowquery-py/src/parsing/functions/value_holder.py +1 -1
  110. package/flowquery-py/src/parsing/logic/__init__.py +2 -2
  111. package/flowquery-py/src/parsing/logic/case.py +0 -1
  112. package/flowquery-py/src/parsing/logic/when.py +3 -1
  113. package/flowquery-py/src/parsing/operations/__init__.py +10 -10
  114. package/flowquery-py/src/parsing/operations/aggregated_return.py +3 -5
  115. package/flowquery-py/src/parsing/operations/aggregated_with.py +4 -4
  116. package/flowquery-py/src/parsing/operations/call.py +6 -7
  117. package/flowquery-py/src/parsing/operations/create_node.py +5 -4
  118. package/flowquery-py/src/parsing/operations/create_relationship.py +5 -4
  119. package/flowquery-py/src/parsing/operations/group_by.py +18 -16
  120. package/flowquery-py/src/parsing/operations/load.py +21 -19
  121. package/flowquery-py/src/parsing/operations/match.py +8 -7
  122. package/flowquery-py/src/parsing/operations/operation.py +3 -3
  123. package/flowquery-py/src/parsing/operations/projection.py +6 -6
  124. package/flowquery-py/src/parsing/operations/return_op.py +9 -5
  125. package/flowquery-py/src/parsing/operations/unwind.py +3 -2
  126. package/flowquery-py/src/parsing/operations/where.py +9 -7
  127. package/flowquery-py/src/parsing/operations/with_op.py +2 -2
  128. package/flowquery-py/src/parsing/parser.py +178 -114
  129. package/flowquery-py/src/parsing/token_to_node.py +2 -2
  130. package/flowquery-py/src/tokenization/__init__.py +4 -4
  131. package/flowquery-py/src/tokenization/keyword.py +1 -1
  132. package/flowquery-py/src/tokenization/operator.py +1 -1
  133. package/flowquery-py/src/tokenization/string_walker.py +4 -4
  134. package/flowquery-py/src/tokenization/symbol.py +1 -1
  135. package/flowquery-py/src/tokenization/token.py +11 -11
  136. package/flowquery-py/src/tokenization/token_mapper.py +10 -9
  137. package/flowquery-py/src/tokenization/token_type.py +1 -1
  138. package/flowquery-py/src/tokenization/tokenizer.py +19 -19
  139. package/flowquery-py/src/tokenization/trie.py +18 -17
  140. package/flowquery-py/src/utils/__init__.py +1 -1
  141. package/flowquery-py/src/utils/object_utils.py +3 -3
  142. package/flowquery-py/src/utils/string_utils.py +12 -12
  143. package/flowquery-py/tests/compute/test_runner.py +214 -7
  144. package/flowquery-py/tests/parsing/test_parser.py +41 -0
  145. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
  146. package/package.json +1 -1
  147. package/src/graph/data.ts +38 -20
  148. package/src/graph/node.ts +23 -0
  149. package/src/graph/node_data.ts +1 -1
  150. package/src/graph/pattern.ts +13 -4
  151. package/src/graph/relationship.ts +45 -5
  152. package/src/graph/relationship_data.ts +8 -1
  153. package/src/graph/relationship_match_collector.ts +1 -1
  154. package/src/graph/relationship_reference.ts +2 -1
  155. package/src/index.ts +5 -5
  156. package/src/parsing/parser.ts +139 -71
  157. package/tests/compute/runner.test.ts +249 -79
  158. package/tests/parsing/parser.test.ts +32 -0
@@ -1,8 +1,7 @@
1
1
  """Function metadata and decorator for FlowQuery functions."""
2
2
 
3
- from typing import Any, Callable, Dict, List, Optional, TypedDict, Union
4
3
  from dataclasses import dataclass
5
-
4
+ from typing import Any, Callable, Dict, List, Optional, TypedDict, cast
6
5
 
7
6
  # Type definitions
8
7
  FunctionCategory = str # "scalar" | "aggregate" | "predicate" | "async" | string
@@ -54,7 +53,7 @@ class FunctionDefOptions(TypedDict, total=False):
54
53
 
55
54
  class FunctionRegistry:
56
55
  """Centralized registry for function metadata, factories, and async providers."""
57
-
56
+
58
57
  _metadata: Dict[str, FunctionMetadata] = {}
59
58
  _factories: Dict[str, Callable[[], Any]] = {}
60
59
 
@@ -71,15 +70,15 @@ class FunctionRegistry:
71
70
  description=options.get('description', ''),
72
71
  category=options.get('category', 'scalar'),
73
72
  parameters=options.get('parameters', []),
74
- output=options.get('output', {'description': '', 'type': 'any'}),
73
+ output=cast(OutputSchema, options.get('output', {'description': '', 'type': 'any'})),
75
74
  examples=options.get('examples'),
76
75
  notes=options.get('notes'),
77
76
  )
78
77
  cls._metadata[registry_key] = metadata
79
78
 
80
79
  if category != 'predicate':
81
- cls._factories[display_name] = lambda c=constructor: c()
82
- cls._factories[registry_key] = lambda c=constructor: c()
80
+ cls._factories[display_name] = lambda c=constructor: c() # type: ignore[misc]
81
+ cls._factories[registry_key] = lambda c=constructor: c() # type: ignore[misc]
83
82
 
84
83
  @classmethod
85
84
  def get_all_metadata(cls) -> List[FunctionMetadata]:
@@ -103,17 +102,17 @@ class FunctionRegistry:
103
102
  return cls._factories.get(lower_name)
104
103
 
105
104
 
106
- def FunctionDef(options: FunctionDefOptions):
105
+ def FunctionDef(options: FunctionDefOptions) -> Callable[[type], type]:
107
106
  """Class decorator that registers function metadata.
108
-
107
+
109
108
  The function name is derived from the class's constructor.
110
-
109
+
111
110
  Args:
112
111
  options: Function metadata (excluding name)
113
-
112
+
114
113
  Returns:
115
114
  Class decorator
116
-
115
+
117
116
  Example:
118
117
  @FunctionDef({
119
118
  'description': "Adds two numbers",
@@ -1,6 +1,6 @@
1
1
  """Functions introspection function."""
2
2
 
3
- from typing import Any, Dict, List, Optional
3
+ from typing import Any
4
4
 
5
5
  from .function import Function
6
6
  from .function_factory import FunctionFactory
@@ -8,10 +8,18 @@ from .function_metadata import FunctionDef
8
8
 
9
9
 
10
10
  @FunctionDef({
11
- "description": "Lists all registered functions with their metadata. Useful for discovering available functions and their documentation.",
11
+ "description": (
12
+ "Lists all registered functions with their metadata. "
13
+ "Useful for discovering available functions and their documentation."
14
+ ),
12
15
  "category": "scalar",
13
16
  "parameters": [
14
- {"name": "category", "description": "Optional category to filter by (e.g., 'aggregation', 'string', 'math')", "type": "string", "required": False}
17
+ {
18
+ "name": "category",
19
+ "description": "Optional category to filter by (e.g., 'aggregation', 'string', 'math')",
20
+ "type": "string",
21
+ "required": False
22
+ }
15
23
  ],
16
24
  "output": {
17
25
  "description": "Array of function metadata objects",
@@ -35,17 +43,17 @@ from .function_metadata import FunctionDef
35
43
  })
36
44
  class Functions(Function):
37
45
  """Functions introspection function.
38
-
46
+
39
47
  Lists all registered functions with their metadata.
40
48
  """
41
49
 
42
- def __init__(self):
50
+ def __init__(self) -> None:
43
51
  super().__init__("functions")
44
52
  self._expected_parameter_count = None # 0 or 1 parameter
45
53
 
46
54
  def value(self) -> Any:
47
55
  children = self.get_children()
48
-
56
+
49
57
  if len(children) == 0:
50
58
  # Return all functions
51
59
  return FunctionFactory.list_functions()
@@ -2,9 +2,9 @@
2
2
 
3
3
  from typing import Any, List
4
4
 
5
- from .function import Function
6
5
  from ..ast_node import ASTNode
7
6
  from ..expressions.string import String
7
+ from .function import Function
8
8
  from .function_metadata import FunctionDef
9
9
 
10
10
 
@@ -20,11 +20,11 @@ from .function_metadata import FunctionDef
20
20
  })
21
21
  class Join(Function):
22
22
  """Join function.
23
-
23
+
24
24
  Joins an array of strings with a delimiter.
25
25
  """
26
26
 
27
- def __init__(self):
27
+ def __init__(self) -> None:
28
28
  super().__init__("join")
29
29
  self._expected_parameter_count = 2
30
30
 
@@ -1,6 +1,6 @@
1
1
  """Keys function."""
2
2
 
3
- from typing import Any, List
3
+ from typing import Any
4
4
 
5
5
  from .function import Function
6
6
  from .function_metadata import FunctionDef
@@ -17,11 +17,11 @@ from .function_metadata import FunctionDef
17
17
  })
18
18
  class Keys(Function):
19
19
  """Keys function.
20
-
20
+
21
21
  Returns the keys of an object (associative array) as an array.
22
22
  """
23
23
 
24
- def __init__(self):
24
+ def __init__(self) -> None:
25
25
  super().__init__("keys")
26
26
  self._expected_parameter_count = 1
27
27
 
@@ -1,12 +1,13 @@
1
1
  """Base class for predicate functions in FlowQuery."""
2
2
 
3
- from typing import Any, Optional
3
+ from typing import TYPE_CHECKING, Any, Optional
4
4
 
5
5
  from ..ast_node import ASTNode
6
- from ..expressions.expression import Expression
7
- from ..expressions.reference import Reference
8
6
  from .value_holder import ValueHolder
9
7
 
8
+ if TYPE_CHECKING:
9
+ pass
10
+
10
11
 
11
12
  class PredicateFunction(ASTNode):
12
13
  """Base class for predicate functions."""
@@ -21,7 +22,7 @@ class PredicateFunction(ASTNode):
21
22
  return self._name
22
23
 
23
24
  @property
24
- def reference(self) -> Reference:
25
+ def reference(self) -> ASTNode:
25
26
  return self.first_child()
26
27
 
27
28
  @property
@@ -29,12 +30,12 @@ class PredicateFunction(ASTNode):
29
30
  return self.get_children()[1].first_child()
30
31
 
31
32
  @property
32
- def _return(self) -> Expression:
33
+ def _return(self) -> ASTNode:
33
34
  return self.get_children()[2]
34
35
 
35
36
  @property
36
- def where(self) -> Optional['Where']:
37
- from ..operations.where import Where
37
+ def where(self) -> Optional[ASTNode]:
38
+ # Import at runtime to avoid circular dependency
38
39
  if len(self.get_children()) == 4:
39
40
  return self.get_children()[3]
40
41
  return None
@@ -1,13 +1,16 @@
1
1
  """PredicateSum function."""
2
2
 
3
- from typing import Any, List, Optional
3
+ from typing import Any, Optional
4
4
 
5
- from .predicate_function import PredicateFunction
6
5
  from .function_metadata import FunctionDef
6
+ from .predicate_function import PredicateFunction
7
7
 
8
8
 
9
9
  @FunctionDef({
10
- "description": "Calculates the sum of values in an array with optional filtering. Uses list comprehension syntax: sum(variable IN array [WHERE condition] | expression)",
10
+ "description": (
11
+ "Calculates the sum of values in an array with optional filtering. "
12
+ "Uses list comprehension syntax: sum(variable IN array [WHERE condition] | expression)"
13
+ ),
11
14
  "category": "predicate",
12
15
  "parameters": [
13
16
  {"name": "variable", "description": "Variable name to bind each element", "type": "string"},
@@ -23,19 +26,21 @@ from .function_metadata import FunctionDef
23
26
  })
24
27
  class PredicateSum(PredicateFunction):
25
28
  """PredicateSum function.
26
-
29
+
27
30
  Calculates the sum of values in an array with optional filtering.
28
31
  """
29
32
 
30
- def __init__(self):
33
+ def __init__(self) -> None:
31
34
  super().__init__("sum")
32
35
 
33
36
  def value(self) -> Any:
34
- self.reference.referred = self._value_holder
37
+ ref = self.reference
38
+ if hasattr(ref, 'referred'):
39
+ ref.referred = self._value_holder
35
40
  array = self.array.value()
36
41
  if array is None or not isinstance(array, list):
37
42
  raise ValueError("Invalid array for sum function")
38
-
43
+
39
44
  _sum: Optional[Any] = None
40
45
  for item in array:
41
46
  self._value_holder.holder = item
@@ -16,11 +16,11 @@ from .function_metadata import FunctionDef
16
16
  })
17
17
  class Rand(Function):
18
18
  """Rand function.
19
-
19
+
20
20
  Generates a random number between 0 and 1.
21
21
  """
22
22
 
23
- def __init__(self):
23
+ def __init__(self) -> None:
24
24
  super().__init__("rand")
25
25
  self._expected_parameter_count = 0
26
26
 
@@ -1,6 +1,6 @@
1
1
  """Range function."""
2
2
 
3
- from typing import Any, List
3
+ from typing import Any
4
4
 
5
5
  from .function import Function
6
6
  from .function_metadata import FunctionDef
@@ -13,16 +13,21 @@ from .function_metadata import FunctionDef
13
13
  {"name": "start", "description": "Starting number (inclusive)", "type": "number"},
14
14
  {"name": "end", "description": "Ending number (inclusive)", "type": "number"}
15
15
  ],
16
- "output": {"description": "Array of integers from start to end", "type": "array", "items": {"type": "number"}, "example": [1, 2, 3, 4, 5]},
16
+ "output": {
17
+ "description": "Array of integers from start to end",
18
+ "type": "array",
19
+ "items": {"type": "number"},
20
+ "example": [1, 2, 3, 4, 5]
21
+ },
17
22
  "examples": ["WITH range(1, 5) AS nums RETURN nums"]
18
23
  })
19
24
  class Range(Function):
20
25
  """Range function.
21
-
26
+
22
27
  Generates an array of sequential integers.
23
28
  """
24
29
 
25
- def __init__(self):
30
+ def __init__(self) -> None:
26
31
  super().__init__("range")
27
32
  self._expected_parameter_count = 2
28
33
 
@@ -20,11 +20,11 @@ from .function_metadata import FunctionDef
20
20
  })
21
21
  class Replace(Function):
22
22
  """Replace function.
23
-
23
+
24
24
  Replaces occurrences of a pattern in a string.
25
25
  """
26
26
 
27
- def __init__(self):
27
+ def __init__(self) -> None:
28
28
  super().__init__("replace")
29
29
  self._expected_parameter_count = 3
30
30
 
@@ -17,11 +17,11 @@ from .function_metadata import FunctionDef
17
17
  })
18
18
  class Round(Function):
19
19
  """Round function.
20
-
20
+
21
21
  Rounds a number to the nearest integer.
22
22
  """
23
23
 
24
- def __init__(self):
24
+ def __init__(self) -> None:
25
25
  super().__init__("round")
26
26
  self._expected_parameter_count = 1
27
27
 
@@ -17,11 +17,11 @@ from .function_metadata import FunctionDef
17
17
  })
18
18
  class Size(Function):
19
19
  """Size function.
20
-
20
+
21
21
  Returns the length of an array or string.
22
22
  """
23
23
 
24
- def __init__(self):
24
+ def __init__(self) -> None:
25
25
  super().__init__("size")
26
26
  self._expected_parameter_count = 1
27
27
 
@@ -2,9 +2,9 @@
2
2
 
3
3
  from typing import Any, List
4
4
 
5
- from .function import Function
6
5
  from ..ast_node import ASTNode
7
6
  from ..expressions.string import String
7
+ from .function import Function
8
8
  from .function_metadata import FunctionDef
9
9
 
10
10
 
@@ -15,16 +15,21 @@ from .function_metadata import FunctionDef
15
15
  {"name": "text", "description": "String to split", "type": "string"},
16
16
  {"name": "delimiter", "description": "Delimiter to split by", "type": "string"}
17
17
  ],
18
- "output": {"description": "Array of string parts", "type": "array", "items": {"type": "string"}, "example": ["a", "b", "c"]},
18
+ "output": {
19
+ "description": "Array of string parts",
20
+ "type": "array",
21
+ "items": {"type": "string"},
22
+ "example": ["a", "b", "c"]
23
+ },
19
24
  "examples": ["WITH 'a,b,c' AS s RETURN split(s, ',')"]
20
25
  })
21
26
  class Split(Function):
22
27
  """Split function.
23
-
28
+
24
29
  Splits a string into an array by a delimiter.
25
30
  """
26
31
 
27
- def __init__(self):
32
+ def __init__(self) -> None:
28
33
  super().__init__("split")
29
34
  self._expected_parameter_count = 2
30
35
 
@@ -3,9 +3,9 @@
3
3
  import json
4
4
  from typing import Any, List
5
5
 
6
- from .function import Function
7
6
  from ..ast_node import ASTNode
8
7
  from ..expressions.number import Number
8
+ from .function import Function
9
9
  from .function_metadata import FunctionDef
10
10
 
11
11
 
@@ -20,11 +20,11 @@ from .function_metadata import FunctionDef
20
20
  })
21
21
  class Stringify(Function):
22
22
  """Stringify function.
23
-
23
+
24
24
  Converts a value to its JSON string representation.
25
25
  """
26
26
 
27
- def __init__(self):
27
+ def __init__(self) -> None:
28
28
  super().__init__("stringify")
29
29
  self._expected_parameter_count = 2
30
30
 
@@ -3,14 +3,14 @@
3
3
  from typing import Any
4
4
 
5
5
  from .aggregate_function import AggregateFunction
6
- from .reducer_element import ReducerElement
7
6
  from .function_metadata import FunctionDef
7
+ from .reducer_element import ReducerElement
8
8
 
9
9
 
10
10
  class SumReducerElement(ReducerElement):
11
11
  """Reducer element for Sum aggregate function."""
12
12
 
13
- def __init__(self):
13
+ def __init__(self) -> None:
14
14
  self._value: Any = None
15
15
 
16
16
  @property
@@ -36,11 +36,11 @@ class SumReducerElement(ReducerElement):
36
36
  })
37
37
  class Sum(AggregateFunction):
38
38
  """Sum aggregate function.
39
-
39
+
40
40
  Calculates the sum of numeric values across grouped rows.
41
41
  """
42
42
 
43
- def __init__(self):
43
+ def __init__(self) -> None:
44
44
  super().__init__("sum")
45
45
  self._expected_parameter_count = 1
46
46
 
@@ -18,11 +18,11 @@ from .function_metadata import FunctionDef
18
18
  })
19
19
  class ToJson(Function):
20
20
  """ToJson function.
21
-
21
+
22
22
  Parses a JSON string into an object.
23
23
  """
24
24
 
25
- def __init__(self):
25
+ def __init__(self) -> None:
26
26
  super().__init__("tojson")
27
27
  self._expected_parameter_count = 1
28
28
 
@@ -21,17 +21,17 @@ from .function_metadata import FunctionDef
21
21
  })
22
22
  class Type(Function):
23
23
  """Type function.
24
-
24
+
25
25
  Returns the type of a value as a string.
26
26
  """
27
27
 
28
- def __init__(self):
28
+ def __init__(self) -> None:
29
29
  super().__init__("type")
30
30
  self._expected_parameter_count = 1
31
31
 
32
32
  def value(self) -> Any:
33
33
  val = self.get_children()[0].value()
34
-
34
+
35
35
  if val is None:
36
36
  return "null"
37
37
  if isinstance(val, list):
@@ -8,7 +8,7 @@ from ..ast_node import ASTNode
8
8
  class ValueHolder(ASTNode):
9
9
  """Holds a value that can be set and retrieved."""
10
10
 
11
- def __init__(self):
11
+ def __init__(self) -> None:
12
12
  super().__init__()
13
13
  self._holder: Any = None
14
14
 
@@ -1,10 +1,10 @@
1
1
  """Logic module for FlowQuery parsing."""
2
2
 
3
3
  from .case import Case
4
- from .when import When
5
- from .then import Then
6
4
  from .else_ import Else
7
5
  from .end import End
6
+ from .then import Then
7
+ from .when import When
8
8
 
9
9
  __all__ = [
10
10
  "Case",
@@ -4,7 +4,6 @@ from typing import Any
4
4
 
5
5
  from ..ast_node import ASTNode
6
6
  from .when import When
7
- from .then import Then
8
7
 
9
8
 
10
9
  class Case(ASTNode):
@@ -1,10 +1,12 @@
1
1
  """Represents a WHEN clause in a CASE expression."""
2
2
 
3
+ from typing import Any
4
+
3
5
  from ..ast_node import ASTNode
4
6
 
5
7
 
6
8
  class When(ASTNode):
7
9
  """Represents a WHEN clause in a CASE expression."""
8
10
 
9
- def value(self) -> bool:
11
+ def value(self) -> Any:
10
12
  return self.get_children()[0].value()
@@ -1,20 +1,20 @@
1
1
  """Operations module for FlowQuery parsing."""
2
2
 
3
- from .operation import Operation
4
- from .projection import Projection
5
- from .return_op import Return
6
- from .with_op import With
7
- from .unwind import Unwind
8
- from .load import Load
9
- from .where import Where
10
- from .limit import Limit
11
3
  from .aggregated_return import AggregatedReturn
12
4
  from .aggregated_with import AggregatedWith
13
5
  from .call import Call
14
- from .group_by import GroupBy
15
- from .match import Match
16
6
  from .create_node import CreateNode
17
7
  from .create_relationship import CreateRelationship
8
+ from .group_by import GroupBy
9
+ from .limit import Limit
10
+ from .load import Load
11
+ from .match import Match
12
+ from .operation import Operation
13
+ from .projection import Projection
14
+ from .return_op import Return
15
+ from .unwind import Unwind
16
+ from .where import Where
17
+ from .with_op import With
18
18
 
19
19
  __all__ = [
20
20
  "Operation",
@@ -1,16 +1,14 @@
1
- """Represents an aggregated RETURN operation."""
2
-
3
1
  from typing import Any, Dict, List
4
2
 
5
- from .return_op import Return
3
+ from ..ast_node import ASTNode
6
4
  from .group_by import GroupBy
7
- from ..expressions.expression import Expression
5
+ from .return_op import Return
8
6
 
9
7
 
10
8
  class AggregatedReturn(Return):
11
9
  """Represents an aggregated RETURN operation that groups and reduces values."""
12
10
 
13
- def __init__(self, expressions):
11
+ def __init__(self, expressions: List[ASTNode]) -> None:
14
12
  super().__init__(expressions)
15
13
  self._group_by = GroupBy(self.children)
16
14
 
@@ -1,14 +1,14 @@
1
- """Represents an aggregated WITH operation."""
1
+ from typing import List
2
2
 
3
- from .return_op import Return
3
+ from ..ast_node import ASTNode
4
4
  from .group_by import GroupBy
5
- from ..expressions.expression import Expression
5
+ from .return_op import Return
6
6
 
7
7
 
8
8
  class AggregatedWith(Return):
9
9
  """Represents an aggregated WITH operation that groups and reduces values."""
10
10
 
11
- def __init__(self, expressions):
11
+ def __init__(self, expressions: List[ASTNode]) -> None:
12
12
  super().__init__(expressions)
13
13
  self._group_by = GroupBy(self.children)
14
14
 
@@ -2,19 +2,18 @@
2
2
 
3
3
  from typing import Any, Dict, List, Optional
4
4
 
5
- from ..expressions.expression import Expression
5
+ from ..ast_node import ASTNode
6
6
  from ..expressions.expression_map import ExpressionMap
7
7
  from ..functions.async_function import AsyncFunction
8
8
  from .projection import Projection
9
9
 
10
-
11
10
  DEFAULT_VARIABLE_NAME = "value"
12
11
 
13
12
 
14
13
  class Call(Projection):
15
14
  """Represents a CALL operation for invoking async functions."""
16
15
 
17
- def __init__(self):
16
+ def __init__(self) -> None:
18
17
  super().__init__([])
19
18
  self._function: Optional[AsyncFunction] = None
20
19
  self._map = ExpressionMap()
@@ -29,13 +28,13 @@ class Call(Projection):
29
28
  self._function = async_function
30
29
 
31
30
  @property
32
- def yielded(self) -> List[Expression]:
31
+ def yielded(self) -> List[ASTNode]:
33
32
  return self.children
34
33
 
35
34
  @yielded.setter
36
- def yielded(self, expressions: List[Expression]) -> None:
35
+ def yielded(self, expressions: List[ASTNode]) -> None:
37
36
  self.children = expressions
38
- self._map.set_map(expressions)
37
+ self._map.set_map(expressions) # ExpressionMap accepts list of expressions
39
38
 
40
39
  @property
41
40
  def has_yield(self) -> bool:
@@ -44,7 +43,7 @@ class Call(Projection):
44
43
  async def run(self) -> None:
45
44
  if self._function is None:
46
45
  raise ValueError("No function set for Call operation.")
47
-
46
+
48
47
  args = self._function.get_arguments()
49
48
  async for item in self._function.generate(*args):
50
49
  if not self.is_last:
@@ -2,20 +2,22 @@
2
2
 
3
3
  from typing import Any, Dict, List
4
4
 
5
- from .operation import Operation
5
+ from ...graph.database import Database
6
+ from ...graph.node import Node
6
7
  from ..ast_node import ASTNode
8
+ from .operation import Operation
7
9
 
8
10
 
9
11
  class CreateNode(Operation):
10
12
  """Represents a CREATE operation for creating virtual nodes."""
11
13
 
12
- def __init__(self, node, statement: ASTNode):
14
+ def __init__(self, node: Node, statement: ASTNode) -> None:
13
15
  super().__init__()
14
16
  self._node = node
15
17
  self._statement = statement
16
18
 
17
19
  @property
18
- def node(self):
20
+ def node(self) -> Node:
19
21
  return self._node
20
22
 
21
23
  @property
@@ -25,7 +27,6 @@ class CreateNode(Operation):
25
27
  async def run(self) -> None:
26
28
  if self._node is None:
27
29
  raise ValueError("Node is null")
28
- from ...graph.database import Database
29
30
  db = Database.get_instance()
30
31
  db.add_node(self._node, self._statement)
31
32