flowquery 1.0.14 → 1.0.16
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.
- package/.editorconfig +21 -0
- package/.husky/pre-commit +1 -0
- package/.prettierrc +22 -0
- package/dist/flowquery.min.js +1 -1
- package/dist/parsing/expressions/expression_map.d.ts +9 -0
- package/dist/parsing/expressions/expression_map.d.ts.map +1 -0
- package/dist/parsing/expressions/expression_map.js +24 -0
- package/dist/parsing/expressions/expression_map.js.map +1 -0
- package/dist/parsing/operations/call.d.ts +17 -0
- package/dist/parsing/operations/call.d.ts.map +1 -0
- package/dist/parsing/operations/call.js +105 -0
- package/dist/parsing/operations/call.js.map +1 -0
- package/dist/parsing/operations/load.d.ts +6 -6
- package/dist/parsing/operations/load.d.ts.map +1 -1
- package/dist/parsing/operations/load.js +8 -6
- package/dist/parsing/operations/load.js.map +1 -1
- package/dist/parsing/operations/operation.d.ts +1 -0
- package/dist/parsing/operations/operation.d.ts.map +1 -1
- package/dist/parsing/operations/operation.js +6 -5
- package/dist/parsing/operations/operation.js.map +1 -1
- package/dist/parsing/operations/projection.d.ts +1 -1
- package/dist/parsing/operations/projection.d.ts.map +1 -1
- package/dist/parsing/operations/projection.js.map +1 -1
- package/dist/parsing/parser.d.ts +1 -0
- package/dist/parsing/parser.d.ts.map +1 -1
- package/dist/parsing/parser.js +148 -99
- package/dist/parsing/parser.js.map +1 -1
- package/dist/parsing/token_to_node.d.ts +2 -2
- package/dist/parsing/token_to_node.d.ts.map +1 -1
- package/dist/parsing/token_to_node.js +12 -12
- package/dist/parsing/token_to_node.js.map +1 -1
- package/dist/tokenization/token.d.ts +5 -1
- package/dist/tokenization/token.d.ts.map +1 -1
- package/dist/tokenization/token.js +17 -5
- package/dist/tokenization/token.js.map +1 -1
- package/docs/flowquery.min.js +1 -1
- package/flowquery-vscode/flowQueryEngine/flowquery.min.js +1 -1
- package/misc/apps/RAG/package.json +1 -1
- package/misc/apps/RAG/src/plugins/loaders/CatFacts.ts +21 -26
- package/misc/apps/RAG/src/plugins/loaders/FetchJson.ts +65 -0
- package/misc/apps/RAG/src/plugins/loaders/Form.ts +163 -147
- package/misc/apps/RAG/src/plugins/loaders/Llm.ts +106 -92
- package/misc/apps/RAG/src/plugins/loaders/MockData.ts +80 -58
- package/misc/apps/RAG/src/plugins/loaders/Table.ts +106 -103
- package/misc/apps/RAG/src/plugins/loaders/Weather.ts +50 -38
- package/misc/apps/RAG/src/prompts/FlowQuerySystemPrompt.ts +77 -78
- package/package.json +12 -2
- package/src/parsing/expressions/expression_map.ts +22 -0
- package/src/parsing/operations/call.ts +69 -0
- package/src/parsing/operations/load.ts +123 -120
- package/src/parsing/operations/operation.ts +14 -13
- package/src/parsing/operations/projection.ts +3 -3
- package/src/parsing/parser.ts +303 -239
- package/src/parsing/token_to_node.ts +67 -50
- package/src/tokenization/token.ts +29 -14
- package/tests/compute/runner.test.ts +277 -165
- package/tests/parsing/parser.test.ts +352 -303
- package/tests/tokenization/tokenizer.test.ts +17 -17
- package/vscode-settings.json.recommended +16 -0
|
@@ -1,434 +1,483 @@
|
|
|
1
|
+
import AsyncFunction from "../../src/parsing/functions/async_function";
|
|
2
|
+
import { FunctionDef } from "../../src/parsing/functions/function_metadata";
|
|
1
3
|
import Parser from "../../src/parsing/parser";
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
// Test class for CALL operation parsing test - defined at module level for Prettier compatibility
|
|
6
|
+
@FunctionDef({
|
|
7
|
+
description: "Asynchronous function for testing CALL operation",
|
|
8
|
+
category: "async",
|
|
9
|
+
parameters: [],
|
|
10
|
+
output: { description: "Yields test values", type: "any" },
|
|
11
|
+
})
|
|
12
|
+
class Test extends AsyncFunction {
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
this._expectedParameterCount = 0;
|
|
16
|
+
}
|
|
17
|
+
public async *generate(): AsyncGenerator<any> {
|
|
18
|
+
yield 1;
|
|
19
|
+
yield 2;
|
|
20
|
+
yield 3;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
test("Test Parser", () => {
|
|
4
25
|
const parser = new Parser();
|
|
5
|
-
const ast = parser.parse(
|
|
26
|
+
const ast = parser.parse("RETURN 1, 2, 3");
|
|
6
27
|
expect(ast.print()).toBe(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
28
|
+
"ASTNode\n" +
|
|
29
|
+
"- Return\n" +
|
|
30
|
+
"-- Expression\n" +
|
|
31
|
+
"--- Number (1)\n" +
|
|
32
|
+
"-- Expression\n" +
|
|
33
|
+
"--- Number (2)\n" +
|
|
34
|
+
"-- Expression\n" +
|
|
35
|
+
"--- Number (3)"
|
|
15
36
|
);
|
|
16
37
|
});
|
|
17
38
|
|
|
18
|
-
test(
|
|
39
|
+
test("Test Parser with function", () => {
|
|
19
40
|
const parser = new Parser();
|
|
20
|
-
const ast = parser.parse(
|
|
41
|
+
const ast = parser.parse("RETURN rand()");
|
|
21
42
|
expect(ast.print()).toBe(
|
|
22
|
-
|
|
23
|
-
'- Return\n' +
|
|
24
|
-
'-- Expression\n' +
|
|
25
|
-
'--- Function (rand)'
|
|
43
|
+
"ASTNode\n" + "- Return\n" + "-- Expression\n" + "--- Function (rand)"
|
|
26
44
|
);
|
|
27
45
|
});
|
|
28
46
|
|
|
29
|
-
test(
|
|
47
|
+
test("Test Parser with associative array", () => {
|
|
30
48
|
const parser = new Parser();
|
|
31
|
-
const ast = parser.parse(
|
|
49
|
+
const ast = parser.parse("RETURN {a: 1, b: 2}");
|
|
32
50
|
expect(ast.print()).toBe(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
"ASTNode\n" +
|
|
52
|
+
"- Return\n" +
|
|
53
|
+
"-- Expression\n" +
|
|
54
|
+
"--- AssociativeArray\n" +
|
|
55
|
+
"---- KeyValuePair\n" +
|
|
56
|
+
"----- String (a)\n" +
|
|
57
|
+
"----- Expression\n" +
|
|
58
|
+
"------ Number (1)\n" +
|
|
59
|
+
"---- KeyValuePair\n" +
|
|
60
|
+
"----- String (b)\n" +
|
|
61
|
+
"----- Expression\n" +
|
|
62
|
+
"------ Number (2)"
|
|
45
63
|
);
|
|
46
64
|
});
|
|
47
65
|
|
|
48
|
-
test(
|
|
66
|
+
test("Test Parser with JSON array", () => {
|
|
49
67
|
const parser = new Parser();
|
|
50
|
-
const ast = parser.parse(
|
|
68
|
+
const ast = parser.parse("RETURN [1, 2]");
|
|
51
69
|
expect(ast.print()).toBe(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
"ASTNode\n" +
|
|
71
|
+
"- Return\n" +
|
|
72
|
+
"-- Expression\n" +
|
|
73
|
+
"--- JSONArray\n" +
|
|
74
|
+
"---- Expression\n" +
|
|
75
|
+
"----- Number (1)\n" +
|
|
76
|
+
"---- Expression\n" +
|
|
77
|
+
"----- Number (2)"
|
|
60
78
|
);
|
|
61
79
|
});
|
|
62
80
|
|
|
63
|
-
test(
|
|
81
|
+
test("Test Parser with nested associative array", () => {
|
|
64
82
|
const parser = new Parser();
|
|
65
|
-
const ast = parser.parse(
|
|
83
|
+
const ast = parser.parse("RETURN {a:{}}");
|
|
66
84
|
expect(ast.print()).toBe(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
85
|
+
"ASTNode\n" +
|
|
86
|
+
"- Return\n" +
|
|
87
|
+
"-- Expression\n" +
|
|
88
|
+
"--- AssociativeArray\n" +
|
|
89
|
+
"---- KeyValuePair\n" +
|
|
90
|
+
"----- String (a)\n" +
|
|
91
|
+
"----- Expression\n" +
|
|
92
|
+
"------ AssociativeArray"
|
|
75
93
|
);
|
|
76
94
|
});
|
|
77
95
|
|
|
78
|
-
test(
|
|
96
|
+
test("Test Parser with multiple operations", () => {
|
|
79
97
|
const parser = new Parser();
|
|
80
|
-
const ast = parser.parse(
|
|
98
|
+
const ast = parser.parse("WITH 1 AS n RETURN n");
|
|
81
99
|
expect(ast.print()).toBe(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
100
|
+
"ASTNode\n" +
|
|
101
|
+
"- With\n" +
|
|
102
|
+
"-- Expression (n)\n" +
|
|
103
|
+
"--- Number (1)\n" +
|
|
104
|
+
"- Return\n" +
|
|
105
|
+
"-- Expression (n)\n" +
|
|
106
|
+
"--- Reference (n)"
|
|
89
107
|
);
|
|
90
108
|
});
|
|
91
109
|
|
|
92
|
-
test(
|
|
110
|
+
test("Test Parser with multiple operations and comments", () => {
|
|
93
111
|
const parser = new Parser();
|
|
94
|
-
const ast = parser.parse(
|
|
112
|
+
const ast = parser.parse("WITH 1 AS n /* comment */ RETURN n");
|
|
95
113
|
expect(ast.print()).toBe(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
114
|
+
"ASTNode\n" +
|
|
115
|
+
"- With\n" +
|
|
116
|
+
"-- Expression (n)\n" +
|
|
117
|
+
"--- Number (1)\n" +
|
|
118
|
+
"- Return\n" +
|
|
119
|
+
"-- Expression (n)\n" +
|
|
120
|
+
"--- Reference (n)"
|
|
103
121
|
);
|
|
104
122
|
});
|
|
105
123
|
|
|
106
|
-
test(
|
|
124
|
+
test("Test Parser with multiple operations including UNWIND", () => {
|
|
107
125
|
const parser = new Parser();
|
|
108
|
-
const ast = parser.parse(
|
|
126
|
+
const ast = parser.parse("UNWIND [1, 2, 3] AS n RETURN n");
|
|
109
127
|
expect(ast.print()).toBe(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
128
|
+
"ASTNode\n" +
|
|
129
|
+
"- Unwind\n" +
|
|
130
|
+
"-- Expression (n)\n" +
|
|
131
|
+
"--- JSONArray\n" +
|
|
132
|
+
"---- Expression\n" +
|
|
133
|
+
"----- Number (1)\n" +
|
|
134
|
+
"---- Expression\n" +
|
|
135
|
+
"----- Number (2)\n" +
|
|
136
|
+
"---- Expression\n" +
|
|
137
|
+
"----- Number (3)\n" +
|
|
138
|
+
"- Return\n" +
|
|
139
|
+
"-- Expression (n)\n" +
|
|
140
|
+
"--- Reference (n)"
|
|
123
141
|
);
|
|
124
142
|
});
|
|
125
143
|
|
|
126
|
-
test(
|
|
144
|
+
test("Test Unwind with invalid expression", () => {
|
|
127
145
|
const parser = new Parser();
|
|
128
|
-
expect(() => parser.parse(
|
|
146
|
+
expect(() => parser.parse("UNWIND 1 AS n RETURN n")).toThrow(
|
|
147
|
+
"Expected array, function, reference, or lookup."
|
|
148
|
+
);
|
|
129
149
|
});
|
|
130
150
|
|
|
131
|
-
test(
|
|
151
|
+
test("Test Unwind with invalid alias", () => {
|
|
132
152
|
const parser = new Parser();
|
|
133
|
-
expect(() => parser.parse(
|
|
153
|
+
expect(() => parser.parse("UNWIND [1, 2, 3] AS 1 RETURN n")).toThrow("Expected identifier");
|
|
134
154
|
});
|
|
135
155
|
|
|
136
|
-
test(
|
|
156
|
+
test("Test Unwind with missing alias", () => {
|
|
137
157
|
const parser = new Parser();
|
|
138
|
-
expect(() => parser.parse(
|
|
158
|
+
expect(() => parser.parse("UNWIND [1, 2, 3] RETURN n")).toThrow("Expected alias");
|
|
139
159
|
});
|
|
140
160
|
|
|
141
|
-
test(
|
|
161
|
+
test("Test statement with where clause", () => {
|
|
142
162
|
const parser = new Parser();
|
|
143
|
-
const ast = parser.parse(
|
|
163
|
+
const ast = parser.parse("with 1 as n where n > 0 return n");
|
|
144
164
|
expect(ast.print()).toBe(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
165
|
+
"ASTNode\n" +
|
|
166
|
+
"- With\n" +
|
|
167
|
+
"-- Expression (n)\n" +
|
|
168
|
+
"--- Number (1)\n" +
|
|
169
|
+
"- Where\n" +
|
|
170
|
+
"-- Expression\n" +
|
|
171
|
+
"--- GreaterThan\n" +
|
|
172
|
+
"---- Reference (n)\n" +
|
|
173
|
+
"---- Number (0)\n" +
|
|
174
|
+
"- Return\n" +
|
|
175
|
+
"-- Expression (n)\n" +
|
|
176
|
+
"--- Reference (n)"
|
|
157
177
|
);
|
|
158
178
|
});
|
|
159
179
|
|
|
160
|
-
test(
|
|
180
|
+
test("Test lookup", () => {
|
|
161
181
|
const parser = new Parser();
|
|
162
|
-
const ast = parser.parse(
|
|
182
|
+
const ast = parser.parse("return {a: 1}.a");
|
|
163
183
|
expect(ast.print()).toBe(
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
184
|
+
"ASTNode\n" +
|
|
185
|
+
"- Return\n" +
|
|
186
|
+
"-- Expression\n" +
|
|
187
|
+
"--- Lookup\n" +
|
|
188
|
+
"---- Identifier (a)\n" +
|
|
189
|
+
"---- AssociativeArray\n" +
|
|
190
|
+
"----- KeyValuePair\n" +
|
|
191
|
+
"------ String (a)\n" +
|
|
192
|
+
"------ Expression\n" +
|
|
193
|
+
"------- Number (1)"
|
|
174
194
|
);
|
|
175
195
|
});
|
|
176
196
|
|
|
177
|
-
test(
|
|
197
|
+
test("Test lookup as part of expression", () => {
|
|
178
198
|
const parser = new Parser();
|
|
179
|
-
const ast = parser.parse(
|
|
199
|
+
const ast = parser.parse("return {a: 1}.a + 1");
|
|
180
200
|
expect(ast.print()).toBe(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
201
|
+
"ASTNode\n" +
|
|
202
|
+
"- Return\n" +
|
|
203
|
+
"-- Expression\n" +
|
|
204
|
+
"--- Add\n" +
|
|
205
|
+
"---- Lookup\n" +
|
|
206
|
+
"----- Identifier (a)\n" +
|
|
207
|
+
"----- AssociativeArray\n" +
|
|
208
|
+
"------ KeyValuePair\n" +
|
|
209
|
+
"------- String (a)\n" +
|
|
210
|
+
"------- Expression\n" +
|
|
211
|
+
"-------- Number (1)\n" +
|
|
212
|
+
"---- Number (1)"
|
|
193
213
|
);
|
|
194
214
|
});
|
|
195
215
|
|
|
196
|
-
test(
|
|
216
|
+
test("Test lookup with nested associative array", () => {
|
|
197
217
|
const parser = new Parser();
|
|
198
|
-
const ast = parser.parse(
|
|
218
|
+
const ast = parser.parse("return {a: {b: 1}}.a.b");
|
|
199
219
|
const _return = ast.firstChild();
|
|
200
220
|
expect(ast.print()).toBe(
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
221
|
+
"ASTNode\n" +
|
|
222
|
+
"- Return\n" +
|
|
223
|
+
"-- Expression\n" +
|
|
224
|
+
"--- Lookup\n" +
|
|
225
|
+
"---- Identifier (b)\n" +
|
|
226
|
+
"---- Lookup\n" +
|
|
227
|
+
"----- Identifier (a)\n" +
|
|
228
|
+
"----- AssociativeArray\n" +
|
|
229
|
+
"------ KeyValuePair\n" +
|
|
230
|
+
"------- String (a)\n" +
|
|
231
|
+
"------- Expression\n" +
|
|
232
|
+
"-------- AssociativeArray\n" +
|
|
233
|
+
"--------- KeyValuePair\n" +
|
|
234
|
+
"---------- String (b)\n" +
|
|
235
|
+
"---------- Expression\n" +
|
|
236
|
+
"----------- Number (1)"
|
|
217
237
|
);
|
|
218
238
|
expect(_return.firstChild().value()).toBe(1);
|
|
219
239
|
});
|
|
220
240
|
|
|
221
|
-
test(
|
|
241
|
+
test("Test lookup with JSON array", () => {
|
|
222
242
|
const parser = new Parser();
|
|
223
|
-
const ast = parser.parse(
|
|
243
|
+
const ast = parser.parse("return [1, 2][1]");
|
|
224
244
|
const _return = ast.firstChild();
|
|
225
245
|
expect(ast.print()).toBe(
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
246
|
+
"ASTNode\n" +
|
|
247
|
+
"- Return\n" +
|
|
248
|
+
"-- Expression\n" +
|
|
249
|
+
"--- Lookup\n" +
|
|
250
|
+
"---- Expression\n" +
|
|
251
|
+
"----- Number (1)\n" +
|
|
252
|
+
"---- JSONArray\n" +
|
|
253
|
+
"----- Expression\n" +
|
|
254
|
+
"------ Number (1)\n" +
|
|
255
|
+
"----- Expression\n" +
|
|
256
|
+
"------ Number (2)"
|
|
237
257
|
);
|
|
238
258
|
expect(_return.firstChild().value()).toBe(2);
|
|
239
259
|
});
|
|
240
260
|
|
|
241
|
-
test(
|
|
261
|
+
test("Test load with post", () => {
|
|
242
262
|
const parser = new Parser();
|
|
243
|
-
const ast = parser.parse(
|
|
263
|
+
const ast = parser.parse(
|
|
264
|
+
'load json from "https://jsonplaceholder.typicode.com/posts" post {userId: 1} as data return data'
|
|
265
|
+
);
|
|
244
266
|
expect(ast.print()).toBe(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
267
|
+
"ASTNode\n" +
|
|
268
|
+
"- Load\n" +
|
|
269
|
+
"-- JSON\n" +
|
|
270
|
+
"-- From\n" +
|
|
271
|
+
"--- Expression\n" +
|
|
272
|
+
"---- String (https://jsonplaceholder.typicode.com/posts)\n" +
|
|
273
|
+
"-- Post\n" +
|
|
274
|
+
"--- Expression\n" +
|
|
275
|
+
"---- AssociativeArray\n" +
|
|
276
|
+
"----- KeyValuePair\n" +
|
|
277
|
+
"------ String (userId)\n" +
|
|
278
|
+
"------ Expression\n" +
|
|
279
|
+
"------- Number (1)\n" +
|
|
280
|
+
"-- Alias (data)\n" +
|
|
281
|
+
"- Return\n" +
|
|
282
|
+
"-- Expression (data)\n" +
|
|
283
|
+
"--- Reference (data)"
|
|
262
284
|
);
|
|
263
285
|
});
|
|
264
286
|
|
|
265
|
-
test(
|
|
287
|
+
test("Test nested aggregate functions", () => {
|
|
266
288
|
expect(() => {
|
|
267
289
|
const parser = new Parser();
|
|
268
|
-
parser.parse(
|
|
269
|
-
}).toThrow(
|
|
290
|
+
parser.parse("RETURN sum(sum(1))");
|
|
291
|
+
}).toThrow("Aggregate functions cannot be nested");
|
|
270
292
|
});
|
|
271
293
|
|
|
272
|
-
test(
|
|
294
|
+
test("Test with and return with renamed variable", () => {
|
|
273
295
|
const parser = new Parser();
|
|
274
|
-
const ast = parser.parse(
|
|
296
|
+
const ast = parser.parse("WITH 1 AS n RETURN n AS m");
|
|
275
297
|
expect(ast.print()).toBe(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
298
|
+
"ASTNode\n" +
|
|
299
|
+
"- With\n" +
|
|
300
|
+
"-- Expression (n)\n" +
|
|
301
|
+
"--- Number (1)\n" +
|
|
302
|
+
"- Return\n" +
|
|
303
|
+
"-- Expression (m)\n" +
|
|
304
|
+
"--- Reference (n)"
|
|
283
305
|
);
|
|
284
306
|
});
|
|
285
307
|
|
|
286
|
-
test(
|
|
308
|
+
test("Test with and return with variable lookup", () => {
|
|
287
309
|
const parser = new Parser();
|
|
288
|
-
const ast = parser.parse(
|
|
310
|
+
const ast = parser.parse("WITH {a: n} AS obj RETURN obj.a");
|
|
289
311
|
expect(ast.print()).toBe(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
312
|
+
"ASTNode\n" +
|
|
313
|
+
"- With\n" +
|
|
314
|
+
"-- Expression (obj)\n" +
|
|
315
|
+
"--- AssociativeArray\n" +
|
|
316
|
+
"---- KeyValuePair\n" +
|
|
317
|
+
"----- String (a)\n" +
|
|
318
|
+
"----- Expression\n" +
|
|
319
|
+
"------ Reference (n)\n" +
|
|
320
|
+
"- Return\n" +
|
|
321
|
+
"-- Expression\n" +
|
|
322
|
+
"--- Lookup\n" +
|
|
323
|
+
"---- Identifier (a)\n" +
|
|
324
|
+
"---- Reference (obj)"
|
|
303
325
|
);
|
|
304
326
|
});
|
|
305
327
|
|
|
306
|
-
test(
|
|
328
|
+
test("Test unwind", () => {
|
|
307
329
|
const parser = new Parser();
|
|
308
|
-
const ast = parser.parse(
|
|
330
|
+
const ast = parser.parse("WITH [1, 2, 4] as n unwind n as i return i");
|
|
309
331
|
expect(ast.print()).toBe(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
332
|
+
"ASTNode\n" +
|
|
333
|
+
"- With\n" +
|
|
334
|
+
"-- Expression (n)\n" +
|
|
335
|
+
"--- JSONArray\n" +
|
|
336
|
+
"---- Expression\n" +
|
|
337
|
+
"----- Number (1)\n" +
|
|
338
|
+
"---- Expression\n" +
|
|
339
|
+
"----- Number (2)\n" +
|
|
340
|
+
"---- Expression\n" +
|
|
341
|
+
"----- Number (4)\n" +
|
|
342
|
+
"- Unwind\n" +
|
|
343
|
+
"-- Expression (i)\n" +
|
|
344
|
+
"--- Reference (n)\n" +
|
|
345
|
+
"- Return\n" +
|
|
346
|
+
"-- Expression (i)\n" +
|
|
347
|
+
"--- Reference (i)"
|
|
326
348
|
);
|
|
327
349
|
});
|
|
328
350
|
|
|
329
|
-
test(
|
|
351
|
+
test("Test predicate function", () => {
|
|
330
352
|
const parser = new Parser();
|
|
331
|
-
const ast = parser.parse(
|
|
353
|
+
const ast = parser.parse("RETURN sum(n in [1, 2, 3] | n where n > 1)");
|
|
332
354
|
expect(ast.print()).toBe(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
355
|
+
"ASTNode\n" +
|
|
356
|
+
"- Return\n" +
|
|
357
|
+
"-- Expression\n" +
|
|
358
|
+
"--- PredicateFunction (sum)\n" +
|
|
359
|
+
"---- Reference (n)\n" +
|
|
360
|
+
"---- Expression\n" +
|
|
361
|
+
"----- JSONArray\n" +
|
|
362
|
+
"------ Expression\n" +
|
|
363
|
+
"------- Number (1)\n" +
|
|
364
|
+
"------ Expression\n" +
|
|
365
|
+
"------- Number (2)\n" +
|
|
366
|
+
"------ Expression\n" +
|
|
367
|
+
"------- Number (3)\n" +
|
|
368
|
+
"---- Expression\n" +
|
|
369
|
+
"----- Reference (n)\n" +
|
|
370
|
+
"---- Where\n" +
|
|
371
|
+
"----- Expression\n" +
|
|
372
|
+
"------ GreaterThan\n" +
|
|
373
|
+
"------- Reference (n)\n" +
|
|
374
|
+
"------- Number (1)"
|
|
353
375
|
);
|
|
354
376
|
});
|
|
355
377
|
|
|
356
|
-
test(
|
|
378
|
+
test("Test case statement", () => {
|
|
357
379
|
const parser = new Parser();
|
|
358
|
-
const ast = parser.parse(
|
|
380
|
+
const ast = parser.parse("RETURN CASE WHEN 1 THEN 2 ELSE 3 END");
|
|
359
381
|
expect(ast.print()).toBe(
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
382
|
+
"ASTNode\n" +
|
|
383
|
+
"- Return\n" +
|
|
384
|
+
"-- Expression\n" +
|
|
385
|
+
"--- Case\n" +
|
|
386
|
+
"---- When\n" +
|
|
387
|
+
"----- Expression\n" +
|
|
388
|
+
"------ Number (1)\n" +
|
|
389
|
+
"---- Then\n" +
|
|
390
|
+
"----- Expression\n" +
|
|
391
|
+
"------ Number (2)\n" +
|
|
392
|
+
"---- Else\n" +
|
|
393
|
+
"----- Expression\n" +
|
|
394
|
+
"------ Number (3)"
|
|
373
395
|
);
|
|
374
396
|
});
|
|
375
397
|
|
|
376
|
-
test(
|
|
377
|
-
expect(() =>
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
expect(() =>
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
expect(() =>
|
|
398
|
+
test("Test functions with wrong number of arguments", () => {
|
|
399
|
+
expect(() => new Parser().parse("RETURN range(1)")).toThrow(
|
|
400
|
+
"Function range expected 2 parameters, but got 1"
|
|
401
|
+
);
|
|
402
|
+
expect(() => new Parser().parse("RETURN range(1, 2, 3)")).toThrow(
|
|
403
|
+
"Function range expected 2 parameters, but got 3"
|
|
404
|
+
);
|
|
405
|
+
expect(() => new Parser().parse("RETURN avg(1, 2, 3)")).toThrow(
|
|
406
|
+
"Function avg expected 1 parameters, but got 3"
|
|
407
|
+
);
|
|
408
|
+
expect(() => new Parser().parse("RETURN sum(1, 2)")).toThrow(
|
|
409
|
+
"Function sum expected 1 parameters, but got 2"
|
|
410
|
+
);
|
|
411
|
+
expect(() => new Parser().parse('RETURN split("a", "b", "c")')).toThrow(
|
|
412
|
+
"Function split expected 2 parameters, but got 3"
|
|
413
|
+
);
|
|
414
|
+
expect(() => new Parser().parse("RETURN size(1, 2)")).toThrow(
|
|
415
|
+
"Function size expected 1 parameters, but got 2"
|
|
416
|
+
);
|
|
417
|
+
expect(() => new Parser().parse("RETURN round(1, 2)")).toThrow(
|
|
418
|
+
"Function round expected 1 parameters, but got 2"
|
|
419
|
+
);
|
|
384
420
|
});
|
|
385
421
|
|
|
386
|
-
test(
|
|
387
|
-
expect(() =>
|
|
388
|
-
|
|
422
|
+
test("Test non-well formed statements", () => {
|
|
423
|
+
expect(() => new Parser().parse("return 1 return 1")).toThrow(
|
|
424
|
+
"Only one RETURN statement is allowed"
|
|
425
|
+
);
|
|
426
|
+
expect(() => new Parser().parse("return 1 with 1 as n")).toThrow(
|
|
427
|
+
"Last statement must be a RETURN, WHERE, or a CALL statement"
|
|
428
|
+
);
|
|
389
429
|
});
|
|
390
430
|
|
|
391
|
-
test(
|
|
431
|
+
test("Test associative array with backtick string", () => {
|
|
392
432
|
const parser = new Parser();
|
|
393
|
-
const ast = parser.parse(
|
|
433
|
+
const ast = parser.parse("RETURN {`key`: `value`}");
|
|
394
434
|
expect(ast.print()).toBe(
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
435
|
+
"ASTNode\n" +
|
|
436
|
+
"- Return\n" +
|
|
437
|
+
"-- Expression\n" +
|
|
438
|
+
"--- AssociativeArray\n" +
|
|
439
|
+
"---- KeyValuePair\n" +
|
|
440
|
+
"----- String (key)\n" +
|
|
441
|
+
"----- Expression\n" +
|
|
442
|
+
"------ Reference (value)"
|
|
403
443
|
);
|
|
404
444
|
});
|
|
405
445
|
|
|
406
|
-
test(
|
|
446
|
+
test("Test limit", () => {
|
|
407
447
|
const parser = new Parser();
|
|
408
|
-
const ast = parser.parse(
|
|
448
|
+
const ast = parser.parse("unwind range(1, 10) as n limit 5 return n");
|
|
409
449
|
expect(ast.print()).toBe(
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
450
|
+
"ASTNode\n" +
|
|
451
|
+
"- Unwind\n" +
|
|
452
|
+
"-- Expression (n)\n" +
|
|
453
|
+
"--- Function (range)\n" +
|
|
454
|
+
"---- Expression\n" +
|
|
455
|
+
"----- Number (1)\n" +
|
|
456
|
+
"---- Expression\n" +
|
|
457
|
+
"----- Number (10)\n" +
|
|
458
|
+
"- Limit\n" +
|
|
459
|
+
"- Return\n" +
|
|
460
|
+
"-- Expression (n)\n" +
|
|
461
|
+
"--- Reference (n)"
|
|
422
462
|
);
|
|
423
463
|
});
|
|
424
464
|
|
|
425
|
-
test(
|
|
465
|
+
test("Test return -2", () => {
|
|
426
466
|
const parser = new Parser();
|
|
427
|
-
const ast = parser.parse(
|
|
467
|
+
const ast = parser.parse("return -2");
|
|
468
|
+
expect(ast.print()).toBe("ASTNode\n" + "- Return\n" + "-- Expression\n" + "--- Number (-2)");
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
test("Test call operation", () => {
|
|
472
|
+
const parser = new Parser();
|
|
473
|
+
const ast = parser.parse("CALL test() YIELD result RETURN result");
|
|
428
474
|
expect(ast.print()).toBe(
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
475
|
+
"ASTNode\n" +
|
|
476
|
+
"- Call\n" +
|
|
477
|
+
"-- Expression (result)\n" +
|
|
478
|
+
"--- Reference (result)\n" +
|
|
479
|
+
"- Return\n" +
|
|
480
|
+
"-- Expression (result)\n" +
|
|
481
|
+
"--- Reference (result)"
|
|
433
482
|
);
|
|
434
|
-
});
|
|
483
|
+
});
|