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,29 @@
1
+ import Runner from "../../src/compute/runner";
2
+ import PhysicalNode from "../../src/graph/physical_node";
3
+ import CreateNode from "../../src/parsing/operations/create_node";
4
+ import Parser from "../../src/parsing/parser";
5
+
6
+ test("Test CreateNode and match operations", async () => {
7
+ const node = new PhysicalNode(null, "Person");
8
+ expect(node.label).toBe("Person");
9
+ expect(node.statement).toBeNull();
10
+ const parser = new Parser();
11
+ const statement = parser.parse(`
12
+ unwind [
13
+ {id: 1, name: 'Person 1'},
14
+ {id: 2, name: 'Person 2'}
15
+ ] as record
16
+ RETURN record.id as id, record.name as name
17
+ `);
18
+ const op = new CreateNode(node, statement);
19
+ await op.run();
20
+ const runner = new Runner("match (n:Person) RETURN n");
21
+ await runner.run();
22
+ expect(runner.results.length).toBe(2);
23
+ expect(runner.results[0].n).toBeDefined();
24
+ expect(runner.results[0].n.id).toBe(1);
25
+ expect(runner.results[0].n.name).toBe("Person 1");
26
+ expect(runner.results[1].n).toBeDefined();
27
+ expect(runner.results[1].n.id).toBe(2);
28
+ expect(runner.results[1].n.name).toBe("Person 2");
29
+ });
@@ -1,8 +1,11 @@
1
+ import Node from "../../src/graph/node";
2
+ import NodeReference from "../../src/graph/node_reference";
3
+ import Relationship from "../../src/graph/relationship";
1
4
  import AsyncFunction from "../../src/parsing/functions/async_function";
2
- import {
3
- FunctionDef,
4
- getRegisteredFunctionFactory,
5
- } from "../../src/parsing/functions/function_metadata";
5
+ import { FunctionDef } from "../../src/parsing/functions/function_metadata";
6
+ import CreateNode from "../../src/parsing/operations/create_node";
7
+ import CreateRelationship from "../../src/parsing/operations/create_relationship";
8
+ import Match from "../../src/parsing/operations/match";
6
9
  import Parser from "../../src/parsing/parser";
7
10
 
8
11
  // Test class for CALL operation parsing test - defined at module level for Prettier compatibility
@@ -12,7 +15,7 @@ import Parser from "../../src/parsing/parser";
12
15
  parameters: [],
13
16
  output: { description: "Yields test values", type: "any" },
14
17
  })
15
- class CallParserTestFunction extends AsyncFunction {
18
+ class Test extends AsyncFunction {
16
19
  constructor() {
17
20
  super();
18
21
  this._expectedParameterCount = 0;
@@ -427,7 +430,7 @@ test("Test non-well formed statements", () => {
427
430
  "Only one RETURN statement is allowed"
428
431
  );
429
432
  expect(() => new Parser().parse("return 1 with 1 as n")).toThrow(
430
- "Last statement must be a RETURN, WHERE, or a CALL statement"
433
+ "Last statement must be a RETURN, WHERE, CALL, or CREATE statement"
431
434
  );
432
435
  });
433
436
 
@@ -468,12 +471,18 @@ test("Test limit", () => {
468
471
  test("Test return -2", () => {
469
472
  const parser = new Parser();
470
473
  const ast = parser.parse("return -2");
471
- expect(ast.print()).toBe("ASTNode\n" + "- Return\n" + "-- Expression\n" + "--- Number (-2)");
474
+ // prettier-ignore
475
+ expect(ast.print()).toBe(
476
+ "ASTNode\n" +
477
+ "- Return\n" +
478
+ "-- Expression\n" +
479
+ "--- Number (-2)"
480
+ );
472
481
  });
473
482
 
474
483
  test("Test call operation", () => {
475
484
  const parser = new Parser();
476
- const ast = parser.parse("CALL callparsertestfunction() YIELD result RETURN result");
485
+ const ast = parser.parse("CALL test() YIELD result RETURN result");
477
486
  expect(ast.print()).toBe(
478
487
  "ASTNode\n" +
479
488
  "- Call\n" +
@@ -484,3 +493,262 @@ test("Test call operation", () => {
484
493
  "--- Reference (result)"
485
494
  );
486
495
  });
496
+
497
+ test("Test f-string", () => {
498
+ const parser = new Parser();
499
+ const ast = parser.parse("with 1 as value RETURN f'Value is: {value}.'");
500
+ expect(ast.print()).toBe(
501
+ "ASTNode\n" +
502
+ "- With\n" +
503
+ "-- Expression (value)\n" +
504
+ "--- Number (1)\n" +
505
+ "- Return\n" +
506
+ "-- Expression\n" +
507
+ "--- FString\n" +
508
+ "---- String (Value is: )\n" +
509
+ "---- Expression\n" +
510
+ "----- Reference (value)\n" +
511
+ "---- String (.)"
512
+ );
513
+ });
514
+
515
+ test("Test create node operation", () => {
516
+ const parser = new Parser();
517
+ const ast = parser.parse(`
518
+ CREATE VIRTUAL (:Person) AS {
519
+ unwind range(1, 3) AS id
520
+ return id, f'Person {id}' AS name
521
+ }
522
+ `);
523
+ // prettier-ignore
524
+ expect(ast.print()).toBe(
525
+ "ASTNode\n" +
526
+ "- CreateNode"
527
+ );
528
+ const create: CreateNode = ast.firstChild() as CreateNode;
529
+ expect(create.node).not.toBeNull();
530
+ expect(create.node!.label).toBe("Person");
531
+ expect(create.statement!.print()).toBe(
532
+ "ASTNode\n" +
533
+ "- Unwind\n" +
534
+ "-- Expression (id)\n" +
535
+ "--- Function (range)\n" +
536
+ "---- Expression\n" +
537
+ "----- Number (1)\n" +
538
+ "---- Expression\n" +
539
+ "----- Number (3)\n" +
540
+ "- Return\n" +
541
+ "-- Expression (id)\n" +
542
+ "--- Reference (id)\n" +
543
+ "-- Expression (name)\n" +
544
+ "--- FString\n" +
545
+ "---- String (Person )\n" +
546
+ "---- Expression\n" +
547
+ "----- Reference (id)\n" +
548
+ "---- String ()"
549
+ );
550
+ });
551
+
552
+ test("Test match operation", () => {
553
+ const parser = new Parser();
554
+ const ast = parser.parse("MATCH (n:Person) RETURN n");
555
+ // prettier-ignore
556
+ expect(ast.print()).toBe(
557
+ "ASTNode\n" +
558
+ "- Match\n" +
559
+ "- Return\n" +
560
+ "-- Expression (n)\n" +
561
+ "--- Reference (n)"
562
+ );
563
+ const match = ast.firstChild() as Match;
564
+ expect(match.patterns[0].startNode).not.toBeNull();
565
+ expect(match.patterns[0].startNode!.label).toBe("Person");
566
+ expect(match.patterns[0].startNode!.identifier).toBe("n");
567
+ });
568
+
569
+ test("Test create relationship operation", () => {
570
+ const parser = new Parser();
571
+ const ast = parser.parse(`
572
+ CREATE VIRTUAL (:Person)-[:KNOWS]-(:Person) AS {
573
+ unwind [
574
+ {from_id: 1, to_id: 2, since: '2020-01-01'},
575
+ {from_id: 2, to_id: 3, since: '2021-01-01'}
576
+ ] AS pair
577
+ return pair.from_id AS from, pair.to_id AS to, pair.since AS since
578
+ }
579
+ `);
580
+ // prettier-ignore
581
+ expect(ast.print()).toBe(
582
+ "ASTNode\n" +
583
+ "- CreateRelationship"
584
+ );
585
+ const create = ast.firstChild() as CreateRelationship;
586
+ expect(create.relationship).not.toBeNull();
587
+ expect(create.relationship!.type).toBe("KNOWS");
588
+ expect(create.statement!.print()).toBe(
589
+ "ASTNode\n" +
590
+ "- Unwind\n" +
591
+ "-- Expression (pair)\n" +
592
+ "--- JSONArray\n" +
593
+ "---- Expression\n" +
594
+ "----- AssociativeArray\n" +
595
+ "------ KeyValuePair\n" +
596
+ "------- String (from_id)\n" +
597
+ "------- Expression\n" +
598
+ "-------- Number (1)\n" +
599
+ "------ KeyValuePair\n" +
600
+ "------- String (to_id)\n" +
601
+ "------- Expression\n" +
602
+ "-------- Number (2)\n" +
603
+ "------ KeyValuePair\n" +
604
+ "------- String (since)\n" +
605
+ "------- Expression\n" +
606
+ "-------- String (2020-01-01)\n" +
607
+ "---- Expression\n" +
608
+ "----- AssociativeArray\n" +
609
+ "------ KeyValuePair\n" +
610
+ "------- String (from_id)\n" +
611
+ "------- Expression\n" +
612
+ "-------- Number (2)\n" +
613
+ "------ KeyValuePair\n" +
614
+ "------- String (to_id)\n" +
615
+ "------- Expression\n" +
616
+ "-------- Number (3)\n" +
617
+ "------ KeyValuePair\n" +
618
+ "------- String (since)\n" +
619
+ "------- Expression\n" +
620
+ "-------- String (2021-01-01)\n" +
621
+ "- Return\n" +
622
+ "-- Expression (from)\n" +
623
+ "--- Lookup\n" +
624
+ "---- Identifier (from_id)\n" +
625
+ "---- Reference (pair)\n" +
626
+ "-- Expression (to)\n" +
627
+ "--- Lookup\n" +
628
+ "---- Identifier (to_id)\n" +
629
+ "---- Reference (pair)\n" +
630
+ "-- Expression (since)\n" +
631
+ "--- Lookup\n" +
632
+ "---- Identifier (since)\n" +
633
+ "---- Reference (pair)"
634
+ );
635
+ });
636
+
637
+ test("Match with graph pattern including relationships", () => {
638
+ const parser = new Parser();
639
+ const ast = parser.parse("MATCH (a:Person)-[:KNOWS]-(b:Person) RETURN a, b");
640
+ // prettier-ignore
641
+ expect(ast.print()).toBe(
642
+ "ASTNode\n" +
643
+ "- Match\n" +
644
+ "- Return\n" +
645
+ "-- Expression (a)\n" +
646
+ "--- Reference (a)\n" +
647
+ "-- Expression (b)\n" +
648
+ "--- Reference (b)"
649
+ );
650
+ const match = ast.firstChild() as Match;
651
+ expect(match.patterns[0].chain.length).toBe(3);
652
+ const source = match.patterns[0].chain[0] as Node;
653
+ const relationship = match.patterns[0].chain[1] as Relationship;
654
+ const target = match.patterns[0].chain[2] as Node;
655
+ expect(source.identifier).toBe("a");
656
+ expect(source.label).toBe("Person");
657
+ expect(relationship.type).toBe("KNOWS");
658
+ expect(target.identifier).toBe("b");
659
+ expect(target.label).toBe("Person");
660
+ });
661
+
662
+ test("Test not equal operator", () => {
663
+ const parser = new Parser();
664
+ const ast = parser.parse("RETURN 1 <> 2");
665
+ expect(ast.print()).toBe(
666
+ "ASTNode\n" +
667
+ "- Return\n" +
668
+ "-- Expression\n" +
669
+ "--- NotEquals\n" +
670
+ "---- Number (1)\n" +
671
+ "---- Number (2)"
672
+ );
673
+ });
674
+
675
+ test("Test equal operator", () => {
676
+ const parser = new Parser();
677
+ const ast = parser.parse("RETURN 1 = 2");
678
+ expect(ast.print()).toBe(
679
+ "ASTNode\n" +
680
+ "- Return\n" +
681
+ "-- Expression\n" +
682
+ "--- Equals\n" +
683
+ "---- Number (1)\n" +
684
+ "---- Number (2)"
685
+ );
686
+ });
687
+
688
+ test("Test not operator", () => {
689
+ const parser = new Parser();
690
+ const ast = parser.parse("RETURN NOT true");
691
+ // prettier-ignore
692
+ expect(ast.print()).toBe(
693
+ "ASTNode\n" +
694
+ "- Return\n" +
695
+ "-- Expression\n" +
696
+ "--- Not\n" +
697
+ "---- Expression\n" +
698
+ "----- Boolean"
699
+ );
700
+ });
701
+
702
+ test("Parse relationship with hops", () => {
703
+ const parser = new Parser();
704
+ const ast = parser.parse("MATCH (a:Test)-[:KNOWS*1..3]->(b:Test) RETURN a, b");
705
+ // prettier-ignore
706
+ expect(ast.print()).toBe(
707
+ "ASTNode\n" +
708
+ "- Match\n" +
709
+ "- Return\n" +
710
+ "-- Expression (a)\n" +
711
+ "--- Reference (a)\n" +
712
+ "-- Expression (b)\n" +
713
+ "--- Reference (b)"
714
+ );
715
+ const match = ast.firstChild() as Match;
716
+ expect(match.patterns[0].chain.length).toBe(3);
717
+ const source = match.patterns[0].chain[0] as Node;
718
+ const relationship = match.patterns[0].chain[1] as Relationship;
719
+ const target = match.patterns[0].chain[2] as Node;
720
+ expect(source.identifier).toBe("a");
721
+ expect(relationship.type).toBe("KNOWS");
722
+ expect(relationship.hops).not.toBeNull();
723
+ expect(relationship.hops!.min).toBe(1);
724
+ expect(relationship.hops!.max).toBe(3);
725
+ expect(target.identifier).toBe("b");
726
+ });
727
+
728
+ test("Parse statement with graph pattern in where clause", () => {
729
+ const parser = new Parser();
730
+ const ast = parser.parse("MATCH (a:Person) WHERE (a)-[:KNOWS]->(:Person) RETURN a");
731
+ // prettier-ignore
732
+ expect(ast.print()).toBe(
733
+ "ASTNode\n" +
734
+ "- Match\n" +
735
+ "- Where\n" +
736
+ "-- Expression\n" +
737
+ "--- PatternExpression\n" +
738
+ "- Return\n" +
739
+ "-- Expression (a)\n" +
740
+ "--- Reference (a)"
741
+ );
742
+ const match = ast.firstChild() as Match;
743
+ expect(match.patterns[0].startNode).not.toBeNull();
744
+ expect(match.patterns[0].startNode!.identifier).toBe("a");
745
+ const where = match.next as any;
746
+ const pattern = where.firstChild().firstChild() as any;
747
+ expect(pattern.chain.length).toBe(3);
748
+ const source = pattern.chain[0] as NodeReference;
749
+ const relationship = pattern.chain[1] as Relationship;
750
+ const target = pattern.chain[2] as Node;
751
+ expect(source.reference?.identifier).toBe("a");
752
+ expect(relationship.type).toBe("KNOWS");
753
+ expect(target.label).toBe("Person");
754
+ });
@@ -1,62 +1,69 @@
1
- import Tokenizer from '../../src/tokenization/tokenizer';
1
+ import Tokenizer from "../../src/tokenization/tokenizer";
2
2
 
3
- test('Tokenizer.tokenize() should return an array of tokens', () => {
4
- const tokenizer = new Tokenizer('MATCH (n:Person) RETURN n');
3
+ test("Tokenizer.tokenize() should return an array of tokens", () => {
4
+ const tokenizer = new Tokenizer("MATCH (n:Person) RETURN n");
5
5
  const tokens = tokenizer.tokenize();
6
6
  expect(tokens).toBeDefined();
7
7
  expect(tokens.length).toBeGreaterThan(0);
8
8
  });
9
9
 
10
- test('Tokenizer.tokenize() should handle escaped quotes', () => {
10
+ test("Tokenizer.tokenize() should handle escaped quotes", () => {
11
11
  const tokenizer = new Tokenizer('return "hello \\"world"');
12
12
  const tokens = tokenizer.tokenize();
13
13
  expect(tokens).toBeDefined();
14
14
  expect(tokens.length).toBeGreaterThan(0);
15
15
  });
16
16
 
17
- test('Test predicate function', () => {
18
- const tokenizer = new Tokenizer('RETURN sum(n in [1, 2, 3] | n where n > 1)');
17
+ test("Test predicate function", () => {
18
+ const tokenizer = new Tokenizer("RETURN sum(n in [1, 2, 3] | n where n > 1)");
19
19
  const tokens = tokenizer.tokenize();
20
20
  expect(tokens).toBeDefined();
21
21
  expect(tokens.length).toBeGreaterThan(0);
22
22
  });
23
23
 
24
- test('Test f-string', () => {
24
+ test("Test f-string", () => {
25
25
  const tokenizer = new Tokenizer('RETURN f"hello {world}"');
26
26
  const tokens = tokenizer.tokenize();
27
27
  expect(tokens).toBeDefined();
28
28
  expect(tokens.length).toBeGreaterThan(0);
29
29
  });
30
30
 
31
- test('Test', () => {
32
- const tokenizer = new Tokenizer('WITH 1 AS n RETURN n');
31
+ test("Test another f-string", () => {
32
+ const tokenizer = new Tokenizer("RETURN f`Value is: {value}`");
33
33
  const tokens = tokenizer.tokenize();
34
34
  expect(tokens).toBeDefined();
35
35
  expect(tokens.length).toBeGreaterThan(0);
36
36
  });
37
37
 
38
- test('Test associative array with backtick string', () => {
39
- const tokenizer = new Tokenizer('RETURN {`key`: `value`}');
38
+ test("Test", () => {
39
+ const tokenizer = new Tokenizer("WITH 1 AS n RETURN n");
40
40
  const tokens = tokenizer.tokenize();
41
41
  expect(tokens).toBeDefined();
42
42
  expect(tokens.length).toBeGreaterThan(0);
43
43
  });
44
44
 
45
- test('Test limit', () => {
46
- const tokenizer = new Tokenizer('unwind range(1, 10) as n limit 5 return n');
45
+ test("Test associative array with backtick string", () => {
46
+ const tokenizer = new Tokenizer("RETURN {`key`: `value`}");
47
47
  const tokens = tokenizer.tokenize();
48
48
  expect(tokens).toBeDefined();
49
49
  expect(tokens.length).toBeGreaterThan(0);
50
50
  });
51
51
 
52
- test('Test return -2', () => {
53
- const tokenizer = new Tokenizer('return [:-2], -2');
52
+ test("Test limit", () => {
53
+ const tokenizer = new Tokenizer("unwind range(1, 10) as n limit 5 return n");
54
54
  const tokens = tokenizer.tokenize();
55
55
  expect(tokens).toBeDefined();
56
56
  expect(tokens.length).toBeGreaterThan(0);
57
57
  });
58
58
 
59
- test('Test range with function', () => {
59
+ test("Test return -2", () => {
60
+ const tokenizer = new Tokenizer("return [:-2], -2");
61
+ const tokens = tokenizer.tokenize();
62
+ expect(tokens).toBeDefined();
63
+ expect(tokens.length).toBeGreaterThan(0);
64
+ });
65
+
66
+ test("Test range with function", () => {
60
67
  const tokenizer = new Tokenizer(`
61
68
  with range(1,10) as data
62
69
  return range(0, size(data)-1) as indices
@@ -64,4 +71,87 @@ test('Test range with function', () => {
64
71
  const tokens = tokenizer.tokenize();
65
72
  expect(tokens).toBeDefined();
66
73
  expect(tokens.length).toBeGreaterThan(0);
67
- });
74
+ });
75
+
76
+ test("Test create virtual node", () => {
77
+ const tokenizer = new Tokenizer(`
78
+ CREATE VIRTUAL (:Person) AS {
79
+ call users() YIELD id, name
80
+ }
81
+ `);
82
+ const tokens = tokenizer.tokenize();
83
+ expect(tokens).toBeDefined();
84
+ expect(tokens.length).toBeGreaterThan(0);
85
+ });
86
+
87
+ test("Test create virtual relationship", () => {
88
+ const tokenizer = new Tokenizer(`
89
+ CREATE VIRTUAL (:Person)-[:KNOWS]->(:Person) AS {
90
+ call friendships() YIELD user1_id, user2_id
91
+ }
92
+ `);
93
+ const tokens = tokenizer.tokenize();
94
+ expect(tokens).toBeDefined();
95
+ expect(tokens.length).toBeGreaterThan(0);
96
+ });
97
+
98
+ test("Match based on virtual node", () => {
99
+ const tokenizer = new Tokenizer(`
100
+ MATCH (a:Person)
101
+ RETURN a.name
102
+ `);
103
+ const tokens = tokenizer.tokenize();
104
+ expect(tokens).toBeDefined();
105
+ expect(tokens.length).toBeGreaterThan(0);
106
+ });
107
+
108
+ test("Match based on virtual nodes and relationships", () => {
109
+ const tokenizer = new Tokenizer(`
110
+ MATCH (a:Person)-[r:KNOWS]->(b:Person)
111
+ RETURN a.name, b.name
112
+ `);
113
+ const tokens = tokenizer.tokenize();
114
+ expect(tokens).toBeDefined();
115
+ expect(tokens.length).toBeGreaterThan(0);
116
+ });
117
+
118
+ test("Test not equal operator", () => {
119
+ const tokenizer = new Tokenizer(`
120
+ MATCH (n:Person)
121
+ WHERE n.age <> 30
122
+ RETURN n.name AS name, n.age AS age
123
+ `);
124
+ const tokens = tokenizer.tokenize();
125
+ expect(tokens).toBeDefined();
126
+ expect(tokens.length).toBeGreaterThan(0);
127
+ });
128
+
129
+ test("Test equal operator", () => {
130
+ const tokenizer = new Tokenizer(`
131
+ MATCH (n:Person)
132
+ WHERE n.age = 30
133
+ RETURN n.name AS name, n.age AS age
134
+ `);
135
+ const tokens = tokenizer.tokenize();
136
+ expect(tokens).toBeDefined();
137
+ expect(tokens.length).toBeGreaterThan(0);
138
+ });
139
+
140
+ test("Test boolean operators", () => {
141
+ const tokenizer = new Tokenizer(`
142
+ return true AND false OR true NOT false
143
+ `);
144
+ const tokens = tokenizer.tokenize();
145
+ expect(tokens).toBeDefined();
146
+ expect(tokens.length).toBeGreaterThan(0);
147
+ });
148
+
149
+ test("Test relationship with hops", () => {
150
+ const tokenizer = new Tokenizer(`
151
+ MATCH (a:Person)-[r:KNOWS*1..3]->(b:Person)
152
+ RETURN a.name, b.name
153
+ `);
154
+ const tokens = tokenizer.tokenize();
155
+ expect(tokens).toBeDefined();
156
+ expect(tokens.length).toBeGreaterThan(0);
157
+ });