flowquery 1.0.46 → 1.0.47

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 (413) hide show
  1. package/dist/index.d.ts +0 -7
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +6 -4
  4. package/dist/index.js.map +1 -1
  5. package/package.json +4 -1
  6. package/.editorconfig +0 -21
  7. package/.gitattributes +0 -3
  8. package/.github/workflows/npm-publish.yml +0 -32
  9. package/.github/workflows/python-publish.yml +0 -143
  10. package/.github/workflows/release.yml +0 -107
  11. package/.husky/pre-commit +0 -28
  12. package/.prettierrc +0 -22
  13. package/CODE_OF_CONDUCT.md +0 -10
  14. package/FlowQueryLogoIcon.png +0 -0
  15. package/SECURITY.md +0 -14
  16. package/SUPPORT.md +0 -13
  17. package/docs/flowquery.min.js +0 -1
  18. package/docs/index.html +0 -105
  19. package/flowquery-py/CONTRIBUTING.md +0 -127
  20. package/flowquery-py/README.md +0 -67
  21. package/flowquery-py/misc/data/test.json +0 -10
  22. package/flowquery-py/misc/data/users.json +0 -242
  23. package/flowquery-py/notebooks/TestFlowQuery.ipynb +0 -440
  24. package/flowquery-py/pyproject.toml +0 -121
  25. package/flowquery-py/setup_env.ps1 +0 -92
  26. package/flowquery-py/setup_env.sh +0 -87
  27. package/flowquery-py/src/__init__.py +0 -38
  28. package/flowquery-py/src/__main__.py +0 -10
  29. package/flowquery-py/src/compute/__init__.py +0 -6
  30. package/flowquery-py/src/compute/flowquery.py +0 -68
  31. package/flowquery-py/src/compute/runner.py +0 -64
  32. package/flowquery-py/src/extensibility.py +0 -52
  33. package/flowquery-py/src/graph/__init__.py +0 -31
  34. package/flowquery-py/src/graph/data.py +0 -136
  35. package/flowquery-py/src/graph/database.py +0 -141
  36. package/flowquery-py/src/graph/hops.py +0 -43
  37. package/flowquery-py/src/graph/node.py +0 -143
  38. package/flowquery-py/src/graph/node_data.py +0 -26
  39. package/flowquery-py/src/graph/node_reference.py +0 -50
  40. package/flowquery-py/src/graph/pattern.py +0 -115
  41. package/flowquery-py/src/graph/pattern_expression.py +0 -67
  42. package/flowquery-py/src/graph/patterns.py +0 -42
  43. package/flowquery-py/src/graph/physical_node.py +0 -41
  44. package/flowquery-py/src/graph/physical_relationship.py +0 -36
  45. package/flowquery-py/src/graph/relationship.py +0 -193
  46. package/flowquery-py/src/graph/relationship_data.py +0 -36
  47. package/flowquery-py/src/graph/relationship_match_collector.py +0 -85
  48. package/flowquery-py/src/graph/relationship_reference.py +0 -21
  49. package/flowquery-py/src/io/__init__.py +0 -5
  50. package/flowquery-py/src/io/command_line.py +0 -108
  51. package/flowquery-py/src/parsing/__init__.py +0 -17
  52. package/flowquery-py/src/parsing/alias.py +0 -20
  53. package/flowquery-py/src/parsing/alias_option.py +0 -11
  54. package/flowquery-py/src/parsing/ast_node.py +0 -147
  55. package/flowquery-py/src/parsing/base_parser.py +0 -84
  56. package/flowquery-py/src/parsing/components/__init__.py +0 -19
  57. package/flowquery-py/src/parsing/components/csv.py +0 -8
  58. package/flowquery-py/src/parsing/components/from_.py +0 -12
  59. package/flowquery-py/src/parsing/components/headers.py +0 -12
  60. package/flowquery-py/src/parsing/components/json.py +0 -8
  61. package/flowquery-py/src/parsing/components/null.py +0 -10
  62. package/flowquery-py/src/parsing/components/post.py +0 -8
  63. package/flowquery-py/src/parsing/components/text.py +0 -8
  64. package/flowquery-py/src/parsing/context.py +0 -50
  65. package/flowquery-py/src/parsing/data_structures/__init__.py +0 -15
  66. package/flowquery-py/src/parsing/data_structures/associative_array.py +0 -41
  67. package/flowquery-py/src/parsing/data_structures/json_array.py +0 -30
  68. package/flowquery-py/src/parsing/data_structures/key_value_pair.py +0 -38
  69. package/flowquery-py/src/parsing/data_structures/lookup.py +0 -51
  70. package/flowquery-py/src/parsing/data_structures/range_lookup.py +0 -42
  71. package/flowquery-py/src/parsing/expressions/__init__.py +0 -61
  72. package/flowquery-py/src/parsing/expressions/boolean.py +0 -20
  73. package/flowquery-py/src/parsing/expressions/expression.py +0 -141
  74. package/flowquery-py/src/parsing/expressions/expression_map.py +0 -26
  75. package/flowquery-py/src/parsing/expressions/f_string.py +0 -27
  76. package/flowquery-py/src/parsing/expressions/identifier.py +0 -21
  77. package/flowquery-py/src/parsing/expressions/number.py +0 -32
  78. package/flowquery-py/src/parsing/expressions/operator.py +0 -271
  79. package/flowquery-py/src/parsing/expressions/reference.py +0 -47
  80. package/flowquery-py/src/parsing/expressions/string.py +0 -27
  81. package/flowquery-py/src/parsing/functions/__init__.py +0 -127
  82. package/flowquery-py/src/parsing/functions/aggregate_function.py +0 -60
  83. package/flowquery-py/src/parsing/functions/async_function.py +0 -65
  84. package/flowquery-py/src/parsing/functions/avg.py +0 -55
  85. package/flowquery-py/src/parsing/functions/coalesce.py +0 -43
  86. package/flowquery-py/src/parsing/functions/collect.py +0 -75
  87. package/flowquery-py/src/parsing/functions/count.py +0 -79
  88. package/flowquery-py/src/parsing/functions/date_.py +0 -61
  89. package/flowquery-py/src/parsing/functions/datetime_.py +0 -62
  90. package/flowquery-py/src/parsing/functions/duration.py +0 -159
  91. package/flowquery-py/src/parsing/functions/element_id.py +0 -50
  92. package/flowquery-py/src/parsing/functions/function.py +0 -68
  93. package/flowquery-py/src/parsing/functions/function_factory.py +0 -170
  94. package/flowquery-py/src/parsing/functions/function_metadata.py +0 -148
  95. package/flowquery-py/src/parsing/functions/functions.py +0 -67
  96. package/flowquery-py/src/parsing/functions/head.py +0 -39
  97. package/flowquery-py/src/parsing/functions/id_.py +0 -49
  98. package/flowquery-py/src/parsing/functions/join.py +0 -49
  99. package/flowquery-py/src/parsing/functions/keys.py +0 -34
  100. package/flowquery-py/src/parsing/functions/last.py +0 -39
  101. package/flowquery-py/src/parsing/functions/localdatetime.py +0 -60
  102. package/flowquery-py/src/parsing/functions/localtime.py +0 -57
  103. package/flowquery-py/src/parsing/functions/max_.py +0 -49
  104. package/flowquery-py/src/parsing/functions/min_.py +0 -49
  105. package/flowquery-py/src/parsing/functions/nodes.py +0 -48
  106. package/flowquery-py/src/parsing/functions/predicate_function.py +0 -47
  107. package/flowquery-py/src/parsing/functions/predicate_sum.py +0 -49
  108. package/flowquery-py/src/parsing/functions/properties.py +0 -50
  109. package/flowquery-py/src/parsing/functions/rand.py +0 -28
  110. package/flowquery-py/src/parsing/functions/range_.py +0 -41
  111. package/flowquery-py/src/parsing/functions/reducer_element.py +0 -15
  112. package/flowquery-py/src/parsing/functions/relationships.py +0 -46
  113. package/flowquery-py/src/parsing/functions/replace.py +0 -39
  114. package/flowquery-py/src/parsing/functions/round_.py +0 -34
  115. package/flowquery-py/src/parsing/functions/schema.py +0 -40
  116. package/flowquery-py/src/parsing/functions/size.py +0 -34
  117. package/flowquery-py/src/parsing/functions/split.py +0 -54
  118. package/flowquery-py/src/parsing/functions/string_distance.py +0 -92
  119. package/flowquery-py/src/parsing/functions/stringify.py +0 -49
  120. package/flowquery-py/src/parsing/functions/substring.py +0 -76
  121. package/flowquery-py/src/parsing/functions/sum.py +0 -51
  122. package/flowquery-py/src/parsing/functions/tail.py +0 -37
  123. package/flowquery-py/src/parsing/functions/temporal_utils.py +0 -186
  124. package/flowquery-py/src/parsing/functions/time_.py +0 -57
  125. package/flowquery-py/src/parsing/functions/timestamp.py +0 -37
  126. package/flowquery-py/src/parsing/functions/to_float.py +0 -46
  127. package/flowquery-py/src/parsing/functions/to_integer.py +0 -46
  128. package/flowquery-py/src/parsing/functions/to_json.py +0 -35
  129. package/flowquery-py/src/parsing/functions/to_lower.py +0 -37
  130. package/flowquery-py/src/parsing/functions/to_string.py +0 -41
  131. package/flowquery-py/src/parsing/functions/trim.py +0 -37
  132. package/flowquery-py/src/parsing/functions/type_.py +0 -47
  133. package/flowquery-py/src/parsing/functions/value_holder.py +0 -24
  134. package/flowquery-py/src/parsing/logic/__init__.py +0 -15
  135. package/flowquery-py/src/parsing/logic/case.py +0 -28
  136. package/flowquery-py/src/parsing/logic/else_.py +0 -12
  137. package/flowquery-py/src/parsing/logic/end.py +0 -8
  138. package/flowquery-py/src/parsing/logic/then.py +0 -12
  139. package/flowquery-py/src/parsing/logic/when.py +0 -12
  140. package/flowquery-py/src/parsing/operations/__init__.py +0 -46
  141. package/flowquery-py/src/parsing/operations/aggregated_return.py +0 -25
  142. package/flowquery-py/src/parsing/operations/aggregated_with.py +0 -22
  143. package/flowquery-py/src/parsing/operations/call.py +0 -73
  144. package/flowquery-py/src/parsing/operations/create_node.py +0 -35
  145. package/flowquery-py/src/parsing/operations/create_relationship.py +0 -35
  146. package/flowquery-py/src/parsing/operations/delete_node.py +0 -29
  147. package/flowquery-py/src/parsing/operations/delete_relationship.py +0 -29
  148. package/flowquery-py/src/parsing/operations/group_by.py +0 -148
  149. package/flowquery-py/src/parsing/operations/limit.py +0 -33
  150. package/flowquery-py/src/parsing/operations/load.py +0 -148
  151. package/flowquery-py/src/parsing/operations/match.py +0 -52
  152. package/flowquery-py/src/parsing/operations/operation.py +0 -69
  153. package/flowquery-py/src/parsing/operations/order_by.py +0 -114
  154. package/flowquery-py/src/parsing/operations/projection.py +0 -21
  155. package/flowquery-py/src/parsing/operations/return_op.py +0 -88
  156. package/flowquery-py/src/parsing/operations/union.py +0 -115
  157. package/flowquery-py/src/parsing/operations/union_all.py +0 -17
  158. package/flowquery-py/src/parsing/operations/unwind.py +0 -42
  159. package/flowquery-py/src/parsing/operations/where.py +0 -43
  160. package/flowquery-py/src/parsing/operations/with_op.py +0 -18
  161. package/flowquery-py/src/parsing/parser.py +0 -1384
  162. package/flowquery-py/src/parsing/parser_state.py +0 -26
  163. package/flowquery-py/src/parsing/token_to_node.py +0 -109
  164. package/flowquery-py/src/tokenization/__init__.py +0 -23
  165. package/flowquery-py/src/tokenization/keyword.py +0 -54
  166. package/flowquery-py/src/tokenization/operator.py +0 -29
  167. package/flowquery-py/src/tokenization/string_walker.py +0 -158
  168. package/flowquery-py/src/tokenization/symbol.py +0 -19
  169. package/flowquery-py/src/tokenization/token.py +0 -693
  170. package/flowquery-py/src/tokenization/token_mapper.py +0 -53
  171. package/flowquery-py/src/tokenization/token_type.py +0 -21
  172. package/flowquery-py/src/tokenization/tokenizer.py +0 -214
  173. package/flowquery-py/src/tokenization/trie.py +0 -125
  174. package/flowquery-py/src/utils/__init__.py +0 -6
  175. package/flowquery-py/src/utils/object_utils.py +0 -20
  176. package/flowquery-py/src/utils/string_utils.py +0 -113
  177. package/flowquery-py/tests/__init__.py +0 -1
  178. package/flowquery-py/tests/compute/__init__.py +0 -1
  179. package/flowquery-py/tests/compute/test_runner.py +0 -4902
  180. package/flowquery-py/tests/graph/__init__.py +0 -1
  181. package/flowquery-py/tests/graph/test_create.py +0 -56
  182. package/flowquery-py/tests/graph/test_data.py +0 -73
  183. package/flowquery-py/tests/graph/test_match.py +0 -40
  184. package/flowquery-py/tests/parsing/__init__.py +0 -1
  185. package/flowquery-py/tests/parsing/test_context.py +0 -34
  186. package/flowquery-py/tests/parsing/test_expression.py +0 -248
  187. package/flowquery-py/tests/parsing/test_parser.py +0 -1237
  188. package/flowquery-py/tests/test_extensibility.py +0 -611
  189. package/flowquery-py/tests/tokenization/__init__.py +0 -1
  190. package/flowquery-py/tests/tokenization/test_token_mapper.py +0 -60
  191. package/flowquery-py/tests/tokenization/test_tokenizer.py +0 -198
  192. package/flowquery-py/tests/tokenization/test_trie.py +0 -30
  193. package/flowquery-vscode/.vscode-test.mjs +0 -5
  194. package/flowquery-vscode/.vscodeignore +0 -13
  195. package/flowquery-vscode/LICENSE +0 -21
  196. package/flowquery-vscode/README.md +0 -11
  197. package/flowquery-vscode/demo/FlowQueryVSCodeDemo.gif +0 -0
  198. package/flowquery-vscode/eslint.config.mjs +0 -25
  199. package/flowquery-vscode/extension.js +0 -508
  200. package/flowquery-vscode/flowQueryEngine/flowquery.min.js +0 -1
  201. package/flowquery-vscode/flowquery-worker.js +0 -66
  202. package/flowquery-vscode/images/FlowQueryLogoIcon.png +0 -0
  203. package/flowquery-vscode/jsconfig.json +0 -13
  204. package/flowquery-vscode/libs/page.css +0 -53
  205. package/flowquery-vscode/libs/table.css +0 -13
  206. package/flowquery-vscode/libs/tabs.css +0 -66
  207. package/flowquery-vscode/package-lock.json +0 -2917
  208. package/flowquery-vscode/package.json +0 -51
  209. package/flowquery-vscode/test/extension.test.js +0 -196
  210. package/flowquery-vscode/test/worker.test.js +0 -25
  211. package/flowquery-vscode/vsc-extension-quickstart.md +0 -42
  212. package/jest.config.js +0 -14
  213. package/misc/apps/RAG/README.md +0 -29
  214. package/misc/apps/RAG/data/chats.json +0 -302
  215. package/misc/apps/RAG/data/emails.json +0 -182
  216. package/misc/apps/RAG/data/events.json +0 -226
  217. package/misc/apps/RAG/data/files.json +0 -172
  218. package/misc/apps/RAG/data/users.json +0 -158
  219. package/misc/apps/RAG/jest.config.js +0 -21
  220. package/misc/apps/RAG/package.json +0 -48
  221. package/misc/apps/RAG/public/index.html +0 -18
  222. package/misc/apps/RAG/src/App.css +0 -42
  223. package/misc/apps/RAG/src/App.tsx +0 -50
  224. package/misc/apps/RAG/src/components/AdaptiveCardRenderer.css +0 -172
  225. package/misc/apps/RAG/src/components/AdaptiveCardRenderer.tsx +0 -380
  226. package/misc/apps/RAG/src/components/ApiKeySettings.tsx +0 -245
  227. package/misc/apps/RAG/src/components/ChatContainer.css +0 -67
  228. package/misc/apps/RAG/src/components/ChatContainer.tsx +0 -242
  229. package/misc/apps/RAG/src/components/ChatInput.css +0 -23
  230. package/misc/apps/RAG/src/components/ChatInput.tsx +0 -76
  231. package/misc/apps/RAG/src/components/ChatMessage.css +0 -160
  232. package/misc/apps/RAG/src/components/ChatMessage.tsx +0 -286
  233. package/misc/apps/RAG/src/components/FlowQueryAgent.ts +0 -708
  234. package/misc/apps/RAG/src/components/FlowQueryRunner.css +0 -113
  235. package/misc/apps/RAG/src/components/FlowQueryRunner.tsx +0 -371
  236. package/misc/apps/RAG/src/components/index.ts +0 -28
  237. package/misc/apps/RAG/src/graph/index.ts +0 -19
  238. package/misc/apps/RAG/src/graph/initializeGraph.ts +0 -254
  239. package/misc/apps/RAG/src/index.tsx +0 -29
  240. package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +0 -327
  241. package/misc/apps/RAG/src/prompts/index.ts +0 -10
  242. package/misc/apps/RAG/src/tests/graph.test.ts +0 -35
  243. package/misc/apps/RAG/src/utils/FlowQueryExecutor.ts +0 -130
  244. package/misc/apps/RAG/src/utils/FlowQueryExtractor.ts +0 -208
  245. package/misc/apps/RAG/src/utils/Llm.ts +0 -248
  246. package/misc/apps/RAG/src/utils/index.ts +0 -12
  247. package/misc/apps/RAG/tsconfig.json +0 -22
  248. package/misc/apps/RAG/webpack.config.js +0 -43
  249. package/misc/apps/README.md +0 -1
  250. package/misc/queries/analyze_catfacts.cql +0 -75
  251. package/misc/queries/azure_openai_completions.cql +0 -13
  252. package/misc/queries/azure_openai_models.cql +0 -9
  253. package/misc/queries/mock_pipeline.cql +0 -84
  254. package/misc/queries/openai_completions.cql +0 -15
  255. package/misc/queries/openai_models.cql +0 -13
  256. package/misc/queries/test.cql +0 -6
  257. package/misc/queries/tool_inference.cql +0 -24
  258. package/misc/queries/wisdom.cql +0 -6
  259. package/misc/queries/wisdom_letter_histogram.cql +0 -8
  260. package/src/compute/flowquery.ts +0 -46
  261. package/src/compute/runner.ts +0 -66
  262. package/src/extensibility.ts +0 -45
  263. package/src/graph/data.ts +0 -130
  264. package/src/graph/database.ts +0 -143
  265. package/src/graph/hops.ts +0 -22
  266. package/src/graph/node.ts +0 -122
  267. package/src/graph/node_data.ts +0 -18
  268. package/src/graph/node_reference.ts +0 -38
  269. package/src/graph/pattern.ts +0 -110
  270. package/src/graph/pattern_expression.ts +0 -48
  271. package/src/graph/patterns.ts +0 -36
  272. package/src/graph/physical_node.ts +0 -23
  273. package/src/graph/physical_relationship.ts +0 -23
  274. package/src/graph/relationship.ts +0 -167
  275. package/src/graph/relationship_data.ts +0 -31
  276. package/src/graph/relationship_match_collector.ts +0 -64
  277. package/src/graph/relationship_reference.ts +0 -25
  278. package/src/index.browser.ts +0 -46
  279. package/src/index.node.ts +0 -55
  280. package/src/index.ts +0 -12
  281. package/src/io/command_line.ts +0 -74
  282. package/src/parsing/alias.ts +0 -23
  283. package/src/parsing/alias_option.ts +0 -5
  284. package/src/parsing/ast_node.ts +0 -153
  285. package/src/parsing/base_parser.ts +0 -98
  286. package/src/parsing/components/csv.ts +0 -9
  287. package/src/parsing/components/from.ts +0 -12
  288. package/src/parsing/components/headers.ts +0 -12
  289. package/src/parsing/components/json.ts +0 -9
  290. package/src/parsing/components/null.ts +0 -9
  291. package/src/parsing/components/post.ts +0 -9
  292. package/src/parsing/components/text.ts +0 -9
  293. package/src/parsing/context.ts +0 -54
  294. package/src/parsing/data_structures/associative_array.ts +0 -43
  295. package/src/parsing/data_structures/json_array.ts +0 -31
  296. package/src/parsing/data_structures/key_value_pair.ts +0 -37
  297. package/src/parsing/data_structures/lookup.ts +0 -44
  298. package/src/parsing/data_structures/range_lookup.ts +0 -36
  299. package/src/parsing/expressions/boolean.ts +0 -21
  300. package/src/parsing/expressions/expression.ts +0 -150
  301. package/src/parsing/expressions/expression_map.ts +0 -22
  302. package/src/parsing/expressions/f_string.ts +0 -26
  303. package/src/parsing/expressions/identifier.ts +0 -22
  304. package/src/parsing/expressions/number.ts +0 -40
  305. package/src/parsing/expressions/operator.ts +0 -354
  306. package/src/parsing/expressions/reference.ts +0 -45
  307. package/src/parsing/expressions/string.ts +0 -34
  308. package/src/parsing/functions/aggregate_function.ts +0 -58
  309. package/src/parsing/functions/async_function.ts +0 -64
  310. package/src/parsing/functions/avg.ts +0 -47
  311. package/src/parsing/functions/coalesce.ts +0 -49
  312. package/src/parsing/functions/collect.ts +0 -54
  313. package/src/parsing/functions/count.ts +0 -54
  314. package/src/parsing/functions/date.ts +0 -63
  315. package/src/parsing/functions/datetime.ts +0 -63
  316. package/src/parsing/functions/duration.ts +0 -143
  317. package/src/parsing/functions/element_id.ts +0 -51
  318. package/src/parsing/functions/function.ts +0 -60
  319. package/src/parsing/functions/function_factory.ts +0 -195
  320. package/src/parsing/functions/function_metadata.ts +0 -217
  321. package/src/parsing/functions/functions.ts +0 -70
  322. package/src/parsing/functions/head.ts +0 -42
  323. package/src/parsing/functions/id.ts +0 -51
  324. package/src/parsing/functions/join.ts +0 -40
  325. package/src/parsing/functions/keys.ts +0 -29
  326. package/src/parsing/functions/last.ts +0 -42
  327. package/src/parsing/functions/localdatetime.ts +0 -63
  328. package/src/parsing/functions/localtime.ts +0 -58
  329. package/src/parsing/functions/max.ts +0 -37
  330. package/src/parsing/functions/min.ts +0 -37
  331. package/src/parsing/functions/nodes.ts +0 -54
  332. package/src/parsing/functions/predicate_function.ts +0 -48
  333. package/src/parsing/functions/predicate_sum.ts +0 -47
  334. package/src/parsing/functions/properties.ts +0 -56
  335. package/src/parsing/functions/rand.ts +0 -21
  336. package/src/parsing/functions/range.ts +0 -37
  337. package/src/parsing/functions/reducer_element.ts +0 -10
  338. package/src/parsing/functions/relationships.ts +0 -52
  339. package/src/parsing/functions/replace.ts +0 -38
  340. package/src/parsing/functions/round.ts +0 -28
  341. package/src/parsing/functions/schema.ts +0 -39
  342. package/src/parsing/functions/size.ts +0 -28
  343. package/src/parsing/functions/split.ts +0 -45
  344. package/src/parsing/functions/string_distance.ts +0 -83
  345. package/src/parsing/functions/stringify.ts +0 -37
  346. package/src/parsing/functions/substring.ts +0 -68
  347. package/src/parsing/functions/sum.ts +0 -41
  348. package/src/parsing/functions/tail.ts +0 -39
  349. package/src/parsing/functions/temporal_utils.ts +0 -180
  350. package/src/parsing/functions/time.ts +0 -58
  351. package/src/parsing/functions/timestamp.ts +0 -37
  352. package/src/parsing/functions/to_float.ts +0 -50
  353. package/src/parsing/functions/to_integer.ts +0 -50
  354. package/src/parsing/functions/to_json.ts +0 -28
  355. package/src/parsing/functions/to_lower.ts +0 -28
  356. package/src/parsing/functions/to_string.ts +0 -32
  357. package/src/parsing/functions/trim.ts +0 -28
  358. package/src/parsing/functions/type.ts +0 -39
  359. package/src/parsing/functions/value_holder.ts +0 -13
  360. package/src/parsing/logic/case.ts +0 -26
  361. package/src/parsing/logic/else.ts +0 -12
  362. package/src/parsing/logic/end.ts +0 -9
  363. package/src/parsing/logic/then.ts +0 -12
  364. package/src/parsing/logic/when.ts +0 -12
  365. package/src/parsing/operations/aggregated_return.ts +0 -22
  366. package/src/parsing/operations/aggregated_with.ts +0 -18
  367. package/src/parsing/operations/call.ts +0 -69
  368. package/src/parsing/operations/create_node.ts +0 -39
  369. package/src/parsing/operations/create_relationship.ts +0 -38
  370. package/src/parsing/operations/delete_node.ts +0 -33
  371. package/src/parsing/operations/delete_relationship.ts +0 -32
  372. package/src/parsing/operations/group_by.ts +0 -137
  373. package/src/parsing/operations/limit.ts +0 -31
  374. package/src/parsing/operations/load.ts +0 -146
  375. package/src/parsing/operations/match.ts +0 -54
  376. package/src/parsing/operations/operation.ts +0 -69
  377. package/src/parsing/operations/order_by.ts +0 -126
  378. package/src/parsing/operations/projection.ts +0 -18
  379. package/src/parsing/operations/return.ts +0 -76
  380. package/src/parsing/operations/union.ts +0 -114
  381. package/src/parsing/operations/union_all.ts +0 -16
  382. package/src/parsing/operations/unwind.ts +0 -36
  383. package/src/parsing/operations/where.ts +0 -42
  384. package/src/parsing/operations/with.ts +0 -20
  385. package/src/parsing/parser.ts +0 -1641
  386. package/src/parsing/parser_state.ts +0 -25
  387. package/src/parsing/token_to_node.ts +0 -114
  388. package/src/tokenization/keyword.ts +0 -50
  389. package/src/tokenization/operator.ts +0 -25
  390. package/src/tokenization/string_walker.ts +0 -197
  391. package/src/tokenization/symbol.ts +0 -15
  392. package/src/tokenization/token.ts +0 -764
  393. package/src/tokenization/token_mapper.ts +0 -53
  394. package/src/tokenization/token_type.ts +0 -16
  395. package/src/tokenization/tokenizer.ts +0 -250
  396. package/src/tokenization/trie.ts +0 -117
  397. package/src/utils/object_utils.ts +0 -17
  398. package/src/utils/string_utils.ts +0 -114
  399. package/tests/compute/runner.test.ts +0 -4559
  400. package/tests/extensibility.test.ts +0 -643
  401. package/tests/graph/create.test.ts +0 -36
  402. package/tests/graph/data.test.ts +0 -58
  403. package/tests/graph/match.test.ts +0 -29
  404. package/tests/parsing/context.test.ts +0 -27
  405. package/tests/parsing/expression.test.ts +0 -303
  406. package/tests/parsing/parser.test.ts +0 -1327
  407. package/tests/tokenization/token_mapper.test.ts +0 -47
  408. package/tests/tokenization/tokenizer.test.ts +0 -191
  409. package/tests/tokenization/trie.test.ts +0 -20
  410. package/tsconfig.json +0 -19
  411. package/typedoc.json +0 -16
  412. package/vscode-settings.json.recommended +0 -16
  413. 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
- });