flowquery 1.0.46 → 1.0.48

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 (422) hide show
  1. package/dist/flowquery.min.js +1 -1
  2. package/dist/index.d.ts +0 -7
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +6 -4
  5. package/dist/index.js.map +1 -1
  6. package/dist/parsing/data_structures/list_comprehension.d.ts +56 -0
  7. package/dist/parsing/data_structures/list_comprehension.d.ts.map +1 -0
  8. package/dist/parsing/data_structures/list_comprehension.js +102 -0
  9. package/dist/parsing/data_structures/list_comprehension.js.map +1 -0
  10. package/dist/parsing/parser.d.ts +18 -0
  11. package/dist/parsing/parser.d.ts.map +1 -1
  12. package/dist/parsing/parser.js +92 -0
  13. package/dist/parsing/parser.js.map +1 -1
  14. package/package.json +4 -1
  15. package/.editorconfig +0 -21
  16. package/.gitattributes +0 -3
  17. package/.github/workflows/npm-publish.yml +0 -32
  18. package/.github/workflows/python-publish.yml +0 -143
  19. package/.github/workflows/release.yml +0 -107
  20. package/.husky/pre-commit +0 -28
  21. package/.prettierrc +0 -22
  22. package/CODE_OF_CONDUCT.md +0 -10
  23. package/FlowQueryLogoIcon.png +0 -0
  24. package/SECURITY.md +0 -14
  25. package/SUPPORT.md +0 -13
  26. package/docs/flowquery.min.js +0 -1
  27. package/docs/index.html +0 -105
  28. package/flowquery-py/CONTRIBUTING.md +0 -127
  29. package/flowquery-py/README.md +0 -67
  30. package/flowquery-py/misc/data/test.json +0 -10
  31. package/flowquery-py/misc/data/users.json +0 -242
  32. package/flowquery-py/notebooks/TestFlowQuery.ipynb +0 -440
  33. package/flowquery-py/pyproject.toml +0 -121
  34. package/flowquery-py/setup_env.ps1 +0 -92
  35. package/flowquery-py/setup_env.sh +0 -87
  36. package/flowquery-py/src/__init__.py +0 -38
  37. package/flowquery-py/src/__main__.py +0 -10
  38. package/flowquery-py/src/compute/__init__.py +0 -6
  39. package/flowquery-py/src/compute/flowquery.py +0 -68
  40. package/flowquery-py/src/compute/runner.py +0 -64
  41. package/flowquery-py/src/extensibility.py +0 -52
  42. package/flowquery-py/src/graph/__init__.py +0 -31
  43. package/flowquery-py/src/graph/data.py +0 -136
  44. package/flowquery-py/src/graph/database.py +0 -141
  45. package/flowquery-py/src/graph/hops.py +0 -43
  46. package/flowquery-py/src/graph/node.py +0 -143
  47. package/flowquery-py/src/graph/node_data.py +0 -26
  48. package/flowquery-py/src/graph/node_reference.py +0 -50
  49. package/flowquery-py/src/graph/pattern.py +0 -115
  50. package/flowquery-py/src/graph/pattern_expression.py +0 -67
  51. package/flowquery-py/src/graph/patterns.py +0 -42
  52. package/flowquery-py/src/graph/physical_node.py +0 -41
  53. package/flowquery-py/src/graph/physical_relationship.py +0 -36
  54. package/flowquery-py/src/graph/relationship.py +0 -193
  55. package/flowquery-py/src/graph/relationship_data.py +0 -36
  56. package/flowquery-py/src/graph/relationship_match_collector.py +0 -85
  57. package/flowquery-py/src/graph/relationship_reference.py +0 -21
  58. package/flowquery-py/src/io/__init__.py +0 -5
  59. package/flowquery-py/src/io/command_line.py +0 -108
  60. package/flowquery-py/src/parsing/__init__.py +0 -17
  61. package/flowquery-py/src/parsing/alias.py +0 -20
  62. package/flowquery-py/src/parsing/alias_option.py +0 -11
  63. package/flowquery-py/src/parsing/ast_node.py +0 -147
  64. package/flowquery-py/src/parsing/base_parser.py +0 -84
  65. package/flowquery-py/src/parsing/components/__init__.py +0 -19
  66. package/flowquery-py/src/parsing/components/csv.py +0 -8
  67. package/flowquery-py/src/parsing/components/from_.py +0 -12
  68. package/flowquery-py/src/parsing/components/headers.py +0 -12
  69. package/flowquery-py/src/parsing/components/json.py +0 -8
  70. package/flowquery-py/src/parsing/components/null.py +0 -10
  71. package/flowquery-py/src/parsing/components/post.py +0 -8
  72. package/flowquery-py/src/parsing/components/text.py +0 -8
  73. package/flowquery-py/src/parsing/context.py +0 -50
  74. package/flowquery-py/src/parsing/data_structures/__init__.py +0 -15
  75. package/flowquery-py/src/parsing/data_structures/associative_array.py +0 -41
  76. package/flowquery-py/src/parsing/data_structures/json_array.py +0 -30
  77. package/flowquery-py/src/parsing/data_structures/key_value_pair.py +0 -38
  78. package/flowquery-py/src/parsing/data_structures/lookup.py +0 -51
  79. package/flowquery-py/src/parsing/data_structures/range_lookup.py +0 -42
  80. package/flowquery-py/src/parsing/expressions/__init__.py +0 -61
  81. package/flowquery-py/src/parsing/expressions/boolean.py +0 -20
  82. package/flowquery-py/src/parsing/expressions/expression.py +0 -141
  83. package/flowquery-py/src/parsing/expressions/expression_map.py +0 -26
  84. package/flowquery-py/src/parsing/expressions/f_string.py +0 -27
  85. package/flowquery-py/src/parsing/expressions/identifier.py +0 -21
  86. package/flowquery-py/src/parsing/expressions/number.py +0 -32
  87. package/flowquery-py/src/parsing/expressions/operator.py +0 -271
  88. package/flowquery-py/src/parsing/expressions/reference.py +0 -47
  89. package/flowquery-py/src/parsing/expressions/string.py +0 -27
  90. package/flowquery-py/src/parsing/functions/__init__.py +0 -127
  91. package/flowquery-py/src/parsing/functions/aggregate_function.py +0 -60
  92. package/flowquery-py/src/parsing/functions/async_function.py +0 -65
  93. package/flowquery-py/src/parsing/functions/avg.py +0 -55
  94. package/flowquery-py/src/parsing/functions/coalesce.py +0 -43
  95. package/flowquery-py/src/parsing/functions/collect.py +0 -75
  96. package/flowquery-py/src/parsing/functions/count.py +0 -79
  97. package/flowquery-py/src/parsing/functions/date_.py +0 -61
  98. package/flowquery-py/src/parsing/functions/datetime_.py +0 -62
  99. package/flowquery-py/src/parsing/functions/duration.py +0 -159
  100. package/flowquery-py/src/parsing/functions/element_id.py +0 -50
  101. package/flowquery-py/src/parsing/functions/function.py +0 -68
  102. package/flowquery-py/src/parsing/functions/function_factory.py +0 -170
  103. package/flowquery-py/src/parsing/functions/function_metadata.py +0 -148
  104. package/flowquery-py/src/parsing/functions/functions.py +0 -67
  105. package/flowquery-py/src/parsing/functions/head.py +0 -39
  106. package/flowquery-py/src/parsing/functions/id_.py +0 -49
  107. package/flowquery-py/src/parsing/functions/join.py +0 -49
  108. package/flowquery-py/src/parsing/functions/keys.py +0 -34
  109. package/flowquery-py/src/parsing/functions/last.py +0 -39
  110. package/flowquery-py/src/parsing/functions/localdatetime.py +0 -60
  111. package/flowquery-py/src/parsing/functions/localtime.py +0 -57
  112. package/flowquery-py/src/parsing/functions/max_.py +0 -49
  113. package/flowquery-py/src/parsing/functions/min_.py +0 -49
  114. package/flowquery-py/src/parsing/functions/nodes.py +0 -48
  115. package/flowquery-py/src/parsing/functions/predicate_function.py +0 -47
  116. package/flowquery-py/src/parsing/functions/predicate_sum.py +0 -49
  117. package/flowquery-py/src/parsing/functions/properties.py +0 -50
  118. package/flowquery-py/src/parsing/functions/rand.py +0 -28
  119. package/flowquery-py/src/parsing/functions/range_.py +0 -41
  120. package/flowquery-py/src/parsing/functions/reducer_element.py +0 -15
  121. package/flowquery-py/src/parsing/functions/relationships.py +0 -46
  122. package/flowquery-py/src/parsing/functions/replace.py +0 -39
  123. package/flowquery-py/src/parsing/functions/round_.py +0 -34
  124. package/flowquery-py/src/parsing/functions/schema.py +0 -40
  125. package/flowquery-py/src/parsing/functions/size.py +0 -34
  126. package/flowquery-py/src/parsing/functions/split.py +0 -54
  127. package/flowquery-py/src/parsing/functions/string_distance.py +0 -92
  128. package/flowquery-py/src/parsing/functions/stringify.py +0 -49
  129. package/flowquery-py/src/parsing/functions/substring.py +0 -76
  130. package/flowquery-py/src/parsing/functions/sum.py +0 -51
  131. package/flowquery-py/src/parsing/functions/tail.py +0 -37
  132. package/flowquery-py/src/parsing/functions/temporal_utils.py +0 -186
  133. package/flowquery-py/src/parsing/functions/time_.py +0 -57
  134. package/flowquery-py/src/parsing/functions/timestamp.py +0 -37
  135. package/flowquery-py/src/parsing/functions/to_float.py +0 -46
  136. package/flowquery-py/src/parsing/functions/to_integer.py +0 -46
  137. package/flowquery-py/src/parsing/functions/to_json.py +0 -35
  138. package/flowquery-py/src/parsing/functions/to_lower.py +0 -37
  139. package/flowquery-py/src/parsing/functions/to_string.py +0 -41
  140. package/flowquery-py/src/parsing/functions/trim.py +0 -37
  141. package/flowquery-py/src/parsing/functions/type_.py +0 -47
  142. package/flowquery-py/src/parsing/functions/value_holder.py +0 -24
  143. package/flowquery-py/src/parsing/logic/__init__.py +0 -15
  144. package/flowquery-py/src/parsing/logic/case.py +0 -28
  145. package/flowquery-py/src/parsing/logic/else_.py +0 -12
  146. package/flowquery-py/src/parsing/logic/end.py +0 -8
  147. package/flowquery-py/src/parsing/logic/then.py +0 -12
  148. package/flowquery-py/src/parsing/logic/when.py +0 -12
  149. package/flowquery-py/src/parsing/operations/__init__.py +0 -46
  150. package/flowquery-py/src/parsing/operations/aggregated_return.py +0 -25
  151. package/flowquery-py/src/parsing/operations/aggregated_with.py +0 -22
  152. package/flowquery-py/src/parsing/operations/call.py +0 -73
  153. package/flowquery-py/src/parsing/operations/create_node.py +0 -35
  154. package/flowquery-py/src/parsing/operations/create_relationship.py +0 -35
  155. package/flowquery-py/src/parsing/operations/delete_node.py +0 -29
  156. package/flowquery-py/src/parsing/operations/delete_relationship.py +0 -29
  157. package/flowquery-py/src/parsing/operations/group_by.py +0 -148
  158. package/flowquery-py/src/parsing/operations/limit.py +0 -33
  159. package/flowquery-py/src/parsing/operations/load.py +0 -148
  160. package/flowquery-py/src/parsing/operations/match.py +0 -52
  161. package/flowquery-py/src/parsing/operations/operation.py +0 -69
  162. package/flowquery-py/src/parsing/operations/order_by.py +0 -114
  163. package/flowquery-py/src/parsing/operations/projection.py +0 -21
  164. package/flowquery-py/src/parsing/operations/return_op.py +0 -88
  165. package/flowquery-py/src/parsing/operations/union.py +0 -115
  166. package/flowquery-py/src/parsing/operations/union_all.py +0 -17
  167. package/flowquery-py/src/parsing/operations/unwind.py +0 -42
  168. package/flowquery-py/src/parsing/operations/where.py +0 -43
  169. package/flowquery-py/src/parsing/operations/with_op.py +0 -18
  170. package/flowquery-py/src/parsing/parser.py +0 -1384
  171. package/flowquery-py/src/parsing/parser_state.py +0 -26
  172. package/flowquery-py/src/parsing/token_to_node.py +0 -109
  173. package/flowquery-py/src/tokenization/__init__.py +0 -23
  174. package/flowquery-py/src/tokenization/keyword.py +0 -54
  175. package/flowquery-py/src/tokenization/operator.py +0 -29
  176. package/flowquery-py/src/tokenization/string_walker.py +0 -158
  177. package/flowquery-py/src/tokenization/symbol.py +0 -19
  178. package/flowquery-py/src/tokenization/token.py +0 -693
  179. package/flowquery-py/src/tokenization/token_mapper.py +0 -53
  180. package/flowquery-py/src/tokenization/token_type.py +0 -21
  181. package/flowquery-py/src/tokenization/tokenizer.py +0 -214
  182. package/flowquery-py/src/tokenization/trie.py +0 -125
  183. package/flowquery-py/src/utils/__init__.py +0 -6
  184. package/flowquery-py/src/utils/object_utils.py +0 -20
  185. package/flowquery-py/src/utils/string_utils.py +0 -113
  186. package/flowquery-py/tests/__init__.py +0 -1
  187. package/flowquery-py/tests/compute/__init__.py +0 -1
  188. package/flowquery-py/tests/compute/test_runner.py +0 -4902
  189. package/flowquery-py/tests/graph/__init__.py +0 -1
  190. package/flowquery-py/tests/graph/test_create.py +0 -56
  191. package/flowquery-py/tests/graph/test_data.py +0 -73
  192. package/flowquery-py/tests/graph/test_match.py +0 -40
  193. package/flowquery-py/tests/parsing/__init__.py +0 -1
  194. package/flowquery-py/tests/parsing/test_context.py +0 -34
  195. package/flowquery-py/tests/parsing/test_expression.py +0 -248
  196. package/flowquery-py/tests/parsing/test_parser.py +0 -1237
  197. package/flowquery-py/tests/test_extensibility.py +0 -611
  198. package/flowquery-py/tests/tokenization/__init__.py +0 -1
  199. package/flowquery-py/tests/tokenization/test_token_mapper.py +0 -60
  200. package/flowquery-py/tests/tokenization/test_tokenizer.py +0 -198
  201. package/flowquery-py/tests/tokenization/test_trie.py +0 -30
  202. package/flowquery-vscode/.vscode-test.mjs +0 -5
  203. package/flowquery-vscode/.vscodeignore +0 -13
  204. package/flowquery-vscode/LICENSE +0 -21
  205. package/flowquery-vscode/README.md +0 -11
  206. package/flowquery-vscode/demo/FlowQueryVSCodeDemo.gif +0 -0
  207. package/flowquery-vscode/eslint.config.mjs +0 -25
  208. package/flowquery-vscode/extension.js +0 -508
  209. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +0 -1
  210. package/flowquery-vscode/flowquery-worker.js +0 -66
  211. package/flowquery-vscode/images/FlowQueryLogoIcon.png +0 -0
  212. package/flowquery-vscode/jsconfig.json +0 -13
  213. package/flowquery-vscode/libs/page.css +0 -53
  214. package/flowquery-vscode/libs/table.css +0 -13
  215. package/flowquery-vscode/libs/tabs.css +0 -66
  216. package/flowquery-vscode/package-lock.json +0 -2917
  217. package/flowquery-vscode/package.json +0 -51
  218. package/flowquery-vscode/test/extension.test.js +0 -196
  219. package/flowquery-vscode/test/worker.test.js +0 -25
  220. package/flowquery-vscode/vsc-extension-quickstart.md +0 -42
  221. package/jest.config.js +0 -14
  222. package/misc/apps/RAG/README.md +0 -29
  223. package/misc/apps/RAG/data/chats.json +0 -302
  224. package/misc/apps/RAG/data/emails.json +0 -182
  225. package/misc/apps/RAG/data/events.json +0 -226
  226. package/misc/apps/RAG/data/files.json +0 -172
  227. package/misc/apps/RAG/data/users.json +0 -158
  228. package/misc/apps/RAG/jest.config.js +0 -21
  229. package/misc/apps/RAG/package.json +0 -48
  230. package/misc/apps/RAG/public/index.html +0 -18
  231. package/misc/apps/RAG/src/App.css +0 -42
  232. package/misc/apps/RAG/src/App.tsx +0 -50
  233. package/misc/apps/RAG/src/components/AdaptiveCardRenderer.css +0 -172
  234. package/misc/apps/RAG/src/components/AdaptiveCardRenderer.tsx +0 -380
  235. package/misc/apps/RAG/src/components/ApiKeySettings.tsx +0 -245
  236. package/misc/apps/RAG/src/components/ChatContainer.css +0 -67
  237. package/misc/apps/RAG/src/components/ChatContainer.tsx +0 -242
  238. package/misc/apps/RAG/src/components/ChatInput.css +0 -23
  239. package/misc/apps/RAG/src/components/ChatInput.tsx +0 -76
  240. package/misc/apps/RAG/src/components/ChatMessage.css +0 -160
  241. package/misc/apps/RAG/src/components/ChatMessage.tsx +0 -286
  242. package/misc/apps/RAG/src/components/FlowQueryAgent.ts +0 -708
  243. package/misc/apps/RAG/src/components/FlowQueryRunner.css +0 -113
  244. package/misc/apps/RAG/src/components/FlowQueryRunner.tsx +0 -371
  245. package/misc/apps/RAG/src/components/index.ts +0 -28
  246. package/misc/apps/RAG/src/graph/index.ts +0 -19
  247. package/misc/apps/RAG/src/graph/initializeGraph.ts +0 -254
  248. package/misc/apps/RAG/src/index.tsx +0 -29
  249. package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +0 -327
  250. package/misc/apps/RAG/src/prompts/index.ts +0 -10
  251. package/misc/apps/RAG/src/tests/graph.test.ts +0 -35
  252. package/misc/apps/RAG/src/utils/FlowQueryExecutor.ts +0 -130
  253. package/misc/apps/RAG/src/utils/FlowQueryExtractor.ts +0 -208
  254. package/misc/apps/RAG/src/utils/Llm.ts +0 -248
  255. package/misc/apps/RAG/src/utils/index.ts +0 -12
  256. package/misc/apps/RAG/tsconfig.json +0 -22
  257. package/misc/apps/RAG/webpack.config.js +0 -43
  258. package/misc/apps/README.md +0 -1
  259. package/misc/queries/analyze_catfacts.cql +0 -75
  260. package/misc/queries/azure_openai_completions.cql +0 -13
  261. package/misc/queries/azure_openai_models.cql +0 -9
  262. package/misc/queries/mock_pipeline.cql +0 -84
  263. package/misc/queries/openai_completions.cql +0 -15
  264. package/misc/queries/openai_models.cql +0 -13
  265. package/misc/queries/test.cql +0 -6
  266. package/misc/queries/tool_inference.cql +0 -24
  267. package/misc/queries/wisdom.cql +0 -6
  268. package/misc/queries/wisdom_letter_histogram.cql +0 -8
  269. package/src/compute/flowquery.ts +0 -46
  270. package/src/compute/runner.ts +0 -66
  271. package/src/extensibility.ts +0 -45
  272. package/src/graph/data.ts +0 -130
  273. package/src/graph/database.ts +0 -143
  274. package/src/graph/hops.ts +0 -22
  275. package/src/graph/node.ts +0 -122
  276. package/src/graph/node_data.ts +0 -18
  277. package/src/graph/node_reference.ts +0 -38
  278. package/src/graph/pattern.ts +0 -110
  279. package/src/graph/pattern_expression.ts +0 -48
  280. package/src/graph/patterns.ts +0 -36
  281. package/src/graph/physical_node.ts +0 -23
  282. package/src/graph/physical_relationship.ts +0 -23
  283. package/src/graph/relationship.ts +0 -167
  284. package/src/graph/relationship_data.ts +0 -31
  285. package/src/graph/relationship_match_collector.ts +0 -64
  286. package/src/graph/relationship_reference.ts +0 -25
  287. package/src/index.browser.ts +0 -46
  288. package/src/index.node.ts +0 -55
  289. package/src/index.ts +0 -12
  290. package/src/io/command_line.ts +0 -74
  291. package/src/parsing/alias.ts +0 -23
  292. package/src/parsing/alias_option.ts +0 -5
  293. package/src/parsing/ast_node.ts +0 -153
  294. package/src/parsing/base_parser.ts +0 -98
  295. package/src/parsing/components/csv.ts +0 -9
  296. package/src/parsing/components/from.ts +0 -12
  297. package/src/parsing/components/headers.ts +0 -12
  298. package/src/parsing/components/json.ts +0 -9
  299. package/src/parsing/components/null.ts +0 -9
  300. package/src/parsing/components/post.ts +0 -9
  301. package/src/parsing/components/text.ts +0 -9
  302. package/src/parsing/context.ts +0 -54
  303. package/src/parsing/data_structures/associative_array.ts +0 -43
  304. package/src/parsing/data_structures/json_array.ts +0 -31
  305. package/src/parsing/data_structures/key_value_pair.ts +0 -37
  306. package/src/parsing/data_structures/lookup.ts +0 -44
  307. package/src/parsing/data_structures/range_lookup.ts +0 -36
  308. package/src/parsing/expressions/boolean.ts +0 -21
  309. package/src/parsing/expressions/expression.ts +0 -150
  310. package/src/parsing/expressions/expression_map.ts +0 -22
  311. package/src/parsing/expressions/f_string.ts +0 -26
  312. package/src/parsing/expressions/identifier.ts +0 -22
  313. package/src/parsing/expressions/number.ts +0 -40
  314. package/src/parsing/expressions/operator.ts +0 -354
  315. package/src/parsing/expressions/reference.ts +0 -45
  316. package/src/parsing/expressions/string.ts +0 -34
  317. package/src/parsing/functions/aggregate_function.ts +0 -58
  318. package/src/parsing/functions/async_function.ts +0 -64
  319. package/src/parsing/functions/avg.ts +0 -47
  320. package/src/parsing/functions/coalesce.ts +0 -49
  321. package/src/parsing/functions/collect.ts +0 -54
  322. package/src/parsing/functions/count.ts +0 -54
  323. package/src/parsing/functions/date.ts +0 -63
  324. package/src/parsing/functions/datetime.ts +0 -63
  325. package/src/parsing/functions/duration.ts +0 -143
  326. package/src/parsing/functions/element_id.ts +0 -51
  327. package/src/parsing/functions/function.ts +0 -60
  328. package/src/parsing/functions/function_factory.ts +0 -195
  329. package/src/parsing/functions/function_metadata.ts +0 -217
  330. package/src/parsing/functions/functions.ts +0 -70
  331. package/src/parsing/functions/head.ts +0 -42
  332. package/src/parsing/functions/id.ts +0 -51
  333. package/src/parsing/functions/join.ts +0 -40
  334. package/src/parsing/functions/keys.ts +0 -29
  335. package/src/parsing/functions/last.ts +0 -42
  336. package/src/parsing/functions/localdatetime.ts +0 -63
  337. package/src/parsing/functions/localtime.ts +0 -58
  338. package/src/parsing/functions/max.ts +0 -37
  339. package/src/parsing/functions/min.ts +0 -37
  340. package/src/parsing/functions/nodes.ts +0 -54
  341. package/src/parsing/functions/predicate_function.ts +0 -48
  342. package/src/parsing/functions/predicate_sum.ts +0 -47
  343. package/src/parsing/functions/properties.ts +0 -56
  344. package/src/parsing/functions/rand.ts +0 -21
  345. package/src/parsing/functions/range.ts +0 -37
  346. package/src/parsing/functions/reducer_element.ts +0 -10
  347. package/src/parsing/functions/relationships.ts +0 -52
  348. package/src/parsing/functions/replace.ts +0 -38
  349. package/src/parsing/functions/round.ts +0 -28
  350. package/src/parsing/functions/schema.ts +0 -39
  351. package/src/parsing/functions/size.ts +0 -28
  352. package/src/parsing/functions/split.ts +0 -45
  353. package/src/parsing/functions/string_distance.ts +0 -83
  354. package/src/parsing/functions/stringify.ts +0 -37
  355. package/src/parsing/functions/substring.ts +0 -68
  356. package/src/parsing/functions/sum.ts +0 -41
  357. package/src/parsing/functions/tail.ts +0 -39
  358. package/src/parsing/functions/temporal_utils.ts +0 -180
  359. package/src/parsing/functions/time.ts +0 -58
  360. package/src/parsing/functions/timestamp.ts +0 -37
  361. package/src/parsing/functions/to_float.ts +0 -50
  362. package/src/parsing/functions/to_integer.ts +0 -50
  363. package/src/parsing/functions/to_json.ts +0 -28
  364. package/src/parsing/functions/to_lower.ts +0 -28
  365. package/src/parsing/functions/to_string.ts +0 -32
  366. package/src/parsing/functions/trim.ts +0 -28
  367. package/src/parsing/functions/type.ts +0 -39
  368. package/src/parsing/functions/value_holder.ts +0 -13
  369. package/src/parsing/logic/case.ts +0 -26
  370. package/src/parsing/logic/else.ts +0 -12
  371. package/src/parsing/logic/end.ts +0 -9
  372. package/src/parsing/logic/then.ts +0 -12
  373. package/src/parsing/logic/when.ts +0 -12
  374. package/src/parsing/operations/aggregated_return.ts +0 -22
  375. package/src/parsing/operations/aggregated_with.ts +0 -18
  376. package/src/parsing/operations/call.ts +0 -69
  377. package/src/parsing/operations/create_node.ts +0 -39
  378. package/src/parsing/operations/create_relationship.ts +0 -38
  379. package/src/parsing/operations/delete_node.ts +0 -33
  380. package/src/parsing/operations/delete_relationship.ts +0 -32
  381. package/src/parsing/operations/group_by.ts +0 -137
  382. package/src/parsing/operations/limit.ts +0 -31
  383. package/src/parsing/operations/load.ts +0 -146
  384. package/src/parsing/operations/match.ts +0 -54
  385. package/src/parsing/operations/operation.ts +0 -69
  386. package/src/parsing/operations/order_by.ts +0 -126
  387. package/src/parsing/operations/projection.ts +0 -18
  388. package/src/parsing/operations/return.ts +0 -76
  389. package/src/parsing/operations/union.ts +0 -114
  390. package/src/parsing/operations/union_all.ts +0 -16
  391. package/src/parsing/operations/unwind.ts +0 -36
  392. package/src/parsing/operations/where.ts +0 -42
  393. package/src/parsing/operations/with.ts +0 -20
  394. package/src/parsing/parser.ts +0 -1641
  395. package/src/parsing/parser_state.ts +0 -25
  396. package/src/parsing/token_to_node.ts +0 -114
  397. package/src/tokenization/keyword.ts +0 -50
  398. package/src/tokenization/operator.ts +0 -25
  399. package/src/tokenization/string_walker.ts +0 -197
  400. package/src/tokenization/symbol.ts +0 -15
  401. package/src/tokenization/token.ts +0 -764
  402. package/src/tokenization/token_mapper.ts +0 -53
  403. package/src/tokenization/token_type.ts +0 -16
  404. package/src/tokenization/tokenizer.ts +0 -250
  405. package/src/tokenization/trie.ts +0 -117
  406. package/src/utils/object_utils.ts +0 -17
  407. package/src/utils/string_utils.ts +0 -114
  408. package/tests/compute/runner.test.ts +0 -4559
  409. package/tests/extensibility.test.ts +0 -643
  410. package/tests/graph/create.test.ts +0 -36
  411. package/tests/graph/data.test.ts +0 -58
  412. package/tests/graph/match.test.ts +0 -29
  413. package/tests/parsing/context.test.ts +0 -27
  414. package/tests/parsing/expression.test.ts +0 -303
  415. package/tests/parsing/parser.test.ts +0 -1327
  416. package/tests/tokenization/token_mapper.test.ts +0 -47
  417. package/tests/tokenization/tokenizer.test.ts +0 -191
  418. package/tests/tokenization/trie.test.ts +0 -20
  419. package/tsconfig.json +0 -19
  420. package/typedoc.json +0 -16
  421. package/vscode-settings.json.recommended +0 -16
  422. package/webpack.config.js +0 -26
@@ -1,1327 +0,0 @@
1
- import Node from "../../src/graph/node";
2
- import NodeReference from "../../src/graph/node_reference";
3
- import Relationship from "../../src/graph/relationship";
4
- import RelationshipReference from "../../src/graph/relationship_reference";
5
- import AsyncFunction from "../../src/parsing/functions/async_function";
6
- import { FunctionDef } from "../../src/parsing/functions/function_metadata";
7
- import CreateNode from "../../src/parsing/operations/create_node";
8
- import CreateRelationship from "../../src/parsing/operations/create_relationship";
9
- import Match from "../../src/parsing/operations/match";
10
- import Parser from "../../src/parsing/parser";
11
-
12
- // Test class for CALL operation parsing test - defined at module level for Prettier compatibility
13
- @FunctionDef({
14
- description: "Asynchronous function for testing CALL operation",
15
- category: "async",
16
- parameters: [],
17
- output: { description: "Yields test values", type: "any" },
18
- })
19
- class Test extends AsyncFunction {
20
- constructor() {
21
- super();
22
- this._expectedParameterCount = 0;
23
- }
24
- public async *generate(): AsyncGenerator<any> {
25
- yield 1;
26
- yield 2;
27
- yield 3;
28
- }
29
- }
30
-
31
- test("Test Parser", () => {
32
- const parser = new Parser();
33
- const ast = parser.parse("RETURN 1, 2, 3");
34
- expect(ast.print()).toBe(
35
- "ASTNode\n" +
36
- "- Return\n" +
37
- "-- Expression\n" +
38
- "--- Number (1)\n" +
39
- "-- Expression\n" +
40
- "--- Number (2)\n" +
41
- "-- Expression\n" +
42
- "--- Number (3)"
43
- );
44
- });
45
-
46
- test("Test Parser with function", () => {
47
- const parser = new Parser();
48
- const ast = parser.parse("RETURN rand()");
49
- expect(ast.print()).toBe(
50
- "ASTNode\n" + "- Return\n" + "-- Expression\n" + "--- Function (rand)"
51
- );
52
- });
53
-
54
- test("Test Parser with associative array", () => {
55
- const parser = new Parser();
56
- const ast = parser.parse("RETURN {a: 1, b: 2}");
57
- expect(ast.print()).toBe(
58
- "ASTNode\n" +
59
- "- Return\n" +
60
- "-- Expression\n" +
61
- "--- AssociativeArray\n" +
62
- "---- KeyValuePair\n" +
63
- "----- String (a)\n" +
64
- "----- Expression\n" +
65
- "------ Number (1)\n" +
66
- "---- KeyValuePair\n" +
67
- "----- String (b)\n" +
68
- "----- Expression\n" +
69
- "------ Number (2)"
70
- );
71
- });
72
-
73
- test("Test Parser with JSON array", () => {
74
- const parser = new Parser();
75
- const ast = parser.parse("RETURN [1, 2]");
76
- expect(ast.print()).toBe(
77
- "ASTNode\n" +
78
- "- Return\n" +
79
- "-- Expression\n" +
80
- "--- JSONArray\n" +
81
- "---- Expression\n" +
82
- "----- Number (1)\n" +
83
- "---- Expression\n" +
84
- "----- Number (2)"
85
- );
86
- });
87
-
88
- test("Test Parser with nested associative array", () => {
89
- const parser = new Parser();
90
- const ast = parser.parse("RETURN {a:{}}");
91
- expect(ast.print()).toBe(
92
- "ASTNode\n" +
93
- "- Return\n" +
94
- "-- Expression\n" +
95
- "--- AssociativeArray\n" +
96
- "---- KeyValuePair\n" +
97
- "----- String (a)\n" +
98
- "----- Expression\n" +
99
- "------ AssociativeArray"
100
- );
101
- });
102
-
103
- test("Test Parser with multiple operations", () => {
104
- const parser = new Parser();
105
- const ast = parser.parse("WITH 1 AS n RETURN n");
106
- expect(ast.print()).toBe(
107
- "ASTNode\n" +
108
- "- With\n" +
109
- "-- Expression (n)\n" +
110
- "--- Number (1)\n" +
111
- "- Return\n" +
112
- "-- Expression (n)\n" +
113
- "--- Reference (n)"
114
- );
115
- });
116
-
117
- test("Test Parser with multiple operations and comments", () => {
118
- const parser = new Parser();
119
- const ast = parser.parse("WITH 1 AS n /* comment */ RETURN n");
120
- expect(ast.print()).toBe(
121
- "ASTNode\n" +
122
- "- With\n" +
123
- "-- Expression (n)\n" +
124
- "--- Number (1)\n" +
125
- "- Return\n" +
126
- "-- Expression (n)\n" +
127
- "--- Reference (n)"
128
- );
129
- });
130
-
131
- test("Test Parser with multiple operations including UNWIND", () => {
132
- const parser = new Parser();
133
- const ast = parser.parse("UNWIND [1, 2, 3] AS n RETURN n");
134
- expect(ast.print()).toBe(
135
- "ASTNode\n" +
136
- "- Unwind\n" +
137
- "-- Expression (n)\n" +
138
- "--- JSONArray\n" +
139
- "---- Expression\n" +
140
- "----- Number (1)\n" +
141
- "---- Expression\n" +
142
- "----- Number (2)\n" +
143
- "---- Expression\n" +
144
- "----- Number (3)\n" +
145
- "- Return\n" +
146
- "-- Expression (n)\n" +
147
- "--- Reference (n)"
148
- );
149
- });
150
-
151
- test("Test Unwind with invalid expression", () => {
152
- const parser = new Parser();
153
- expect(() => parser.parse("UNWIND 1 AS n RETURN n")).toThrow(
154
- "Expected array, function, reference, or lookup."
155
- );
156
- });
157
-
158
- test("Test Unwind with invalid alias", () => {
159
- const parser = new Parser();
160
- expect(() => parser.parse("UNWIND [1, 2, 3] AS 1 RETURN n")).toThrow("Expected identifier");
161
- });
162
-
163
- test("Test Unwind with missing alias", () => {
164
- const parser = new Parser();
165
- expect(() => parser.parse("UNWIND [1, 2, 3] RETURN n")).toThrow("Expected alias");
166
- });
167
-
168
- test("Test statement with where clause", () => {
169
- const parser = new Parser();
170
- const ast = parser.parse("with 1 as n where n > 0 return n");
171
- expect(ast.print()).toBe(
172
- "ASTNode\n" +
173
- "- With\n" +
174
- "-- Expression (n)\n" +
175
- "--- Number (1)\n" +
176
- "- Where\n" +
177
- "-- Expression\n" +
178
- "--- GreaterThan\n" +
179
- "---- Reference (n)\n" +
180
- "---- Number (0)\n" +
181
- "- Return\n" +
182
- "-- Expression (n)\n" +
183
- "--- Reference (n)"
184
- );
185
- });
186
-
187
- test("Test lookup", () => {
188
- const parser = new Parser();
189
- const ast = parser.parse("return {a: 1}.a");
190
- expect(ast.print()).toBe(
191
- "ASTNode\n" +
192
- "- Return\n" +
193
- "-- Expression\n" +
194
- "--- Lookup\n" +
195
- "---- Identifier (a)\n" +
196
- "---- AssociativeArray\n" +
197
- "----- KeyValuePair\n" +
198
- "------ String (a)\n" +
199
- "------ Expression\n" +
200
- "------- Number (1)"
201
- );
202
- });
203
-
204
- test("Test lookup as part of expression", () => {
205
- const parser = new Parser();
206
- const ast = parser.parse("return {a: 1}.a + 1");
207
- expect(ast.print()).toBe(
208
- "ASTNode\n" +
209
- "- Return\n" +
210
- "-- Expression\n" +
211
- "--- Add\n" +
212
- "---- Lookup\n" +
213
- "----- Identifier (a)\n" +
214
- "----- AssociativeArray\n" +
215
- "------ KeyValuePair\n" +
216
- "------- String (a)\n" +
217
- "------- Expression\n" +
218
- "-------- Number (1)\n" +
219
- "---- Number (1)"
220
- );
221
- });
222
-
223
- test("Test lookup with nested associative array", () => {
224
- const parser = new Parser();
225
- const ast = parser.parse("return {a: {b: 1}}.a.b");
226
- const _return = ast.firstChild();
227
- expect(ast.print()).toBe(
228
- "ASTNode\n" +
229
- "- Return\n" +
230
- "-- Expression\n" +
231
- "--- Lookup\n" +
232
- "---- Identifier (b)\n" +
233
- "---- Lookup\n" +
234
- "----- Identifier (a)\n" +
235
- "----- AssociativeArray\n" +
236
- "------ KeyValuePair\n" +
237
- "------- String (a)\n" +
238
- "------- Expression\n" +
239
- "-------- AssociativeArray\n" +
240
- "--------- KeyValuePair\n" +
241
- "---------- String (b)\n" +
242
- "---------- Expression\n" +
243
- "----------- Number (1)"
244
- );
245
- expect(_return.firstChild().value()).toBe(1);
246
- });
247
-
248
- test("Test lookup with JSON array", () => {
249
- const parser = new Parser();
250
- const ast = parser.parse("return [1, 2][1]");
251
- const _return = ast.firstChild();
252
- expect(ast.print()).toBe(
253
- "ASTNode\n" +
254
- "- Return\n" +
255
- "-- Expression\n" +
256
- "--- Lookup\n" +
257
- "---- Expression\n" +
258
- "----- Number (1)\n" +
259
- "---- JSONArray\n" +
260
- "----- Expression\n" +
261
- "------ Number (1)\n" +
262
- "----- Expression\n" +
263
- "------ Number (2)"
264
- );
265
- expect(_return.firstChild().value()).toBe(2);
266
- });
267
-
268
- test("Test lookup with from keyword as property name", () => {
269
- const parser = new Parser();
270
- const ast = parser.parse("with {from: 1, to: 2} as x return x.from, x.to");
271
- expect(ast.print()).toBe(
272
- "ASTNode\n" +
273
- "- With\n" +
274
- "-- Expression (x)\n" +
275
- "--- AssociativeArray\n" +
276
- "---- KeyValuePair\n" +
277
- "----- String (from)\n" +
278
- "----- Expression\n" +
279
- "------ Number (1)\n" +
280
- "---- KeyValuePair\n" +
281
- "----- String (to)\n" +
282
- "----- Expression\n" +
283
- "------ Number (2)\n" +
284
- "- Return\n" +
285
- "-- Expression\n" +
286
- "--- Lookup\n" +
287
- "---- Identifier (from)\n" +
288
- "---- Reference (x)\n" +
289
- "-- Expression\n" +
290
- "--- Lookup\n" +
291
- "---- Identifier (to)\n" +
292
- "---- Reference (x)"
293
- );
294
- });
295
-
296
- test("Test camelCase alias starting with keyword", () => {
297
- const parser = new Parser();
298
- const ast = parser.parse("LOAD JSON FROM '/data.json' AS x RETURN x.from AS fromUser");
299
- expect(ast.print()).toContain("Lookup");
300
- expect(ast.print()).toContain("Identifier (from)");
301
- });
302
-
303
- test("Test from keyword property in create virtual subquery", () => {
304
- const parser = new Parser();
305
- // Should not throw - email.from should be parsed correctly even with FROM being a keyword
306
- expect(() => {
307
- parser.parse(
308
- "CREATE VIRTUAL (:Email) AS { LOAD JSON FROM '/data/emails.json' AS email RETURN email.id AS id, email.from AS fromUser }"
309
- );
310
- }).not.toThrow();
311
- });
312
-
313
- test("Test lookup with reserved keyword property names", () => {
314
- const parser = new Parser();
315
- const ast = parser.parse("with {end: 1, null: 2, case: 3} as x return x.end, x.null, x.case");
316
- expect(ast.print()).toBe(
317
- "ASTNode\n" +
318
- "- With\n" +
319
- "-- Expression (x)\n" +
320
- "--- AssociativeArray\n" +
321
- "---- KeyValuePair\n" +
322
- "----- String (end)\n" +
323
- "----- Expression\n" +
324
- "------ Number (1)\n" +
325
- "---- KeyValuePair\n" +
326
- "----- String (null)\n" +
327
- "----- Expression\n" +
328
- "------ Number (2)\n" +
329
- "---- KeyValuePair\n" +
330
- "----- String (case)\n" +
331
- "----- Expression\n" +
332
- "------ Number (3)\n" +
333
- "- Return\n" +
334
- "-- Expression\n" +
335
- "--- Lookup\n" +
336
- "---- Identifier (end)\n" +
337
- "---- Reference (x)\n" +
338
- "-- Expression\n" +
339
- "--- Lookup\n" +
340
- "---- Identifier (null)\n" +
341
- "---- Reference (x)\n" +
342
- "-- Expression\n" +
343
- "--- Lookup\n" +
344
- "---- Identifier (case)\n" +
345
- "---- Reference (x)"
346
- );
347
- });
348
-
349
- test("Test load with post", () => {
350
- const parser = new Parser();
351
- const ast = parser.parse(
352
- 'load json from "https://jsonplaceholder.typicode.com/posts" post {userId: 1} as data return data'
353
- );
354
- expect(ast.print()).toBe(
355
- "ASTNode\n" +
356
- "- Load\n" +
357
- "-- JSON\n" +
358
- "-- From\n" +
359
- "--- Expression\n" +
360
- "---- String (https://jsonplaceholder.typicode.com/posts)\n" +
361
- "-- Post\n" +
362
- "--- Expression\n" +
363
- "---- AssociativeArray\n" +
364
- "----- KeyValuePair\n" +
365
- "------ String (userId)\n" +
366
- "------ Expression\n" +
367
- "------- Number (1)\n" +
368
- "-- Alias (data)\n" +
369
- "- Return\n" +
370
- "-- Expression (data)\n" +
371
- "--- Reference (data)"
372
- );
373
- });
374
-
375
- test("Test nested aggregate functions", () => {
376
- expect(() => {
377
- const parser = new Parser();
378
- parser.parse("RETURN sum(sum(1))");
379
- }).toThrow("Aggregate functions cannot be nested");
380
- });
381
-
382
- test("Test with and return with renamed variable", () => {
383
- const parser = new Parser();
384
- const ast = parser.parse("WITH 1 AS n RETURN n AS m");
385
- expect(ast.print()).toBe(
386
- "ASTNode\n" +
387
- "- With\n" +
388
- "-- Expression (n)\n" +
389
- "--- Number (1)\n" +
390
- "- Return\n" +
391
- "-- Expression (m)\n" +
392
- "--- Reference (n)"
393
- );
394
- });
395
-
396
- test("Test with and return with variable lookup", () => {
397
- const parser = new Parser();
398
- const ast = parser.parse("WITH {a: n} AS obj RETURN obj.a");
399
- expect(ast.print()).toBe(
400
- "ASTNode\n" +
401
- "- With\n" +
402
- "-- Expression (obj)\n" +
403
- "--- AssociativeArray\n" +
404
- "---- KeyValuePair\n" +
405
- "----- String (a)\n" +
406
- "----- Expression\n" +
407
- "------ Reference (n)\n" +
408
- "- Return\n" +
409
- "-- Expression\n" +
410
- "--- Lookup\n" +
411
- "---- Identifier (a)\n" +
412
- "---- Reference (obj)"
413
- );
414
- });
415
-
416
- test("Test unwind", () => {
417
- const parser = new Parser();
418
- const ast = parser.parse("WITH [1, 2, 4] as n unwind n as i return i");
419
- expect(ast.print()).toBe(
420
- "ASTNode\n" +
421
- "- With\n" +
422
- "-- Expression (n)\n" +
423
- "--- JSONArray\n" +
424
- "---- Expression\n" +
425
- "----- Number (1)\n" +
426
- "---- Expression\n" +
427
- "----- Number (2)\n" +
428
- "---- Expression\n" +
429
- "----- Number (4)\n" +
430
- "- Unwind\n" +
431
- "-- Expression (i)\n" +
432
- "--- Reference (n)\n" +
433
- "- Return\n" +
434
- "-- Expression (i)\n" +
435
- "--- Reference (i)"
436
- );
437
- });
438
-
439
- test("Test predicate function", () => {
440
- const parser = new Parser();
441
- const ast = parser.parse("RETURN sum(n in [1, 2, 3] | n where n > 1)");
442
- expect(ast.print()).toBe(
443
- "ASTNode\n" +
444
- "- Return\n" +
445
- "-- Expression\n" +
446
- "--- PredicateFunction (sum)\n" +
447
- "---- Reference (n)\n" +
448
- "---- Expression\n" +
449
- "----- JSONArray\n" +
450
- "------ Expression\n" +
451
- "------- Number (1)\n" +
452
- "------ Expression\n" +
453
- "------- Number (2)\n" +
454
- "------ Expression\n" +
455
- "------- Number (3)\n" +
456
- "---- Expression\n" +
457
- "----- Reference (n)\n" +
458
- "---- Where\n" +
459
- "----- Expression\n" +
460
- "------ GreaterThan\n" +
461
- "------- Reference (n)\n" +
462
- "------- Number (1)"
463
- );
464
- });
465
-
466
- test("Test case statement", () => {
467
- const parser = new Parser();
468
- const ast = parser.parse("RETURN CASE WHEN 1 THEN 2 ELSE 3 END");
469
- expect(ast.print()).toBe(
470
- "ASTNode\n" +
471
- "- Return\n" +
472
- "-- Expression\n" +
473
- "--- Case\n" +
474
- "---- When\n" +
475
- "----- Expression\n" +
476
- "------ Number (1)\n" +
477
- "---- Then\n" +
478
- "----- Expression\n" +
479
- "------ Number (2)\n" +
480
- "---- Else\n" +
481
- "----- Expression\n" +
482
- "------ Number (3)"
483
- );
484
- });
485
-
486
- test("Test case statement with keywords as identifiers", () => {
487
- const parser = new Parser();
488
- const ast = parser.parse("RETURN CASE WHEN 1 THEN 2 ELSE 3 END");
489
- expect(ast.print()).toContain("Case");
490
- expect(ast.print()).toContain("When");
491
- expect(ast.print()).toContain("Then");
492
- expect(ast.print()).toContain("Else");
493
- });
494
-
495
- test("Test functions with wrong number of arguments", () => {
496
- expect(() => new Parser().parse("RETURN range(1)")).toThrow(
497
- "Function range expected 2 parameters, but got 1"
498
- );
499
- expect(() => new Parser().parse("RETURN range(1, 2, 3)")).toThrow(
500
- "Function range expected 2 parameters, but got 3"
501
- );
502
- expect(() => new Parser().parse("RETURN avg(1, 2, 3)")).toThrow(
503
- "Function avg expected 1 parameters, but got 3"
504
- );
505
- expect(() => new Parser().parse("RETURN sum(1, 2)")).toThrow(
506
- "Function sum expected 1 parameters, but got 2"
507
- );
508
- expect(() => new Parser().parse('RETURN split("a", "b", "c")')).toThrow(
509
- "Function split expected 2 parameters, but got 3"
510
- );
511
- expect(() => new Parser().parse("RETURN size(1, 2)")).toThrow(
512
- "Function size expected 1 parameters, but got 2"
513
- );
514
- expect(() => new Parser().parse("RETURN round(1, 2)")).toThrow(
515
- "Function round expected 1 parameters, but got 2"
516
- );
517
- });
518
-
519
- test("Test non-well formed statements", () => {
520
- expect(() => new Parser().parse("return 1 return 1")).toThrow(
521
- "Only one RETURN statement is allowed"
522
- );
523
- expect(() => new Parser().parse("return 1 with 1 as n")).toThrow(
524
- "Last statement must be a RETURN, WHERE, CALL, CREATE, or DELETE statement"
525
- );
526
- });
527
-
528
- test("Test associative array with backtick string", () => {
529
- const parser = new Parser();
530
- const ast = parser.parse("RETURN {`key`: `value`}");
531
- expect(ast.print()).toBe(
532
- "ASTNode\n" +
533
- "- Return\n" +
534
- "-- Expression\n" +
535
- "--- AssociativeArray\n" +
536
- "---- KeyValuePair\n" +
537
- "----- String (key)\n" +
538
- "----- Expression\n" +
539
- "------ Reference (value)"
540
- );
541
- });
542
-
543
- test("Test limit", () => {
544
- const parser = new Parser();
545
- const ast = parser.parse("unwind range(1, 10) as n limit 5 return n");
546
- expect(ast.print()).toBe(
547
- "ASTNode\n" +
548
- "- Unwind\n" +
549
- "-- Expression (n)\n" +
550
- "--- Function (range)\n" +
551
- "---- Expression\n" +
552
- "----- Number (1)\n" +
553
- "---- Expression\n" +
554
- "----- Number (10)\n" +
555
- "- Limit\n" +
556
- "- Return\n" +
557
- "-- Expression (n)\n" +
558
- "--- Reference (n)"
559
- );
560
- });
561
-
562
- test("Test return -2", () => {
563
- const parser = new Parser();
564
- const ast = parser.parse("return -2");
565
- // prettier-ignore
566
- expect(ast.print()).toBe(
567
- "ASTNode\n" +
568
- "- Return\n" +
569
- "-- Expression\n" +
570
- "--- Number (-2)"
571
- );
572
- });
573
-
574
- test("Test call operation", () => {
575
- const parser = new Parser();
576
- const ast = parser.parse("CALL test() YIELD result RETURN result");
577
- expect(ast.print()).toBe(
578
- "ASTNode\n" +
579
- "- Call\n" +
580
- "-- Expression (result)\n" +
581
- "--- Reference (result)\n" +
582
- "- Return\n" +
583
- "-- Expression (result)\n" +
584
- "--- Reference (result)"
585
- );
586
- });
587
-
588
- test("Test f-string", () => {
589
- const parser = new Parser();
590
- const ast = parser.parse("with 1 as value RETURN f'Value is: {value}.'");
591
- expect(ast.print()).toBe(
592
- "ASTNode\n" +
593
- "- With\n" +
594
- "-- Expression (value)\n" +
595
- "--- Number (1)\n" +
596
- "- Return\n" +
597
- "-- Expression\n" +
598
- "--- FString\n" +
599
- "---- String (Value is: )\n" +
600
- "---- Expression\n" +
601
- "----- Reference (value)\n" +
602
- "---- String (.)"
603
- );
604
- });
605
-
606
- test("Test create node operation", () => {
607
- const parser = new Parser();
608
- const ast = parser.parse(`
609
- CREATE VIRTUAL (:Person) AS {
610
- unwind range(1, 3) AS id
611
- return id, f'Person {id}' AS name
612
- }
613
- `);
614
- // prettier-ignore
615
- expect(ast.print()).toBe(
616
- "ASTNode\n" +
617
- "- CreateNode"
618
- );
619
- const create: CreateNode = ast.firstChild() as CreateNode;
620
- expect(create.node).not.toBeNull();
621
- expect(create.node!.label).toBe("Person");
622
- expect(create.statement!.print()).toBe(
623
- "ASTNode\n" +
624
- "- Unwind\n" +
625
- "-- Expression (id)\n" +
626
- "--- Function (range)\n" +
627
- "---- Expression\n" +
628
- "----- Number (1)\n" +
629
- "---- Expression\n" +
630
- "----- Number (3)\n" +
631
- "- Return\n" +
632
- "-- Expression (id)\n" +
633
- "--- Reference (id)\n" +
634
- "-- Expression (name)\n" +
635
- "--- FString\n" +
636
- "---- String (Person )\n" +
637
- "---- Expression\n" +
638
- "----- Reference (id)\n" +
639
- "---- String ()"
640
- );
641
- });
642
-
643
- test("Test match operation", () => {
644
- const parser = new Parser();
645
- const ast = parser.parse("MATCH (n:Person) RETURN n");
646
- // prettier-ignore
647
- expect(ast.print()).toBe(
648
- "ASTNode\n" +
649
- "- Match\n" +
650
- "- Return\n" +
651
- "-- Expression (n)\n" +
652
- "--- Reference (n)"
653
- );
654
- const match = ast.firstChild() as Match;
655
- expect(match.patterns[0].startNode).not.toBeNull();
656
- expect(match.patterns[0].startNode!.label).toBe("Person");
657
- expect(match.patterns[0].startNode!.identifier).toBe("n");
658
- });
659
-
660
- test("Test create relationship operation", () => {
661
- const parser = new Parser();
662
- const ast = parser.parse(`
663
- CREATE VIRTUAL (:Person)-[:KNOWS]-(:Person) AS {
664
- unwind [
665
- {from_id: 1, to_id: 2, since: '2020-01-01'},
666
- {from_id: 2, to_id: 3, since: '2021-01-01'}
667
- ] AS pair
668
- return pair.from_id AS from, pair.to_id AS to, pair.since AS since
669
- }
670
- `);
671
- // prettier-ignore
672
- expect(ast.print()).toBe(
673
- "ASTNode\n" +
674
- "- CreateRelationship"
675
- );
676
- const create = ast.firstChild() as CreateRelationship;
677
- expect(create.relationship).not.toBeNull();
678
- expect(create.relationship!.type).toBe("KNOWS");
679
- expect(create.statement!.print()).toBe(
680
- "ASTNode\n" +
681
- "- Unwind\n" +
682
- "-- Expression (pair)\n" +
683
- "--- JSONArray\n" +
684
- "---- Expression\n" +
685
- "----- AssociativeArray\n" +
686
- "------ KeyValuePair\n" +
687
- "------- String (from_id)\n" +
688
- "------- Expression\n" +
689
- "-------- Number (1)\n" +
690
- "------ KeyValuePair\n" +
691
- "------- String (to_id)\n" +
692
- "------- Expression\n" +
693
- "-------- Number (2)\n" +
694
- "------ KeyValuePair\n" +
695
- "------- String (since)\n" +
696
- "------- Expression\n" +
697
- "-------- String (2020-01-01)\n" +
698
- "---- Expression\n" +
699
- "----- AssociativeArray\n" +
700
- "------ KeyValuePair\n" +
701
- "------- String (from_id)\n" +
702
- "------- Expression\n" +
703
- "-------- Number (2)\n" +
704
- "------ KeyValuePair\n" +
705
- "------- String (to_id)\n" +
706
- "------- Expression\n" +
707
- "-------- Number (3)\n" +
708
- "------ KeyValuePair\n" +
709
- "------- String (since)\n" +
710
- "------- Expression\n" +
711
- "-------- String (2021-01-01)\n" +
712
- "- Return\n" +
713
- "-- Expression (from)\n" +
714
- "--- Lookup\n" +
715
- "---- Identifier (from_id)\n" +
716
- "---- Reference (pair)\n" +
717
- "-- Expression (to)\n" +
718
- "--- Lookup\n" +
719
- "---- Identifier (to_id)\n" +
720
- "---- Reference (pair)\n" +
721
- "-- Expression (since)\n" +
722
- "--- Lookup\n" +
723
- "---- Identifier (since)\n" +
724
- "---- Reference (pair)"
725
- );
726
- });
727
-
728
- test("Match with graph pattern including relationships", () => {
729
- const parser = new Parser();
730
- const ast = parser.parse("MATCH (a:Person)-[:KNOWS]-(b:Person) RETURN a, b");
731
- // prettier-ignore
732
- expect(ast.print()).toBe(
733
- "ASTNode\n" +
734
- "- Match\n" +
735
- "- Return\n" +
736
- "-- Expression (a)\n" +
737
- "--- Reference (a)\n" +
738
- "-- Expression (b)\n" +
739
- "--- Reference (b)"
740
- );
741
- const match = ast.firstChild() as Match;
742
- expect(match.patterns[0].chain.length).toBe(3);
743
- const source = match.patterns[0].chain[0] as Node;
744
- const relationship = match.patterns[0].chain[1] as Relationship;
745
- const target = match.patterns[0].chain[2] as Node;
746
- expect(source.identifier).toBe("a");
747
- expect(source.label).toBe("Person");
748
- expect(relationship.type).toBe("KNOWS");
749
- expect(target.identifier).toBe("b");
750
- expect(target.label).toBe("Person");
751
- });
752
-
753
- test("Match with ORed relationship types", () => {
754
- const parser = new Parser();
755
- const ast = parser.parse("MATCH (a:Person)-[:KNOWS|FOLLOWS]->(b:Person) RETURN a, b");
756
- const match = ast.firstChild() as Match;
757
- expect(match.patterns[0].chain.length).toBe(3);
758
- const relationship = match.patterns[0].chain[1] as Relationship;
759
- expect(relationship.types).toEqual(["KNOWS", "FOLLOWS"]);
760
- expect(relationship.type).toBe("KNOWS");
761
- });
762
-
763
- test("Match with ORed relationship types with optional colons", () => {
764
- const parser = new Parser();
765
- const ast = parser.parse("MATCH (a:Person)-[:KNOWS|:FOLLOWS|:LIKES]->(b:Person) RETURN a, b");
766
- const match = ast.firstChild() as Match;
767
- const relationship = match.patterns[0].chain[1] as Relationship;
768
- expect(relationship.types).toEqual(["KNOWS", "FOLLOWS", "LIKES"]);
769
- });
770
-
771
- test("Match with ORed relationship types and variable", () => {
772
- const parser = new Parser();
773
- const ast = parser.parse("MATCH (a:Person)-[r:KNOWS|FOLLOWS]->(b:Person) RETURN a, r, b");
774
- const match = ast.firstChild() as Match;
775
- const relationship = match.patterns[0].chain[1] as Relationship;
776
- expect(relationship.identifier).toBe("r");
777
- expect(relationship.types).toEqual(["KNOWS", "FOLLOWS"]);
778
- });
779
-
780
- test("Match with ORed relationship types and hops", () => {
781
- const parser = new Parser();
782
- const ast = parser.parse("MATCH (a:Person)-[:KNOWS|FOLLOWS*1..3]->(b:Person) RETURN a, b");
783
- const match = ast.firstChild() as Match;
784
- const relationship = match.patterns[0].chain[1] as Relationship;
785
- expect(relationship.types).toEqual(["KNOWS", "FOLLOWS"]);
786
- expect(relationship.hops!.min).toBe(1);
787
- expect(relationship.hops!.max).toBe(3);
788
- });
789
-
790
- test("Test not equal operator", () => {
791
- const parser = new Parser();
792
- const ast = parser.parse("RETURN 1 <> 2");
793
- expect(ast.print()).toBe(
794
- "ASTNode\n" +
795
- "- Return\n" +
796
- "-- Expression\n" +
797
- "--- NotEquals\n" +
798
- "---- Number (1)\n" +
799
- "---- Number (2)"
800
- );
801
- });
802
-
803
- test("Test equal operator", () => {
804
- const parser = new Parser();
805
- const ast = parser.parse("RETURN 1 = 2");
806
- expect(ast.print()).toBe(
807
- "ASTNode\n" +
808
- "- Return\n" +
809
- "-- Expression\n" +
810
- "--- Equals\n" +
811
- "---- Number (1)\n" +
812
- "---- Number (2)"
813
- );
814
- });
815
-
816
- test("Test not operator", () => {
817
- const parser = new Parser();
818
- const ast = parser.parse("RETURN NOT true");
819
- // prettier-ignore
820
- expect(ast.print()).toBe(
821
- "ASTNode\n" +
822
- "- Return\n" +
823
- "-- Expression\n" +
824
- "--- Not\n" +
825
- "---- Expression\n" +
826
- "----- Boolean"
827
- );
828
- });
829
-
830
- test("Parse relationship with hops", () => {
831
- const parser = new Parser();
832
- const ast = parser.parse("MATCH (a:Test)-[:KNOWS*1..3]->(b:Test) RETURN a, b");
833
- // prettier-ignore
834
- expect(ast.print()).toBe(
835
- "ASTNode\n" +
836
- "- Match\n" +
837
- "- Return\n" +
838
- "-- Expression (a)\n" +
839
- "--- Reference (a)\n" +
840
- "-- Expression (b)\n" +
841
- "--- Reference (b)"
842
- );
843
- const match = ast.firstChild() as Match;
844
- expect(match.patterns[0].chain.length).toBe(3);
845
- const source = match.patterns[0].chain[0] as Node;
846
- const relationship = match.patterns[0].chain[1] as Relationship;
847
- const target = match.patterns[0].chain[2] as Node;
848
- expect(source.identifier).toBe("a");
849
- expect(relationship.type).toBe("KNOWS");
850
- expect(relationship.hops).not.toBeNull();
851
- expect(relationship.hops!.min).toBe(1);
852
- expect(relationship.hops!.max).toBe(3);
853
- expect(target.identifier).toBe("b");
854
- });
855
-
856
- test("Parse statement with graph pattern in where clause", () => {
857
- const parser = new Parser();
858
- const ast = parser.parse("MATCH (a:Person) WHERE (a)-[:KNOWS]->(:Person) RETURN a");
859
- // prettier-ignore
860
- expect(ast.print()).toBe(
861
- "ASTNode\n" +
862
- "- Match\n" +
863
- "- Where\n" +
864
- "-- Expression\n" +
865
- "--- PatternExpression\n" +
866
- "- Return\n" +
867
- "-- Expression (a)\n" +
868
- "--- Reference (a)"
869
- );
870
- const match = ast.firstChild() as Match;
871
- expect(match.patterns[0].startNode).not.toBeNull();
872
- expect(match.patterns[0].startNode!.identifier).toBe("a");
873
- const where = match.next as any;
874
- const pattern = where.firstChild().firstChild() as any;
875
- expect(pattern.chain.length).toBe(3);
876
- const source = pattern.chain[0] as NodeReference;
877
- const relationship = pattern.chain[1] as Relationship;
878
- const target = pattern.chain[2] as Node;
879
- expect((source.reference as Node)?.identifier).toBe("a");
880
- expect(relationship.type).toBe("KNOWS");
881
- expect(target.label).toBe("Person");
882
- });
883
-
884
- test("Test check pattern expression without NodeReference", () => {
885
- const parser = new Parser();
886
- // Should throw an error because pattern does not start with NodeReference
887
- expect(() => {
888
- parser.parse("MATCH (a:Person) WHERE (:Person)-[:KNOWS]->(:Person) RETURN a");
889
- }).toThrow("PatternExpression must contain at least one NodeReference");
890
- });
891
-
892
- test("Test node with properties", () => {
893
- const parser = new Parser();
894
- const ast = parser.parse("MATCH (a:Person{value: 'hello'}) return a");
895
- // prettier-ignore
896
- expect(ast.print()).toBe(
897
- "ASTNode\n" +
898
- "- Match\n" +
899
- "- Return\n" +
900
- "-- Expression (a)\n" +
901
- "--- Reference (a)"
902
- );
903
- const match: Match = ast.firstChild() as Match;
904
- const node: Node = match.patterns[0].chain[0] as Node;
905
- expect(node.properties.get("value")?.value()).toBe("hello");
906
- });
907
-
908
- test("Test WHERE in CREATE VIRTUAL sub-query", () => {
909
- const parser = new Parser();
910
- const ast = parser.parse(`
911
- CREATE VIRTUAL (:Email)-[:HAS_ATTACHMENT]-(:File) AS {
912
- LOAD JSON FROM '/data/emails.json' AS email
913
- WHERE email.hasAttachments = true
914
- UNWIND email.attachments AS fileId
915
- RETURN email.id AS left_id, fileId AS right_id
916
- }
917
- `);
918
- const create = ast.firstChild() as CreateRelationship;
919
- expect(create.relationship).not.toBeNull();
920
- expect(create.relationship!.type).toBe("HAS_ATTACHMENT");
921
- expect(create.statement).not.toBeNull();
922
- });
923
-
924
- test("Test relationship with properties", () => {
925
- const parser = new Parser();
926
- const ast = parser.parse("MATCH (:Person)-[r:LIKES{since: 2022}]->(:Food) return a");
927
- // prettier-ignore
928
- expect(ast.print()).toBe(
929
- "ASTNode\n" +
930
- "- Match\n" +
931
- "- Return\n" +
932
- "-- Expression (a)\n" +
933
- "--- Reference (a)"
934
- );
935
- const match: Match = ast.firstChild() as Match;
936
- const relationship: Relationship = match.patterns[0].chain[1] as Relationship;
937
- expect(relationship.properties.get("since")?.value()).toBe(2022);
938
- });
939
-
940
- test("Test node reference with label creates NodeReference instead of new node", () => {
941
- const parser = new Parser();
942
- const ast = parser.parse("MATCH (n:Person)-[:KNOWS]->(n:Person) RETURN n");
943
- const match: Match = ast.firstChild() as Match;
944
- const firstNode = match.patterns[0].chain[0] as Node;
945
- const secondNode = match.patterns[0].chain[2] as NodeReference;
946
- expect(firstNode.identifier).toBe("n");
947
- expect(firstNode.label).toBe("Person");
948
- expect(secondNode).toBeInstanceOf(NodeReference);
949
- expect((secondNode.reference! as Node).identifier).toBe("n");
950
- expect(secondNode.label).toBe("Person");
951
- });
952
-
953
- test("Test relationship reference with type creates RelationshipReference instead of new relationship", () => {
954
- const parser = new Parser();
955
- const ast = parser.parse(
956
- "MATCH (a:Person)-[r:KNOWS]->(b:Person)-[r:KNOWS]->(c:Person) RETURN a, b, c"
957
- );
958
- const match: Match = ast.firstChild() as Match;
959
- const firstRel = match.patterns[0].chain[1] as Relationship;
960
- const secondRel = match.patterns[0].chain[3] as RelationshipReference;
961
- expect(firstRel.identifier).toBe("r");
962
- expect(firstRel.type).toBe("KNOWS");
963
- expect(secondRel).toBeInstanceOf(RelationshipReference);
964
- expect(secondRel.type).toBe("KNOWS");
965
- });
966
-
967
- test("Test WHERE with IN list check", () => {
968
- const parser = new Parser();
969
- const ast = parser.parse("with 1 as n where n IN [1, 2, 3] return n");
970
- // prettier-ignore
971
- expect(ast.print()).toBe(
972
- "ASTNode\n" +
973
- "- With\n" +
974
- "-- Expression (n)\n" +
975
- "--- Number (1)\n" +
976
- "- Where\n" +
977
- "-- Expression\n" +
978
- "--- In\n" +
979
- "---- Reference (n)\n" +
980
- "---- JSONArray\n" +
981
- "----- Expression\n" +
982
- "------ Number (1)\n" +
983
- "----- Expression\n" +
984
- "------ Number (2)\n" +
985
- "----- Expression\n" +
986
- "------ Number (3)\n" +
987
- "- Return\n" +
988
- "-- Expression (n)\n" +
989
- "--- Reference (n)"
990
- );
991
- });
992
-
993
- test("Test WHERE with NOT IN list check", () => {
994
- const parser = new Parser();
995
- const ast = parser.parse("with 4 as n where n NOT IN [1, 2, 3] return n");
996
- // prettier-ignore
997
- expect(ast.print()).toBe(
998
- "ASTNode\n" +
999
- "- With\n" +
1000
- "-- Expression (n)\n" +
1001
- "--- Number (4)\n" +
1002
- "- Where\n" +
1003
- "-- Expression\n" +
1004
- "--- NotIn\n" +
1005
- "---- Reference (n)\n" +
1006
- "---- JSONArray\n" +
1007
- "----- Expression\n" +
1008
- "------ Number (1)\n" +
1009
- "----- Expression\n" +
1010
- "------ Number (2)\n" +
1011
- "----- Expression\n" +
1012
- "------ Number (3)\n" +
1013
- "- Return\n" +
1014
- "-- Expression (n)\n" +
1015
- "--- Reference (n)"
1016
- );
1017
- });
1018
-
1019
- test("Test WHERE with CONTAINS", () => {
1020
- const parser = new Parser();
1021
- const ast = parser.parse("with 'hello' as s where s CONTAINS 'ell' return s");
1022
- // prettier-ignore
1023
- expect(ast.print()).toBe(
1024
- "ASTNode\n" +
1025
- "- With\n" +
1026
- "-- Expression (s)\n" +
1027
- "--- String (hello)\n" +
1028
- "- Where\n" +
1029
- "-- Expression\n" +
1030
- "--- Contains\n" +
1031
- "---- Reference (s)\n" +
1032
- "---- String (ell)\n" +
1033
- "- Return\n" +
1034
- "-- Expression (s)\n" +
1035
- "--- Reference (s)"
1036
- );
1037
- });
1038
-
1039
- test("Test WHERE with NOT CONTAINS", () => {
1040
- const parser = new Parser();
1041
- const ast = parser.parse("with 'hello' as s where s NOT CONTAINS 'xyz' return s");
1042
- // prettier-ignore
1043
- expect(ast.print()).toBe(
1044
- "ASTNode\n" +
1045
- "- With\n" +
1046
- "-- Expression (s)\n" +
1047
- "--- String (hello)\n" +
1048
- "- Where\n" +
1049
- "-- Expression\n" +
1050
- "--- NotContains\n" +
1051
- "---- Reference (s)\n" +
1052
- "---- String (xyz)\n" +
1053
- "- Return\n" +
1054
- "-- Expression (s)\n" +
1055
- "--- Reference (s)"
1056
- );
1057
- });
1058
-
1059
- test("Test WHERE with STARTS WITH", () => {
1060
- const parser = new Parser();
1061
- const ast = parser.parse("with 'hello' as s where s STARTS WITH 'hel' return s");
1062
- // prettier-ignore
1063
- expect(ast.print()).toBe(
1064
- "ASTNode\n" +
1065
- "- With\n" +
1066
- "-- Expression (s)\n" +
1067
- "--- String (hello)\n" +
1068
- "- Where\n" +
1069
- "-- Expression\n" +
1070
- "--- StartsWith\n" +
1071
- "---- Reference (s)\n" +
1072
- "---- String (hel)\n" +
1073
- "- Return\n" +
1074
- "-- Expression (s)\n" +
1075
- "--- Reference (s)"
1076
- );
1077
- });
1078
-
1079
- test("Test WHERE with NOT STARTS WITH", () => {
1080
- const parser = new Parser();
1081
- const ast = parser.parse("with 'hello' as s where s NOT STARTS WITH 'xyz' return s");
1082
- // prettier-ignore
1083
- expect(ast.print()).toBe(
1084
- "ASTNode\n" +
1085
- "- With\n" +
1086
- "-- Expression (s)\n" +
1087
- "--- String (hello)\n" +
1088
- "- Where\n" +
1089
- "-- Expression\n" +
1090
- "--- NotStartsWith\n" +
1091
- "---- Reference (s)\n" +
1092
- "---- String (xyz)\n" +
1093
- "- Return\n" +
1094
- "-- Expression (s)\n" +
1095
- "--- Reference (s)"
1096
- );
1097
- });
1098
-
1099
- test("Test WHERE with ENDS WITH", () => {
1100
- const parser = new Parser();
1101
- const ast = parser.parse("with 'hello' as s where s ENDS WITH 'llo' return s");
1102
- // prettier-ignore
1103
- expect(ast.print()).toBe(
1104
- "ASTNode\n" +
1105
- "- With\n" +
1106
- "-- Expression (s)\n" +
1107
- "--- String (hello)\n" +
1108
- "- Where\n" +
1109
- "-- Expression\n" +
1110
- "--- EndsWith\n" +
1111
- "---- Reference (s)\n" +
1112
- "---- String (llo)\n" +
1113
- "- Return\n" +
1114
- "-- Expression (s)\n" +
1115
- "--- Reference (s)"
1116
- );
1117
- });
1118
-
1119
- test("Test WHERE with NOT ENDS WITH", () => {
1120
- const parser = new Parser();
1121
- const ast = parser.parse("with 'hello' as s where s NOT ENDS WITH 'xyz' return s");
1122
- // prettier-ignore
1123
- expect(ast.print()).toBe(
1124
- "ASTNode\n" +
1125
- "- With\n" +
1126
- "-- Expression (s)\n" +
1127
- "--- String (hello)\n" +
1128
- "- Where\n" +
1129
- "-- Expression\n" +
1130
- "--- NotEndsWith\n" +
1131
- "---- Reference (s)\n" +
1132
- "---- String (xyz)\n" +
1133
- "- Return\n" +
1134
- "-- Expression (s)\n" +
1135
- "--- Reference (s)"
1136
- );
1137
- });
1138
-
1139
- test("Test parenthesized expression with addition", () => {
1140
- const parser = new Parser();
1141
- const ast = parser.parse("WITH 1 AS n RETURN (n + 2)");
1142
- // prettier-ignore
1143
- expect(ast.print()).toBe(
1144
- "ASTNode\n" +
1145
- "- With\n" +
1146
- "-- Expression (n)\n" +
1147
- "--- Number (1)\n" +
1148
- "- Return\n" +
1149
- "-- Expression\n" +
1150
- "--- Expression\n" +
1151
- "---- Add\n" +
1152
- "----- Reference (n)\n" +
1153
- "----- Number (2)"
1154
- );
1155
- });
1156
-
1157
- test("Test parenthesized expression with property access", () => {
1158
- const parser = new Parser();
1159
- const ast = parser.parse("WITH {a: 1} AS obj RETURN (obj.a)");
1160
- // prettier-ignore
1161
- expect(ast.print()).toBe(
1162
- "ASTNode\n" +
1163
- "- With\n" +
1164
- "-- Expression (obj)\n" +
1165
- "--- AssociativeArray\n" +
1166
- "---- KeyValuePair\n" +
1167
- "----- String (a)\n" +
1168
- "----- Expression\n" +
1169
- "------ Number (1)\n" +
1170
- "- Return\n" +
1171
- "-- Expression\n" +
1172
- "--- Expression\n" +
1173
- "---- Lookup\n" +
1174
- "----- Identifier (a)\n" +
1175
- "----- Reference (obj)"
1176
- );
1177
- });
1178
-
1179
- test("Test parenthesized expression with multiplication", () => {
1180
- const parser = new Parser();
1181
- const ast = parser.parse("WITH 5 AS x RETURN (x * 3)");
1182
- // prettier-ignore
1183
- expect(ast.print()).toBe(
1184
- "ASTNode\n" +
1185
- "- With\n" +
1186
- "-- Expression (x)\n" +
1187
- "--- Number (5)\n" +
1188
- "- Return\n" +
1189
- "-- Expression\n" +
1190
- "--- Expression\n" +
1191
- "---- Multiply\n" +
1192
- "----- Reference (x)\n" +
1193
- "----- Number (3)"
1194
- );
1195
- });
1196
-
1197
- test("Test optional match operation", () => {
1198
- const parser = new Parser();
1199
- const ast = parser.parse("OPTIONAL MATCH (n:Person) RETURN n");
1200
- // prettier-ignore
1201
- expect(ast.print()).toBe(
1202
- "ASTNode\n" +
1203
- "- OptionalMatch\n" +
1204
- "- Return\n" +
1205
- "-- Expression (n)\n" +
1206
- "--- Reference (n)"
1207
- );
1208
- const match = ast.firstChild() as Match;
1209
- expect(match.optional).toBe(true);
1210
- expect(match.patterns[0].startNode).not.toBeNull();
1211
- expect(match.patterns[0].startNode!.label).toBe("Person");
1212
- expect(match.patterns[0].startNode!.identifier).toBe("n");
1213
- });
1214
-
1215
- test("Optional match with relationships", () => {
1216
- const parser = new Parser();
1217
- const ast = parser.parse("OPTIONAL MATCH (a:Person)-[:KNOWS]-(b:Person) RETURN a, b");
1218
- // prettier-ignore
1219
- expect(ast.print()).toBe(
1220
- "ASTNode\n" +
1221
- "- OptionalMatch\n" +
1222
- "- Return\n" +
1223
- "-- Expression (a)\n" +
1224
- "--- Reference (a)\n" +
1225
- "-- Expression (b)\n" +
1226
- "--- Reference (b)"
1227
- );
1228
- const match = ast.firstChild() as Match;
1229
- expect(match.optional).toBe(true);
1230
- expect(match.patterns[0].chain.length).toBe(3);
1231
- const source = match.patterns[0].chain[0] as Node;
1232
- const relationship = match.patterns[0].chain[1] as Relationship;
1233
- const target = match.patterns[0].chain[2] as Node;
1234
- expect(source.identifier).toBe("a");
1235
- expect(source.label).toBe("Person");
1236
- expect(relationship.type).toBe("KNOWS");
1237
- expect(target.identifier).toBe("b");
1238
- expect(target.label).toBe("Person");
1239
- });
1240
-
1241
- test("Match followed by optional match", () => {
1242
- const parser = new Parser();
1243
- const ast = parser.parse("MATCH (a:Person) OPTIONAL MATCH (a)-[:KNOWS]-(b:Person) RETURN a, b");
1244
- // prettier-ignore
1245
- expect(ast.print()).toBe(
1246
- "ASTNode\n" +
1247
- "- Match\n" +
1248
- "- OptionalMatch\n" +
1249
- "- Return\n" +
1250
- "-- Expression (a)\n" +
1251
- "--- Reference (a)\n" +
1252
- "-- Expression (b)\n" +
1253
- "--- Reference (b)"
1254
- );
1255
- const match = ast.firstChild() as Match;
1256
- expect(match.optional).toBe(false);
1257
- const optionalMatch = match.next as Match;
1258
- expect(optionalMatch.optional).toBe(true);
1259
- });
1260
-
1261
- test("Regular match is not optional", () => {
1262
- const parser = new Parser();
1263
- const ast = parser.parse("MATCH (n:Person) RETURN n");
1264
- const match = ast.firstChild() as Match;
1265
- expect(match.optional).toBe(false);
1266
- });
1267
-
1268
- test("OPTIONAL without MATCH throws error", () => {
1269
- const parser = new Parser();
1270
- expect(() => parser.parse("OPTIONAL RETURN 1")).toThrow("Expected MATCH after OPTIONAL");
1271
- });
1272
-
1273
- // ORDER BY expression tests
1274
-
1275
- test("ORDER BY with simple identifier parses correctly", () => {
1276
- const parser = new Parser();
1277
- const ast = parser.parse("unwind [1, 2] as x return x order by x");
1278
- expect(ast).toBeDefined();
1279
- });
1280
-
1281
- test("ORDER BY with property access parses correctly", () => {
1282
- const parser = new Parser();
1283
- const ast = parser.parse(
1284
- "unwind [{name: 'Bob'}, {name: 'Alice'}] as person return person.name as name order by person.name asc"
1285
- );
1286
- expect(ast).toBeDefined();
1287
- });
1288
-
1289
- test("ORDER BY with function call parses correctly", () => {
1290
- const parser = new Parser();
1291
- const ast = parser.parse(
1292
- "unwind ['HELLO', 'WORLD'] as word return word order by toLower(word) asc"
1293
- );
1294
- expect(ast).toBeDefined();
1295
- });
1296
-
1297
- test("ORDER BY with nested function calls parses correctly", () => {
1298
- const parser = new Parser();
1299
- const ast = parser.parse(
1300
- "unwind ['Alice', 'Bob'] as name return name order by string_distance(toLower(name), toLower('alice')) asc"
1301
- );
1302
- expect(ast).toBeDefined();
1303
- });
1304
-
1305
- test("ORDER BY with arithmetic expression parses correctly", () => {
1306
- const parser = new Parser();
1307
- const ast = parser.parse(
1308
- "unwind [{a: 3, b: 1}, {a: 1, b: 5}] as item return item.a as a, item.b as b order by item.a + item.b desc"
1309
- );
1310
- expect(ast).toBeDefined();
1311
- });
1312
-
1313
- test("ORDER BY with multiple expression fields parses correctly", () => {
1314
- const parser = new Parser();
1315
- const ast = parser.parse(
1316
- "unwind [{a: 1, b: 2}] as item return item.a as a, item.b as b order by toLower(item.a) asc, item.b desc"
1317
- );
1318
- expect(ast).toBeDefined();
1319
- });
1320
-
1321
- test("ORDER BY with expression and LIMIT parses correctly", () => {
1322
- const parser = new Parser();
1323
- const ast = parser.parse(
1324
- "unwind ['c', 'a', 'b'] as x return x order by toLower(x) asc limit 2"
1325
- );
1326
- expect(ast).toBeDefined();
1327
- });