flowquery 1.0.15 → 1.0.17

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 (333) hide show
  1. package/.github/workflows/python-publish.yml +97 -0
  2. package/dist/compute/runner.d.ts +3 -2
  3. package/dist/compute/runner.d.ts.map +1 -1
  4. package/dist/compute/runner.js +7 -7
  5. package/dist/compute/runner.js.map +1 -1
  6. package/dist/flowquery.min.js +1 -1
  7. package/dist/graph/data.d.ts +31 -0
  8. package/dist/graph/data.d.ts.map +1 -0
  9. package/dist/graph/data.js +110 -0
  10. package/dist/graph/data.js.map +1 -0
  11. package/dist/graph/database.d.ts +20 -0
  12. package/dist/graph/database.d.ts.map +1 -0
  13. package/dist/graph/database.js +77 -0
  14. package/dist/graph/database.js.map +1 -0
  15. package/dist/graph/hops.d.ts +11 -0
  16. package/dist/graph/hops.d.ts.map +1 -0
  17. package/dist/graph/hops.js +25 -0
  18. package/dist/graph/hops.js.map +1 -0
  19. package/dist/graph/node.d.ts +35 -0
  20. package/dist/graph/node.d.ts.map +1 -0
  21. package/dist/graph/node.js +113 -0
  22. package/dist/graph/node.js.map +1 -0
  23. package/dist/graph/node_data.d.ts +11 -0
  24. package/dist/graph/node_data.d.ts.map +1 -0
  25. package/dist/graph/node_data.js +20 -0
  26. package/dist/graph/node_data.js.map +1 -0
  27. package/dist/graph/node_reference.d.ts +10 -0
  28. package/dist/graph/node_reference.d.ts.map +1 -0
  29. package/dist/graph/node_reference.js +52 -0
  30. package/dist/graph/node_reference.js.map +1 -0
  31. package/dist/graph/pattern.d.ts +18 -0
  32. package/dist/graph/pattern.d.ts.map +1 -0
  33. package/dist/graph/pattern.js +114 -0
  34. package/dist/graph/pattern.js.map +1 -0
  35. package/dist/graph/pattern_expression.d.ts +14 -0
  36. package/dist/graph/pattern_expression.d.ts.map +1 -0
  37. package/dist/graph/pattern_expression.js +58 -0
  38. package/dist/graph/pattern_expression.js.map +1 -0
  39. package/dist/graph/patterns.d.ts +11 -0
  40. package/dist/graph/patterns.d.ts.map +1 -0
  41. package/dist/graph/patterns.js +49 -0
  42. package/dist/graph/patterns.js.map +1 -0
  43. package/dist/graph/physical_node.d.ts +10 -0
  44. package/dist/graph/physical_node.d.ts.map +1 -0
  45. package/dist/graph/physical_node.js +40 -0
  46. package/dist/graph/physical_node.js.map +1 -0
  47. package/dist/graph/physical_relationship.d.ts +10 -0
  48. package/dist/graph/physical_relationship.d.ts.map +1 -0
  49. package/dist/graph/physical_relationship.js +40 -0
  50. package/dist/graph/physical_relationship.js.map +1 -0
  51. package/dist/graph/relationship.d.ts +40 -0
  52. package/dist/graph/relationship.d.ts.map +1 -0
  53. package/dist/graph/relationship.js +124 -0
  54. package/dist/graph/relationship.js.map +1 -0
  55. package/dist/graph/relationship_data.d.ts +12 -0
  56. package/dist/graph/relationship_data.d.ts.map +1 -0
  57. package/dist/graph/relationship_data.js +40 -0
  58. package/dist/graph/relationship_data.js.map +1 -0
  59. package/dist/graph/relationship_match_collector.d.ts +19 -0
  60. package/dist/graph/relationship_match_collector.d.ts.map +1 -0
  61. package/dist/graph/relationship_match_collector.js +55 -0
  62. package/dist/graph/relationship_match_collector.js.map +1 -0
  63. package/dist/graph/relationship_reference.d.ts +8 -0
  64. package/dist/graph/relationship_reference.d.ts.map +1 -0
  65. package/dist/graph/relationship_reference.js +37 -0
  66. package/dist/graph/relationship_reference.js.map +1 -0
  67. package/dist/parsing/base_parser.d.ts +1 -0
  68. package/dist/parsing/base_parser.d.ts.map +1 -1
  69. package/dist/parsing/base_parser.js +4 -1
  70. package/dist/parsing/base_parser.js.map +1 -1
  71. package/dist/parsing/context.d.ts +2 -2
  72. package/dist/parsing/context.js +5 -5
  73. package/dist/parsing/expressions/boolean.d.ts +8 -0
  74. package/dist/parsing/expressions/boolean.d.ts.map +1 -0
  75. package/dist/parsing/expressions/boolean.js +26 -0
  76. package/dist/parsing/expressions/boolean.js.map +1 -0
  77. package/dist/parsing/expressions/expression.d.ts +4 -1
  78. package/dist/parsing/expressions/expression.d.ts.map +1 -1
  79. package/dist/parsing/expressions/expression.js +15 -8
  80. package/dist/parsing/expressions/expression.js.map +1 -1
  81. package/dist/parsing/expressions/expression_map.d.ts +1 -0
  82. package/dist/parsing/expressions/expression_map.d.ts.map +1 -1
  83. package/dist/parsing/expressions/expression_map.js +3 -0
  84. package/dist/parsing/expressions/expression_map.js.map +1 -1
  85. package/dist/parsing/expressions/operator.d.ts +1 -1
  86. package/dist/parsing/expressions/operator.d.ts.map +1 -1
  87. package/dist/parsing/expressions/operator.js.map +1 -1
  88. package/dist/parsing/functions/function_factory.d.ts +13 -13
  89. package/dist/parsing/functions/function_factory.d.ts.map +1 -1
  90. package/dist/parsing/functions/function_factory.js +20 -18
  91. package/dist/parsing/functions/function_factory.js.map +1 -1
  92. package/dist/parsing/operations/call.d.ts.map +1 -1
  93. package/dist/parsing/operations/call.js +3 -1
  94. package/dist/parsing/operations/call.js.map +1 -1
  95. package/dist/parsing/operations/create_node.d.ts +14 -0
  96. package/dist/parsing/operations/create_node.d.ts.map +1 -0
  97. package/dist/parsing/operations/create_node.js +51 -0
  98. package/dist/parsing/operations/create_node.js.map +1 -0
  99. package/dist/parsing/operations/create_relationship.d.ts +14 -0
  100. package/dist/parsing/operations/create_relationship.d.ts.map +1 -0
  101. package/dist/parsing/operations/create_relationship.js +51 -0
  102. package/dist/parsing/operations/create_relationship.js.map +1 -0
  103. package/dist/parsing/operations/match.d.ts +15 -0
  104. package/dist/parsing/operations/match.d.ts.map +1 -0
  105. package/dist/parsing/operations/match.js +45 -0
  106. package/dist/parsing/operations/match.js.map +1 -0
  107. package/dist/parsing/operations/operation.d.ts +1 -0
  108. package/dist/parsing/operations/operation.d.ts.map +1 -1
  109. package/dist/parsing/operations/operation.js +6 -0
  110. package/dist/parsing/operations/operation.js.map +1 -1
  111. package/dist/parsing/operations/return.d.ts +1 -0
  112. package/dist/parsing/operations/return.d.ts.map +1 -1
  113. package/dist/parsing/operations/return.js +7 -1
  114. package/dist/parsing/operations/return.js.map +1 -1
  115. package/dist/parsing/operations/where.d.ts +1 -1
  116. package/dist/parsing/operations/where.d.ts.map +1 -1
  117. package/dist/parsing/operations/where.js +4 -0
  118. package/dist/parsing/operations/where.js.map +1 -1
  119. package/dist/parsing/parser.d.ts +10 -0
  120. package/dist/parsing/parser.d.ts.map +1 -1
  121. package/dist/parsing/parser.js +344 -5
  122. package/dist/parsing/parser.js.map +1 -1
  123. package/dist/parsing/token_to_node.d.ts.map +1 -1
  124. package/dist/parsing/token_to_node.js +7 -0
  125. package/dist/parsing/token_to_node.js.map +1 -1
  126. package/dist/tokenization/keyword.d.ts +1 -0
  127. package/dist/tokenization/keyword.d.ts.map +1 -1
  128. package/dist/tokenization/keyword.js +1 -0
  129. package/dist/tokenization/keyword.js.map +1 -1
  130. package/dist/tokenization/token.d.ts +4 -0
  131. package/dist/tokenization/token.d.ts.map +1 -1
  132. package/dist/tokenization/token.js +14 -1
  133. package/dist/tokenization/token.js.map +1 -1
  134. package/dist/tokenization/token_type.d.ts +1 -0
  135. package/dist/tokenization/token_type.d.ts.map +1 -1
  136. package/dist/tokenization/token_type.js +1 -0
  137. package/dist/tokenization/token_type.js.map +1 -1
  138. package/dist/tokenization/tokenizer.d.ts +2 -1
  139. package/dist/tokenization/tokenizer.d.ts.map +1 -1
  140. package/dist/tokenization/tokenizer.js +25 -12
  141. package/dist/tokenization/tokenizer.js.map +1 -1
  142. package/docs/flowquery.min.js +1 -1
  143. package/flowquery-py/README.md +166 -0
  144. package/flowquery-py/pyproject.toml +75 -0
  145. package/flowquery-py/setup_env.ps1 +92 -0
  146. package/flowquery-py/setup_env.sh +87 -0
  147. package/flowquery-py/src/__init__.py +34 -0
  148. package/flowquery-py/src/__main__.py +10 -0
  149. package/flowquery-py/src/compute/__init__.py +5 -0
  150. package/flowquery-py/src/compute/runner.py +60 -0
  151. package/flowquery-py/src/extensibility.py +52 -0
  152. package/flowquery-py/src/graph/__init__.py +31 -0
  153. package/flowquery-py/src/graph/data.py +118 -0
  154. package/flowquery-py/src/graph/database.py +82 -0
  155. package/flowquery-py/src/graph/hops.py +43 -0
  156. package/flowquery-py/src/graph/node.py +112 -0
  157. package/flowquery-py/src/graph/node_data.py +26 -0
  158. package/flowquery-py/src/graph/node_reference.py +49 -0
  159. package/flowquery-py/src/graph/pattern.py +125 -0
  160. package/flowquery-py/src/graph/pattern_expression.py +62 -0
  161. package/flowquery-py/src/graph/patterns.py +42 -0
  162. package/flowquery-py/src/graph/physical_node.py +40 -0
  163. package/flowquery-py/src/graph/physical_relationship.py +36 -0
  164. package/flowquery-py/src/graph/relationship.py +135 -0
  165. package/flowquery-py/src/graph/relationship_data.py +33 -0
  166. package/flowquery-py/src/graph/relationship_match_collector.py +77 -0
  167. package/flowquery-py/src/graph/relationship_reference.py +21 -0
  168. package/flowquery-py/src/io/__init__.py +5 -0
  169. package/flowquery-py/src/io/command_line.py +67 -0
  170. package/flowquery-py/src/parsing/__init__.py +17 -0
  171. package/flowquery-py/src/parsing/alias.py +20 -0
  172. package/flowquery-py/src/parsing/alias_option.py +11 -0
  173. package/flowquery-py/src/parsing/ast_node.py +146 -0
  174. package/flowquery-py/src/parsing/base_parser.py +84 -0
  175. package/flowquery-py/src/parsing/components/__init__.py +19 -0
  176. package/flowquery-py/src/parsing/components/csv.py +8 -0
  177. package/flowquery-py/src/parsing/components/from_.py +10 -0
  178. package/flowquery-py/src/parsing/components/headers.py +12 -0
  179. package/flowquery-py/src/parsing/components/json.py +8 -0
  180. package/flowquery-py/src/parsing/components/null.py +10 -0
  181. package/flowquery-py/src/parsing/components/post.py +8 -0
  182. package/flowquery-py/src/parsing/components/text.py +8 -0
  183. package/flowquery-py/src/parsing/context.py +50 -0
  184. package/flowquery-py/src/parsing/data_structures/__init__.py +15 -0
  185. package/flowquery-py/src/parsing/data_structures/associative_array.py +41 -0
  186. package/flowquery-py/src/parsing/data_structures/json_array.py +30 -0
  187. package/flowquery-py/src/parsing/data_structures/key_value_pair.py +38 -0
  188. package/flowquery-py/src/parsing/data_structures/lookup.py +49 -0
  189. package/flowquery-py/src/parsing/data_structures/range_lookup.py +42 -0
  190. package/flowquery-py/src/parsing/expressions/__init__.py +57 -0
  191. package/flowquery-py/src/parsing/expressions/boolean.py +20 -0
  192. package/flowquery-py/src/parsing/expressions/expression.py +138 -0
  193. package/flowquery-py/src/parsing/expressions/expression_map.py +26 -0
  194. package/flowquery-py/src/parsing/expressions/f_string.py +27 -0
  195. package/flowquery-py/src/parsing/expressions/identifier.py +20 -0
  196. package/flowquery-py/src/parsing/expressions/number.py +32 -0
  197. package/flowquery-py/src/parsing/expressions/operator.py +169 -0
  198. package/flowquery-py/src/parsing/expressions/reference.py +47 -0
  199. package/flowquery-py/src/parsing/expressions/string.py +27 -0
  200. package/flowquery-py/src/parsing/functions/__init__.py +75 -0
  201. package/flowquery-py/src/parsing/functions/aggregate_function.py +60 -0
  202. package/flowquery-py/src/parsing/functions/async_function.py +62 -0
  203. package/flowquery-py/src/parsing/functions/avg.py +55 -0
  204. package/flowquery-py/src/parsing/functions/collect.py +75 -0
  205. package/flowquery-py/src/parsing/functions/function.py +68 -0
  206. package/flowquery-py/src/parsing/functions/function_factory.py +173 -0
  207. package/flowquery-py/src/parsing/functions/function_metadata.py +149 -0
  208. package/flowquery-py/src/parsing/functions/functions.py +59 -0
  209. package/flowquery-py/src/parsing/functions/join.py +47 -0
  210. package/flowquery-py/src/parsing/functions/keys.py +34 -0
  211. package/flowquery-py/src/parsing/functions/predicate_function.py +46 -0
  212. package/flowquery-py/src/parsing/functions/predicate_sum.py +47 -0
  213. package/flowquery-py/src/parsing/functions/rand.py +28 -0
  214. package/flowquery-py/src/parsing/functions/range_.py +34 -0
  215. package/flowquery-py/src/parsing/functions/reducer_element.py +15 -0
  216. package/flowquery-py/src/parsing/functions/replace.py +37 -0
  217. package/flowquery-py/src/parsing/functions/round_.py +32 -0
  218. package/flowquery-py/src/parsing/functions/size.py +32 -0
  219. package/flowquery-py/src/parsing/functions/split.py +47 -0
  220. package/flowquery-py/src/parsing/functions/stringify.py +47 -0
  221. package/flowquery-py/src/parsing/functions/sum.py +51 -0
  222. package/flowquery-py/src/parsing/functions/to_json.py +33 -0
  223. package/flowquery-py/src/parsing/functions/type_.py +47 -0
  224. package/flowquery-py/src/parsing/functions/value_holder.py +24 -0
  225. package/flowquery-py/src/parsing/logic/__init__.py +15 -0
  226. package/flowquery-py/src/parsing/logic/case.py +29 -0
  227. package/flowquery-py/src/parsing/logic/else_.py +12 -0
  228. package/flowquery-py/src/parsing/logic/end.py +8 -0
  229. package/flowquery-py/src/parsing/logic/then.py +12 -0
  230. package/flowquery-py/src/parsing/logic/when.py +10 -0
  231. package/flowquery-py/src/parsing/operations/__init__.py +35 -0
  232. package/flowquery-py/src/parsing/operations/aggregated_return.py +24 -0
  233. package/flowquery-py/src/parsing/operations/aggregated_with.py +22 -0
  234. package/flowquery-py/src/parsing/operations/call.py +74 -0
  235. package/flowquery-py/src/parsing/operations/create_node.py +34 -0
  236. package/flowquery-py/src/parsing/operations/create_relationship.py +34 -0
  237. package/flowquery-py/src/parsing/operations/group_by.py +130 -0
  238. package/flowquery-py/src/parsing/operations/limit.py +22 -0
  239. package/flowquery-py/src/parsing/operations/load.py +140 -0
  240. package/flowquery-py/src/parsing/operations/match.py +29 -0
  241. package/flowquery-py/src/parsing/operations/operation.py +69 -0
  242. package/flowquery-py/src/parsing/operations/projection.py +21 -0
  243. package/flowquery-py/src/parsing/operations/return_op.py +50 -0
  244. package/flowquery-py/src/parsing/operations/unwind.py +37 -0
  245. package/flowquery-py/src/parsing/operations/where.py +41 -0
  246. package/flowquery-py/src/parsing/operations/with_op.py +18 -0
  247. package/flowquery-py/src/parsing/parser.py +1011 -0
  248. package/flowquery-py/src/parsing/token_to_node.py +109 -0
  249. package/flowquery-py/src/tokenization/__init__.py +23 -0
  250. package/flowquery-py/src/tokenization/keyword.py +48 -0
  251. package/flowquery-py/src/tokenization/operator.py +29 -0
  252. package/flowquery-py/src/tokenization/string_walker.py +158 -0
  253. package/flowquery-py/src/tokenization/symbol.py +19 -0
  254. package/flowquery-py/src/tokenization/token.py +659 -0
  255. package/flowquery-py/src/tokenization/token_mapper.py +52 -0
  256. package/flowquery-py/src/tokenization/token_type.py +21 -0
  257. package/flowquery-py/src/tokenization/tokenizer.py +214 -0
  258. package/flowquery-py/src/tokenization/trie.py +124 -0
  259. package/flowquery-py/src/utils/__init__.py +6 -0
  260. package/flowquery-py/src/utils/object_utils.py +20 -0
  261. package/flowquery-py/src/utils/string_utils.py +113 -0
  262. package/flowquery-py/tests/__init__.py +1 -0
  263. package/flowquery-py/tests/compute/__init__.py +1 -0
  264. package/flowquery-py/tests/compute/test_runner.py +1335 -0
  265. package/flowquery-py/tests/graph/__init__.py +1 -0
  266. package/flowquery-py/tests/graph/test_create.py +56 -0
  267. package/flowquery-py/tests/graph/test_data.py +73 -0
  268. package/flowquery-py/tests/graph/test_match.py +40 -0
  269. package/flowquery-py/tests/parsing/__init__.py +1 -0
  270. package/flowquery-py/tests/parsing/test_context.py +34 -0
  271. package/flowquery-py/tests/parsing/test_expression.py +49 -0
  272. package/flowquery-py/tests/parsing/test_parser.py +674 -0
  273. package/flowquery-py/tests/test_extensibility.py +611 -0
  274. package/flowquery-py/tests/tokenization/__init__.py +1 -0
  275. package/flowquery-py/tests/tokenization/test_token_mapper.py +60 -0
  276. package/flowquery-py/tests/tokenization/test_tokenizer.py +164 -0
  277. package/flowquery-py/tests/tokenization/test_trie.py +30 -0
  278. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
  279. package/misc/apps/RAG/package.json +1 -1
  280. package/misc/apps/RAG/src/components/AdaptiveCardRenderer.tsx +76 -8
  281. package/misc/apps/RAG/src/components/index.ts +19 -10
  282. package/misc/apps/RAG/src/plugins/loaders/CatFacts.ts +21 -26
  283. package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +24 -25
  284. package/misc/apps/RAG/src/plugins/loaders/Form.ts +163 -147
  285. package/misc/apps/RAG/src/plugins/loaders/Llm.ts +103 -90
  286. package/misc/apps/RAG/src/plugins/loaders/MockData.ts +80 -130
  287. package/misc/apps/RAG/src/plugins/loaders/Table.ts +104 -101
  288. package/misc/apps/RAG/src/plugins/loaders/Weather.ts +47 -36
  289. package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +89 -78
  290. package/package.json +1 -1
  291. package/src/compute/runner.ts +24 -19
  292. package/src/graph/data.ts +112 -0
  293. package/src/graph/database.ts +63 -0
  294. package/src/graph/hops.ts +22 -0
  295. package/src/graph/node.ts +99 -0
  296. package/src/graph/node_data.ts +18 -0
  297. package/src/graph/node_reference.ts +33 -0
  298. package/src/graph/pattern.ts +101 -0
  299. package/src/graph/pattern_expression.ts +37 -0
  300. package/src/graph/patterns.ts +36 -0
  301. package/src/graph/physical_node.ts +23 -0
  302. package/src/graph/physical_relationship.ts +23 -0
  303. package/src/graph/relationship.ts +116 -0
  304. package/src/graph/relationship_data.ts +27 -0
  305. package/src/graph/relationship_match_collector.ts +58 -0
  306. package/src/graph/relationship_reference.ts +24 -0
  307. package/src/parsing/base_parser.ts +20 -14
  308. package/src/parsing/context.ts +14 -14
  309. package/src/parsing/expressions/boolean.ts +21 -0
  310. package/src/parsing/expressions/expression.ts +34 -26
  311. package/src/parsing/expressions/expression_map.ts +3 -0
  312. package/src/parsing/expressions/operator.ts +19 -1
  313. package/src/parsing/functions/function_factory.ts +45 -45
  314. package/src/parsing/operations/call.ts +3 -1
  315. package/src/parsing/operations/create_node.ts +39 -0
  316. package/src/parsing/operations/create_relationship.ts +38 -0
  317. package/src/parsing/operations/match.ts +31 -0
  318. package/src/parsing/operations/operation.ts +3 -0
  319. package/src/parsing/operations/return.ts +11 -7
  320. package/src/parsing/operations/where.ts +10 -6
  321. package/src/parsing/parser.ts +346 -8
  322. package/src/parsing/token_to_node.ts +6 -0
  323. package/src/tokenization/keyword.ts +41 -40
  324. package/src/tokenization/token.ts +21 -1
  325. package/src/tokenization/token_type.ts +2 -1
  326. package/src/tokenization/tokenizer.ts +52 -31
  327. package/tests/compute/runner.test.ts +660 -6
  328. package/tests/extensibility.test.ts +97 -93
  329. package/tests/graph/create.test.ts +36 -0
  330. package/tests/graph/data.test.ts +58 -0
  331. package/tests/graph/match.test.ts +29 -0
  332. package/tests/parsing/parser.test.ts +276 -8
  333. package/tests/tokenization/tokenizer.test.ts +107 -17
@@ -0,0 +1,26 @@
1
+ """Expression map for managing named expressions."""
2
+
3
+ from typing import Optional, List, TYPE_CHECKING
4
+
5
+ if TYPE_CHECKING:
6
+ from .expression import Expression
7
+
8
+
9
+ class ExpressionMap:
10
+ """Maps expression aliases to their corresponding Expression objects."""
11
+
12
+ def __init__(self):
13
+ self._map: dict[str, Expression] = {}
14
+
15
+ def get(self, alias: str) -> Optional['Expression']:
16
+ return self._map.get(alias)
17
+
18
+ def has(self, alias: str) -> bool:
19
+ return alias in self._map
20
+
21
+ def set_map(self, expressions: List['Expression']) -> None:
22
+ self._map.clear()
23
+ for expr in expressions:
24
+ if expr.alias is None:
25
+ continue
26
+ self._map[expr.alias] = expr
@@ -0,0 +1,27 @@
1
+ """Represents a formatted string (f-string) in the AST."""
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from ..ast_node import ASTNode
6
+
7
+ if TYPE_CHECKING:
8
+ from .expression import Expression
9
+
10
+
11
+ class FString(ASTNode):
12
+ """Represents a formatted string (f-string) in the AST.
13
+
14
+ F-strings allow embedding expressions within string literals.
15
+ Child nodes represent the parts of the f-string (literal strings and expressions).
16
+
17
+ Example:
18
+ # For f"Hello {name}!"
19
+ fstr = FString()
20
+ fstr.add_child(String("Hello "))
21
+ fstr.add_child(name_expression)
22
+ fstr.add_child(String("!"))
23
+ """
24
+
25
+ def value(self) -> str:
26
+ parts = self.get_children()
27
+ return "".join(str(part.value()) for part in parts)
@@ -0,0 +1,20 @@
1
+ """Represents an identifier in the AST."""
2
+
3
+ from .string import String
4
+ from typing import Any
5
+
6
+
7
+ class Identifier(String):
8
+ """Represents an identifier in the AST.
9
+
10
+ Identifiers are used for variable names, property names, and similar constructs.
11
+
12
+ Example:
13
+ id = Identifier("myVariable")
14
+ """
15
+
16
+ def __str__(self) -> str:
17
+ return f"Identifier ({self._value})"
18
+
19
+ def value(self) -> Any:
20
+ return super().value()
@@ -0,0 +1,32 @@
1
+ """Represents a numeric literal in the AST."""
2
+
3
+ from ..ast_node import ASTNode
4
+
5
+
6
+ class Number(ASTNode):
7
+ """Represents a numeric literal in the AST.
8
+
9
+ Parses string representations of numbers into integer or float values.
10
+
11
+ Example:
12
+ num = Number("42")
13
+ print(num.value()) # 42
14
+ """
15
+
16
+ def __init__(self, value: str):
17
+ """Creates a new Number node by parsing the string value.
18
+
19
+ Args:
20
+ value: The string representation of the number
21
+ """
22
+ super().__init__()
23
+ if '.' in value:
24
+ self._value = float(value)
25
+ else:
26
+ self._value = int(value)
27
+
28
+ def value(self) -> float | int:
29
+ return self._value
30
+
31
+ def __str__(self) -> str:
32
+ return f"{self.__class__.__name__} ({self._value})"
@@ -0,0 +1,169 @@
1
+ """Operator classes for FlowQuery expressions."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from typing import Any
5
+
6
+ from ..ast_node import ASTNode
7
+
8
+
9
+ class Operator(ASTNode, ABC):
10
+ """Base class for all operators in FlowQuery."""
11
+
12
+ def __init__(self, precedence: int, left_associative: bool):
13
+ super().__init__()
14
+ self._precedence = precedence
15
+ self._left_associative = left_associative
16
+
17
+ def is_operator(self) -> bool:
18
+ return True
19
+
20
+ @property
21
+ def precedence(self) -> int:
22
+ return self._precedence
23
+
24
+ @property
25
+ def left_associative(self) -> bool:
26
+ return self._left_associative
27
+
28
+ @abstractmethod
29
+ def value(self) -> Any:
30
+ pass
31
+
32
+ @property
33
+ def lhs(self) -> ASTNode:
34
+ return self.get_children()[0]
35
+
36
+ @property
37
+ def rhs(self) -> ASTNode:
38
+ return self.get_children()[1]
39
+
40
+
41
+ class Add(Operator):
42
+ def __init__(self):
43
+ super().__init__(1, True)
44
+
45
+ def value(self) -> Any:
46
+ return self.lhs.value() + self.rhs.value()
47
+
48
+
49
+ class Subtract(Operator):
50
+ def __init__(self):
51
+ super().__init__(1, True)
52
+
53
+ def value(self) -> Any:
54
+ return self.lhs.value() - self.rhs.value()
55
+
56
+
57
+ class Multiply(Operator):
58
+ def __init__(self):
59
+ super().__init__(2, True)
60
+
61
+ def value(self) -> Any:
62
+ return self.lhs.value() * self.rhs.value()
63
+
64
+
65
+ class Divide(Operator):
66
+ def __init__(self):
67
+ super().__init__(2, True)
68
+
69
+ def value(self) -> Any:
70
+ return self.lhs.value() / self.rhs.value()
71
+
72
+
73
+ class Modulo(Operator):
74
+ def __init__(self):
75
+ super().__init__(2, True)
76
+
77
+ def value(self) -> Any:
78
+ return self.lhs.value() % self.rhs.value()
79
+
80
+
81
+ class Power(Operator):
82
+ def __init__(self):
83
+ super().__init__(3, False)
84
+
85
+ def value(self) -> Any:
86
+ return self.lhs.value() ** self.rhs.value()
87
+
88
+
89
+ class Equals(Operator):
90
+ def __init__(self):
91
+ super().__init__(0, True)
92
+
93
+ def value(self) -> int:
94
+ return 1 if self.lhs.value() == self.rhs.value() else 0
95
+
96
+
97
+ class NotEquals(Operator):
98
+ def __init__(self):
99
+ super().__init__(0, True)
100
+
101
+ def value(self) -> int:
102
+ return 1 if self.lhs.value() != self.rhs.value() else 0
103
+
104
+
105
+ class GreaterThan(Operator):
106
+ def __init__(self):
107
+ super().__init__(0, True)
108
+
109
+ def value(self) -> int:
110
+ return 1 if self.lhs.value() > self.rhs.value() else 0
111
+
112
+
113
+ class LessThan(Operator):
114
+ def __init__(self):
115
+ super().__init__(0, True)
116
+
117
+ def value(self) -> int:
118
+ return 1 if self.lhs.value() < self.rhs.value() else 0
119
+
120
+
121
+ class GreaterThanOrEqual(Operator):
122
+ def __init__(self):
123
+ super().__init__(0, True)
124
+
125
+ def value(self) -> int:
126
+ return 1 if self.lhs.value() >= self.rhs.value() else 0
127
+
128
+
129
+ class LessThanOrEqual(Operator):
130
+ def __init__(self):
131
+ super().__init__(0, True)
132
+
133
+ def value(self) -> int:
134
+ return 1 if self.lhs.value() <= self.rhs.value() else 0
135
+
136
+
137
+ class And(Operator):
138
+ def __init__(self):
139
+ super().__init__(-1, True)
140
+
141
+ def value(self) -> int:
142
+ return 1 if (self.lhs.value() and self.rhs.value()) else 0
143
+
144
+
145
+ class Or(Operator):
146
+ def __init__(self):
147
+ super().__init__(-1, True)
148
+
149
+ def value(self) -> int:
150
+ return 1 if (self.lhs.value() or self.rhs.value()) else 0
151
+
152
+
153
+ class Not(Operator):
154
+ def __init__(self):
155
+ super().__init__(0, True)
156
+
157
+ def is_operator(self) -> bool:
158
+ return False
159
+
160
+ def value(self) -> int:
161
+ return 1 if not self.lhs.value() else 0
162
+
163
+
164
+ class Is(Operator):
165
+ def __init__(self):
166
+ super().__init__(-1, True)
167
+
168
+ def value(self) -> int:
169
+ return 1 if self.lhs.value() == self.rhs.value() else 0
@@ -0,0 +1,47 @@
1
+ """Represents a reference to a previously defined variable or expression."""
2
+
3
+ from typing import Any, Optional
4
+
5
+ from ..ast_node import ASTNode
6
+ from .identifier import Identifier
7
+
8
+
9
+ class Reference(Identifier):
10
+ """Represents a reference to a previously defined variable or expression.
11
+
12
+ References point to values defined earlier in the query (e.g., in WITH or LOAD statements).
13
+
14
+ Example:
15
+ ref = Reference("myVar", previous_node)
16
+ print(ref.value()) # Gets value from referred node
17
+ """
18
+
19
+ def __init__(self, value: str, referred: Optional[ASTNode] = None):
20
+ """Creates a new Reference to a variable.
21
+
22
+ Args:
23
+ value: The identifier name
24
+ referred: The node this reference points to (optional)
25
+ """
26
+ super().__init__(value)
27
+ self._referred = referred
28
+
29
+ @property
30
+ def referred(self) -> Optional[ASTNode]:
31
+ return self._referred
32
+
33
+ @referred.setter
34
+ def referred(self, node: ASTNode) -> None:
35
+ self._referred = node
36
+
37
+ def __str__(self) -> str:
38
+ return f"Reference ({self._value})"
39
+
40
+ def value(self) -> Any:
41
+ if self._referred is not None:
42
+ return self._referred.value()
43
+ return None
44
+
45
+ @property
46
+ def identifier(self) -> str:
47
+ return self._value
@@ -0,0 +1,27 @@
1
+ """Represents a string literal in the AST."""
2
+
3
+ from ..ast_node import ASTNode
4
+
5
+
6
+ class String(ASTNode):
7
+ """Represents a string literal in the AST.
8
+
9
+ Example:
10
+ s = String("hello")
11
+ print(s.value()) # "hello"
12
+ """
13
+
14
+ def __init__(self, value: str):
15
+ """Creates a new String node with the given value.
16
+
17
+ Args:
18
+ value: The string value
19
+ """
20
+ super().__init__()
21
+ self._value = value
22
+
23
+ def value(self) -> str:
24
+ return self._value
25
+
26
+ def __str__(self) -> str:
27
+ return f"String ({self._value})"
@@ -0,0 +1,75 @@
1
+ """Functions module for FlowQuery parsing."""
2
+
3
+ from .function import Function
4
+ from .aggregate_function import AggregateFunction
5
+ from .async_function import AsyncFunction
6
+ from .predicate_function import PredicateFunction
7
+ from .reducer_element import ReducerElement
8
+ from .value_holder import ValueHolder
9
+ from .function_metadata import (
10
+ FunctionCategory,
11
+ ParameterSchema,
12
+ OutputSchema,
13
+ FunctionMetadata,
14
+ FunctionDef,
15
+ FunctionDefOptions,
16
+ get_registered_function_metadata,
17
+ get_registered_function_factory,
18
+ get_function_metadata,
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
26
+ from .join import Join
27
+ from .keys import Keys
28
+ from .rand import Rand
29
+ from .range_ import Range
30
+ from .replace import Replace
31
+ from .round_ import Round
32
+ from .size import Size
33
+ from .split import Split
34
+ from .stringify import Stringify
35
+ from .to_json import ToJson
36
+ from .type_ import Type
37
+ from .functions import Functions
38
+ from .predicate_sum import PredicateSum
39
+
40
+ __all__ = [
41
+ # Base classes
42
+ "Function",
43
+ "AggregateFunction",
44
+ "AsyncFunction",
45
+ "PredicateFunction",
46
+ "ReducerElement",
47
+ "ValueHolder",
48
+ "FunctionCategory",
49
+ "ParameterSchema",
50
+ "OutputSchema",
51
+ "FunctionMetadata",
52
+ "FunctionDef",
53
+ "FunctionDefOptions",
54
+ "get_registered_function_metadata",
55
+ "get_registered_function_factory",
56
+ "get_function_metadata",
57
+ "FunctionFactory",
58
+ # Built-in functions
59
+ "Sum",
60
+ "Avg",
61
+ "Collect",
62
+ "Join",
63
+ "Keys",
64
+ "Rand",
65
+ "Range",
66
+ "Replace",
67
+ "Round",
68
+ "Size",
69
+ "Split",
70
+ "Stringify",
71
+ "ToJson",
72
+ "Type",
73
+ "Functions",
74
+ "PredicateSum",
75
+ ]
@@ -0,0 +1,60 @@
1
+ """Base class for aggregate functions that reduce multiple values to a single value."""
2
+
3
+ from typing import Any, Optional
4
+
5
+ from .function import Function
6
+ from .reducer_element import ReducerElement
7
+
8
+
9
+ class AggregateFunction(Function):
10
+ """Base class for aggregate functions that reduce multiple values to a single value.
11
+
12
+ Aggregate functions like SUM, AVG, and COLLECT process multiple input values
13
+ and produce a single output. They cannot be nested within other aggregate functions.
14
+
15
+ Example:
16
+ sum_func = Sum()
17
+ # Used in: RETURN SUM(values)
18
+ """
19
+
20
+ def __init__(self, name: Optional[str] = None):
21
+ """Creates a new AggregateFunction with the given name.
22
+
23
+ Args:
24
+ name: The function name
25
+ """
26
+ super().__init__(name)
27
+ self._overridden: Any = None
28
+
29
+ def reduce(self, value: ReducerElement) -> None:
30
+ """Processes a value during the aggregation phase.
31
+
32
+ Args:
33
+ value: The element to aggregate
34
+
35
+ Raises:
36
+ NotImplementedError: If not implemented by subclass
37
+ """
38
+ raise NotImplementedError("Method not implemented.")
39
+
40
+ def element(self) -> ReducerElement:
41
+ """Creates a reducer element for this aggregate function.
42
+
43
+ Returns:
44
+ A ReducerElement instance
45
+
46
+ Raises:
47
+ NotImplementedError: If not implemented by subclass
48
+ """
49
+ raise NotImplementedError("Method not implemented.")
50
+
51
+ @property
52
+ def overridden(self) -> Any:
53
+ return self._overridden
54
+
55
+ @overridden.setter
56
+ def overridden(self, value: Any) -> None:
57
+ self._overridden = value
58
+
59
+ def value(self) -> Any:
60
+ return self._overridden
@@ -0,0 +1,62 @@
1
+ """Represents an async data provider function call for use in LOAD operations."""
2
+
3
+ from typing import Any, AsyncGenerator, List
4
+
5
+ from ..ast_node import ASTNode
6
+ from .function import Function
7
+
8
+
9
+ class AsyncFunction(Function):
10
+ """Represents an async data provider function call for use in LOAD operations.
11
+
12
+ This class holds the function name and arguments, and provides async iteration
13
+ over the results from a registered async data provider.
14
+
15
+ Example:
16
+ # Used in: LOAD JSON FROM myDataSource('arg1', 'arg2') AS data
17
+ async_func = AsyncFunction("myDataSource")
18
+ async_func.parameters = [arg1_node, arg2_node]
19
+ async for item in async_func.execute():
20
+ print(item)
21
+ """
22
+
23
+ @property
24
+ def parameters(self) -> List[ASTNode]:
25
+ return self.children
26
+
27
+ @parameters.setter
28
+ def parameters(self, nodes: List[ASTNode]) -> None:
29
+ """Sets the function parameters.
30
+
31
+ Args:
32
+ nodes: Array of AST nodes representing the function arguments
33
+ """
34
+ self.children = nodes
35
+
36
+ def get_arguments(self) -> List[Any]:
37
+ """Evaluates all parameters and returns their values.
38
+ Used by the framework to pass arguments to generate().
39
+
40
+ Returns:
41
+ Array of parameter values
42
+ """
43
+ return [child.value() for child in self.children]
44
+
45
+ async def generate(self, *args: Any) -> AsyncGenerator[Any, None]:
46
+ """Generates the async data provider function results.
47
+
48
+ Subclasses override this method with their own typed parameters.
49
+ The framework automatically evaluates the AST children and spreads
50
+ them as arguments when calling this method.
51
+
52
+ Args:
53
+ args: Arguments passed from the query (e.g., myFunc(arg1, arg2))
54
+
55
+ Yields:
56
+ Data items from the async provider
57
+
58
+ Raises:
59
+ NotImplementedError: If the function is not registered as an async provider
60
+ """
61
+ raise NotImplementedError("generate method must be overridden in subclasses.")
62
+ yield # Make this a generator
@@ -0,0 +1,55 @@
1
+ """Avg aggregate function."""
2
+
3
+ from typing import Optional
4
+
5
+ from .aggregate_function import AggregateFunction
6
+ from .reducer_element import ReducerElement
7
+ from .function_metadata import FunctionDef
8
+
9
+
10
+ class AvgReducerElement(ReducerElement):
11
+ """Reducer element for Avg aggregate function."""
12
+
13
+ def __init__(self):
14
+ self._count: int = 0
15
+ self._sum: Optional[float] = None
16
+
17
+ @property
18
+ def value(self) -> Optional[float]:
19
+ if self._sum is None:
20
+ return None
21
+ return self._sum / self._count
22
+
23
+ @value.setter
24
+ def value(self, val: float) -> None:
25
+ self._count += 1
26
+ if self._sum is not None:
27
+ self._sum += val
28
+ else:
29
+ self._sum = val
30
+
31
+
32
+ @FunctionDef({
33
+ "description": "Calculates the average of numeric values across grouped rows",
34
+ "category": "aggregate",
35
+ "parameters": [
36
+ {"name": "value", "description": "Numeric value to average", "type": "number"}
37
+ ],
38
+ "output": {"description": "Average of all values", "type": "number", "example": 50},
39
+ "examples": ["WITH [10, 20, 30] AS nums UNWIND nums AS n RETURN avg(n)"]
40
+ })
41
+ class Avg(AggregateFunction):
42
+ """Avg aggregate function.
43
+
44
+ Calculates the average of numeric values across grouped rows.
45
+ """
46
+
47
+ def __init__(self):
48
+ super().__init__("avg")
49
+ self._expected_parameter_count = 1
50
+
51
+ def reduce(self, element: AvgReducerElement) -> None:
52
+ element.value = self.first_child().value()
53
+
54
+ def element(self) -> AvgReducerElement:
55
+ return AvgReducerElement()
@@ -0,0 +1,75 @@
1
+ """Collect aggregate function."""
2
+
3
+ from typing import Any, Dict, List, Union
4
+ import json
5
+
6
+ from .aggregate_function import AggregateFunction
7
+ from .reducer_element import ReducerElement
8
+ from .function_metadata import FunctionDef
9
+
10
+
11
+ class CollectReducerElement(ReducerElement):
12
+ """Reducer element for Collect aggregate function."""
13
+
14
+ def __init__(self):
15
+ self._value: List[Any] = []
16
+
17
+ @property
18
+ def value(self) -> Any:
19
+ return self._value
20
+
21
+ @value.setter
22
+ def value(self, val: Any) -> None:
23
+ self._value.append(val)
24
+
25
+
26
+ class DistinctCollectReducerElement(ReducerElement):
27
+ """Reducer element for Collect aggregate function with DISTINCT."""
28
+
29
+ def __init__(self):
30
+ self._value: Dict[str, Any] = {}
31
+
32
+ @property
33
+ def value(self) -> Any:
34
+ return list(self._value.values())
35
+
36
+ @value.setter
37
+ def value(self, val: Any) -> None:
38
+ key: str = json.dumps(val, sort_keys=True, default=str)
39
+ if key not in self._value:
40
+ self._value[key] = val
41
+
42
+
43
+ @FunctionDef({
44
+ "description": "Collects values into an array across grouped rows",
45
+ "category": "aggregate",
46
+ "parameters": [
47
+ {"name": "value", "description": "Value to collect", "type": "any"}
48
+ ],
49
+ "output": {"description": "Array of collected values", "type": "array", "example": [1, 2, 3]},
50
+ "examples": ["WITH [1, 2, 3] AS nums UNWIND nums AS n RETURN collect(n)"]
51
+ })
52
+ class Collect(AggregateFunction):
53
+ """Collect aggregate function.
54
+
55
+ Collects values into an array across grouped rows.
56
+ """
57
+
58
+ def __init__(self):
59
+ super().__init__("collect")
60
+ self._expected_parameter_count = 1
61
+ self._distinct: bool = False
62
+
63
+ def reduce(self, element: CollectReducerElement) -> None:
64
+ element.value = self.first_child().value()
65
+
66
+ def element(self) -> Union[CollectReducerElement, DistinctCollectReducerElement]:
67
+ return DistinctCollectReducerElement() if self._distinct else CollectReducerElement()
68
+
69
+ @property
70
+ def distinct(self) -> bool:
71
+ return self._distinct
72
+
73
+ @distinct.setter
74
+ def distinct(self, val: bool) -> None:
75
+ self._distinct = val