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