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
@@ -39,7 +39,7 @@ class Operator(ASTNode, ABC):
39
39
 
40
40
 
41
41
  class Add(Operator):
42
- def __init__(self):
42
+ def __init__(self) -> None:
43
43
  super().__init__(1, True)
44
44
 
45
45
  def value(self) -> Any:
@@ -47,7 +47,7 @@ class Add(Operator):
47
47
 
48
48
 
49
49
  class Subtract(Operator):
50
- def __init__(self):
50
+ def __init__(self) -> None:
51
51
  super().__init__(1, True)
52
52
 
53
53
  def value(self) -> Any:
@@ -55,7 +55,7 @@ class Subtract(Operator):
55
55
 
56
56
 
57
57
  class Multiply(Operator):
58
- def __init__(self):
58
+ def __init__(self) -> None:
59
59
  super().__init__(2, True)
60
60
 
61
61
  def value(self) -> Any:
@@ -63,7 +63,7 @@ class Multiply(Operator):
63
63
 
64
64
 
65
65
  class Divide(Operator):
66
- def __init__(self):
66
+ def __init__(self) -> None:
67
67
  super().__init__(2, True)
68
68
 
69
69
  def value(self) -> Any:
@@ -71,7 +71,7 @@ class Divide(Operator):
71
71
 
72
72
 
73
73
  class Modulo(Operator):
74
- def __init__(self):
74
+ def __init__(self) -> None:
75
75
  super().__init__(2, True)
76
76
 
77
77
  def value(self) -> Any:
@@ -79,7 +79,7 @@ class Modulo(Operator):
79
79
 
80
80
 
81
81
  class Power(Operator):
82
- def __init__(self):
82
+ def __init__(self) -> None:
83
83
  super().__init__(3, False)
84
84
 
85
85
  def value(self) -> Any:
@@ -87,7 +87,7 @@ class Power(Operator):
87
87
 
88
88
 
89
89
  class Equals(Operator):
90
- def __init__(self):
90
+ def __init__(self) -> None:
91
91
  super().__init__(0, True)
92
92
 
93
93
  def value(self) -> int:
@@ -95,7 +95,7 @@ class Equals(Operator):
95
95
 
96
96
 
97
97
  class NotEquals(Operator):
98
- def __init__(self):
98
+ def __init__(self) -> None:
99
99
  super().__init__(0, True)
100
100
 
101
101
  def value(self) -> int:
@@ -103,7 +103,7 @@ class NotEquals(Operator):
103
103
 
104
104
 
105
105
  class GreaterThan(Operator):
106
- def __init__(self):
106
+ def __init__(self) -> None:
107
107
  super().__init__(0, True)
108
108
 
109
109
  def value(self) -> int:
@@ -111,7 +111,7 @@ class GreaterThan(Operator):
111
111
 
112
112
 
113
113
  class LessThan(Operator):
114
- def __init__(self):
114
+ def __init__(self) -> None:
115
115
  super().__init__(0, True)
116
116
 
117
117
  def value(self) -> int:
@@ -119,7 +119,7 @@ class LessThan(Operator):
119
119
 
120
120
 
121
121
  class GreaterThanOrEqual(Operator):
122
- def __init__(self):
122
+ def __init__(self) -> None:
123
123
  super().__init__(0, True)
124
124
 
125
125
  def value(self) -> int:
@@ -127,7 +127,7 @@ class GreaterThanOrEqual(Operator):
127
127
 
128
128
 
129
129
  class LessThanOrEqual(Operator):
130
- def __init__(self):
130
+ def __init__(self) -> None:
131
131
  super().__init__(0, True)
132
132
 
133
133
  def value(self) -> int:
@@ -135,7 +135,7 @@ class LessThanOrEqual(Operator):
135
135
 
136
136
 
137
137
  class And(Operator):
138
- def __init__(self):
138
+ def __init__(self) -> None:
139
139
  super().__init__(-1, True)
140
140
 
141
141
  def value(self) -> int:
@@ -143,7 +143,7 @@ class And(Operator):
143
143
 
144
144
 
145
145
  class Or(Operator):
146
- def __init__(self):
146
+ def __init__(self) -> None:
147
147
  super().__init__(-1, True)
148
148
 
149
149
  def value(self) -> int:
@@ -151,7 +151,7 @@ class Or(Operator):
151
151
 
152
152
 
153
153
  class Not(Operator):
154
- def __init__(self):
154
+ def __init__(self) -> None:
155
155
  super().__init__(0, True)
156
156
 
157
157
  def is_operator(self) -> bool:
@@ -162,7 +162,7 @@ class Not(Operator):
162
162
 
163
163
 
164
164
  class Is(Operator):
165
- def __init__(self):
165
+ def __init__(self) -> None:
166
166
  super().__init__(-1, True)
167
167
 
168
168
  def value(self) -> int:
@@ -8,9 +8,9 @@ from .identifier import Identifier
8
8
 
9
9
  class Reference(Identifier):
10
10
  """Represents a reference to a previously defined variable or expression.
11
-
11
+
12
12
  References point to values defined earlier in the query (e.g., in WITH or LOAD statements).
13
-
13
+
14
14
  Example:
15
15
  ref = Reference("myVar", previous_node)
16
16
  print(ref.value()) # Gets value from referred node
@@ -18,7 +18,7 @@ class Reference(Identifier):
18
18
 
19
19
  def __init__(self, value: str, referred: Optional[ASTNode] = None):
20
20
  """Creates a new Reference to a variable.
21
-
21
+
22
22
  Args:
23
23
  value: The identifier name
24
24
  referred: The node this reference points to (optional)
@@ -5,7 +5,7 @@ from ..ast_node import ASTNode
5
5
 
6
6
  class String(ASTNode):
7
7
  """Represents a string literal in the AST.
8
-
8
+
9
9
  Example:
10
10
  s = String("hello")
11
11
  print(s.value()) # "hello"
@@ -13,7 +13,7 @@ class String(ASTNode):
13
13
 
14
14
  def __init__(self, value: str):
15
15
  """Creates a new String node with the given value.
16
-
16
+
17
17
  Args:
18
18
  value: The string value
19
19
  """
@@ -1,41 +1,41 @@
1
1
  """Functions module for FlowQuery parsing."""
2
2
 
3
- from .function import Function
4
3
  from .aggregate_function import AggregateFunction
5
4
  from .async_function import AsyncFunction
6
- from .predicate_function import PredicateFunction
7
- from .reducer_element import ReducerElement
8
- from .value_holder import ValueHolder
5
+ from .avg import Avg
6
+ from .collect import Collect
7
+ from .function import Function
8
+ from .function_factory import FunctionFactory
9
9
  from .function_metadata import (
10
10
  FunctionCategory,
11
- ParameterSchema,
12
- OutputSchema,
13
- FunctionMetadata,
14
11
  FunctionDef,
15
12
  FunctionDefOptions,
16
- get_registered_function_metadata,
17
- get_registered_function_factory,
13
+ FunctionMetadata,
14
+ OutputSchema,
15
+ ParameterSchema,
18
16
  get_function_metadata,
17
+ get_registered_function_factory,
18
+ get_registered_function_metadata,
19
19
  )
20
- from .function_factory import FunctionFactory
21
-
22
- # Built-in functions
23
- from .sum import Sum
24
- from .avg import Avg
25
- from .collect import Collect
20
+ from .functions import Functions
26
21
  from .join import Join
27
22
  from .keys import Keys
23
+ from .predicate_function import PredicateFunction
24
+ from .predicate_sum import PredicateSum
28
25
  from .rand import Rand
29
26
  from .range_ import Range
27
+ from .reducer_element import ReducerElement
30
28
  from .replace import Replace
31
29
  from .round_ import Round
32
30
  from .size import Size
33
31
  from .split import Split
34
32
  from .stringify import Stringify
33
+
34
+ # Built-in functions
35
+ from .sum import Sum
35
36
  from .to_json import ToJson
36
37
  from .type_ import Type
37
- from .functions import Functions
38
- from .predicate_sum import PredicateSum
38
+ from .value_holder import ValueHolder
39
39
 
40
40
  __all__ = [
41
41
  # Base classes
@@ -8,10 +8,10 @@ from .reducer_element import ReducerElement
8
8
 
9
9
  class AggregateFunction(Function):
10
10
  """Base class for aggregate functions that reduce multiple values to a single value.
11
-
11
+
12
12
  Aggregate functions like SUM, AVG, and COLLECT process multiple input values
13
13
  and produce a single output. They cannot be nested within other aggregate functions.
14
-
14
+
15
15
  Example:
16
16
  sum_func = Sum()
17
17
  # Used in: RETURN SUM(values)
@@ -19,19 +19,19 @@ class AggregateFunction(Function):
19
19
 
20
20
  def __init__(self, name: Optional[str] = None):
21
21
  """Creates a new AggregateFunction with the given name.
22
-
22
+
23
23
  Args:
24
24
  name: The function name
25
25
  """
26
26
  super().__init__(name)
27
27
  self._overridden: Any = None
28
28
 
29
- def reduce(self, value: ReducerElement) -> None:
29
+ def reduce(self, value: Any) -> None:
30
30
  """Processes a value during the aggregation phase.
31
-
31
+
32
32
  Args:
33
33
  value: The element to aggregate
34
-
34
+
35
35
  Raises:
36
36
  NotImplementedError: If not implemented by subclass
37
37
  """
@@ -39,10 +39,10 @@ class AggregateFunction(Function):
39
39
 
40
40
  def element(self) -> ReducerElement:
41
41
  """Creates a reducer element for this aggregate function.
42
-
42
+
43
43
  Returns:
44
44
  A ReducerElement instance
45
-
45
+
46
46
  Raises:
47
47
  NotImplementedError: If not implemented by subclass
48
48
  """
@@ -8,10 +8,10 @@ from .function import Function
8
8
 
9
9
  class AsyncFunction(Function):
10
10
  """Represents an async data provider function call for use in LOAD operations.
11
-
11
+
12
12
  This class holds the function name and arguments, and provides async iteration
13
13
  over the results from a registered async data provider.
14
-
14
+
15
15
  Example:
16
16
  # Used in: LOAD JSON FROM myDataSource('arg1', 'arg2') AS data
17
17
  async_func = AsyncFunction("myDataSource")
@@ -27,7 +27,7 @@ class AsyncFunction(Function):
27
27
  @parameters.setter
28
28
  def parameters(self, nodes: List[ASTNode]) -> None:
29
29
  """Sets the function parameters.
30
-
30
+
31
31
  Args:
32
32
  nodes: Array of AST nodes representing the function arguments
33
33
  """
@@ -36,7 +36,7 @@ class AsyncFunction(Function):
36
36
  def get_arguments(self) -> List[Any]:
37
37
  """Evaluates all parameters and returns their values.
38
38
  Used by the framework to pass arguments to generate().
39
-
39
+
40
40
  Returns:
41
41
  Array of parameter values
42
42
  """
@@ -44,19 +44,22 @@ class AsyncFunction(Function):
44
44
 
45
45
  async def generate(self, *args: Any) -> AsyncGenerator[Any, None]:
46
46
  """Generates the async data provider function results.
47
-
47
+
48
48
  Subclasses override this method with their own typed parameters.
49
49
  The framework automatically evaluates the AST children and spreads
50
50
  them as arguments when calling this method.
51
-
51
+
52
52
  Args:
53
53
  args: Arguments passed from the query (e.g., myFunc(arg1, arg2))
54
-
54
+
55
55
  Yields:
56
56
  Data items from the async provider
57
-
57
+
58
58
  Raises:
59
59
  NotImplementedError: If the function is not registered as an async provider
60
60
  """
61
61
  raise NotImplementedError("generate method must be overridden in subclasses.")
62
- yield # Make this a generator
62
+ # Note: yield is here only to make this a generator function
63
+ # It will never be reached due to the raise above
64
+ if False: # pragma: no cover
65
+ yield # Make this a generator
@@ -3,14 +3,14 @@
3
3
  from typing import Optional
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 AvgReducerElement(ReducerElement):
11
11
  """Reducer element for Avg aggregate function."""
12
12
 
13
- def __init__(self):
13
+ def __init__(self) -> None:
14
14
  self._count: int = 0
15
15
  self._sum: Optional[float] = None
16
16
 
@@ -40,11 +40,11 @@ class AvgReducerElement(ReducerElement):
40
40
  })
41
41
  class Avg(AggregateFunction):
42
42
  """Avg aggregate function.
43
-
43
+
44
44
  Calculates the average of numeric values across grouped rows.
45
45
  """
46
46
 
47
- def __init__(self):
47
+ def __init__(self) -> None:
48
48
  super().__init__("avg")
49
49
  self._expected_parameter_count = 1
50
50
 
@@ -1,17 +1,17 @@
1
1
  """Collect aggregate function."""
2
2
 
3
- from typing import Any, Dict, List, Union
4
3
  import json
4
+ from typing import Any, Dict, List, Union
5
5
 
6
6
  from .aggregate_function import AggregateFunction
7
- from .reducer_element import ReducerElement
8
7
  from .function_metadata import FunctionDef
8
+ from .reducer_element import ReducerElement
9
9
 
10
10
 
11
11
  class CollectReducerElement(ReducerElement):
12
12
  """Reducer element for Collect aggregate function."""
13
13
 
14
- def __init__(self):
14
+ def __init__(self) -> None:
15
15
  self._value: List[Any] = []
16
16
 
17
17
  @property
@@ -26,7 +26,7 @@ class CollectReducerElement(ReducerElement):
26
26
  class DistinctCollectReducerElement(ReducerElement):
27
27
  """Reducer element for Collect aggregate function with DISTINCT."""
28
28
 
29
- def __init__(self):
29
+ def __init__(self) -> None:
30
30
  self._value: Dict[str, Any] = {}
31
31
 
32
32
  @property
@@ -51,11 +51,11 @@ class DistinctCollectReducerElement(ReducerElement):
51
51
  })
52
52
  class Collect(AggregateFunction):
53
53
  """Collect aggregate function.
54
-
54
+
55
55
  Collects values into an array across grouped rows.
56
56
  """
57
57
 
58
- def __init__(self):
58
+ def __init__(self) -> None:
59
59
  super().__init__("collect")
60
60
  self._expected_parameter_count = 1
61
61
  self._distinct: bool = False
@@ -1,16 +1,16 @@
1
1
  """Base class for all functions in FlowQuery."""
2
2
 
3
- from typing import List, Optional, Any
3
+ from typing import List, Optional
4
4
 
5
5
  from ..ast_node import ASTNode
6
6
 
7
7
 
8
8
  class Function(ASTNode):
9
9
  """Base class for all functions in FlowQuery.
10
-
10
+
11
11
  Functions can have parameters and may support the DISTINCT modifier.
12
12
  Subclasses implement specific function logic.
13
-
13
+
14
14
  Example:
15
15
  func = FunctionFactory.create("sum")
16
16
  func.parameters = [expression1, expression2]
@@ -18,7 +18,7 @@ class Function(ASTNode):
18
18
 
19
19
  def __init__(self, name: Optional[str] = None):
20
20
  """Creates a new Function with the given name.
21
-
21
+
22
22
  Args:
23
23
  name: The function name
24
24
  """
@@ -35,10 +35,10 @@ class Function(ASTNode):
35
35
  @parameters.setter
36
36
  def parameters(self, nodes: List[ASTNode]) -> None:
37
37
  """Sets the function parameters.
38
-
38
+
39
39
  Args:
40
40
  nodes: Array of AST nodes representing the function arguments
41
-
41
+
42
42
  Raises:
43
43
  ValueError: If the number of parameters doesn't match expected count
44
44
  """
@@ -2,9 +2,6 @@
2
2
 
3
3
  from typing import Any, Callable, Dict, List, Optional
4
4
 
5
- from .function import Function
6
- from .async_function import AsyncFunction
7
- from .predicate_function import PredicateFunction
8
5
  from .function_metadata import (
9
6
  FunctionMetadata,
10
7
  get_function_metadata,
@@ -15,23 +12,23 @@ from .function_metadata import (
15
12
 
16
13
  class FunctionFactory:
17
14
  """Factory for creating function instances by name.
18
-
15
+
19
16
  All functions are registered via the @FunctionDef decorator.
20
17
  Maps function names (case-insensitive) to their corresponding implementation classes.
21
18
  Supports built-in functions like sum, avg, collect, range, split, join, etc.
22
-
19
+
23
20
  Example:
24
21
  sum_func = FunctionFactory.create("sum")
25
22
  avg_func = FunctionFactory.create("AVG")
26
23
  """
27
24
 
28
25
  @staticmethod
29
- def get_async_provider(name: str) -> Optional[Callable]:
26
+ def get_async_provider(name: str) -> Optional[Callable[..., Any]]:
30
27
  """Gets an async data provider by name.
31
-
28
+
32
29
  Args:
33
30
  name: The function name (case-insensitive)
34
-
31
+
35
32
  Returns:
36
33
  The async data provider, or None if not found
37
34
  """
@@ -40,10 +37,10 @@ class FunctionFactory:
40
37
  @staticmethod
41
38
  def is_async_provider(name: str) -> bool:
42
39
  """Checks if a function name is registered as an async data provider.
43
-
40
+
44
41
  Args:
45
42
  name: The function name (case-insensitive)
46
-
43
+
47
44
  Returns:
48
45
  True if the function is an async data provider
49
46
  """
@@ -52,10 +49,10 @@ class FunctionFactory:
52
49
  @staticmethod
53
50
  def get_metadata(name: str) -> Optional[FunctionMetadata]:
54
51
  """Gets metadata for a specific function.
55
-
52
+
56
53
  Args:
57
54
  name: The function name (case-insensitive)
58
-
55
+
59
56
  Returns:
60
57
  The function metadata, or None if not found
61
58
  """
@@ -68,17 +65,17 @@ class FunctionFactory:
68
65
  sync_only: bool = False
69
66
  ) -> List[FunctionMetadata]:
70
67
  """Lists all registered functions with their metadata.
71
-
68
+
72
69
  Args:
73
70
  category: Optional category filter
74
71
  async_only: If True, only return async functions
75
72
  sync_only: If True, only return sync functions
76
-
73
+
77
74
  Returns:
78
75
  Array of function metadata
79
76
  """
80
77
  result: List[FunctionMetadata] = []
81
-
78
+
82
79
  for meta in get_registered_function_metadata():
83
80
  if category and meta.category != category:
84
81
  continue
@@ -87,13 +84,13 @@ class FunctionFactory:
87
84
  if sync_only and meta.category == "async":
88
85
  continue
89
86
  result.append(meta)
90
-
87
+
91
88
  return result
92
89
 
93
90
  @staticmethod
94
91
  def list_function_names() -> List[str]:
95
92
  """Lists all registered function names.
96
-
93
+
97
94
  Returns:
98
95
  Array of function names
99
96
  """
@@ -102,7 +99,7 @@ class FunctionFactory:
102
99
  @staticmethod
103
100
  def to_json() -> Dict[str, Any]:
104
101
  """Gets all function metadata as a JSON-serializable object for LLM consumption.
105
-
102
+
106
103
  Returns:
107
104
  Object with functions grouped by category
108
105
  """
@@ -111,58 +108,58 @@ class FunctionFactory:
111
108
  return {"functions": functions, "categories": categories}
112
109
 
113
110
  @staticmethod
114
- def create(name: str) -> Function:
111
+ def create(name: str) -> Any:
115
112
  """Creates a function instance by name.
116
-
113
+
117
114
  Args:
118
115
  name: The function name (case-insensitive)
119
-
116
+
120
117
  Returns:
121
118
  A Function instance of the appropriate type
122
-
119
+
123
120
  Raises:
124
121
  ValueError: If the function name is not registered
125
122
  """
126
123
  lower_name = name.lower()
127
-
124
+
128
125
  # Check decorator-registered functions
129
126
  decorator_factory = get_registered_function_factory(lower_name)
130
127
  if decorator_factory:
131
128
  return decorator_factory()
132
-
129
+
133
130
  raise ValueError(f"Unknown function: {name}")
134
131
 
135
132
  @staticmethod
136
- def create_predicate(name: str) -> PredicateFunction:
133
+ def create_predicate(name: str) -> Any:
137
134
  """Creates a predicate function instance by name.
138
-
135
+
139
136
  Args:
140
137
  name: The function name (case-insensitive)
141
-
138
+
142
139
  Returns:
143
140
  A PredicateFunction instance of the appropriate type
144
-
141
+
145
142
  Raises:
146
143
  ValueError: If the predicate function name is not registered
147
144
  """
148
145
  lower_name = name.lower()
149
-
146
+
150
147
  decorator_factory = get_registered_function_factory(lower_name, "predicate")
151
148
  if decorator_factory:
152
149
  return decorator_factory()
153
-
150
+
154
151
  raise ValueError(f"Unknown predicate function: {name}")
155
152
 
156
153
  @staticmethod
157
- def create_async(name: str) -> AsyncFunction:
154
+ def create_async(name: str) -> Any:
158
155
  """Creates an async function instance by name.
159
-
156
+
160
157
  Args:
161
158
  name: The function name (case-insensitive)
162
-
159
+
163
160
  Returns:
164
161
  An AsyncFunction instance of the appropriate type
165
-
162
+
166
163
  Raises:
167
164
  ValueError: If the async function name is not registered
168
165
  """