sql-typechecker 0.0.7 → 0.0.10
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/out/cli.js +133 -88
- package/out/cli.js.map +2 -2
- package/out/typeparsers.js +1 -1
- package/out/typeparsers.js.map +2 -2
- package/package.json +5 -5
- package/.envrc +0 -2
- package/esbuild.js +0 -12
- package/index.ts +0 -22
- package/sample/nested/sample2.sql +0 -26
- package/sample/out.ts +0 -70
- package/sample/sample1.sql +0 -20
- package/school/sql.sql +0 -1055
- package/school/test.ts +0 -27
- package/shell.nix +0 -16
- package/src/builtincasts.ts +0 -277
- package/src/builtinoperators.ts +0 -5144
- package/src/builtinunaryoperators.ts +0 -291
- package/src/cli.ts +0 -144
- package/src/codegen.ts +0 -384
- package/src/readme.md +0 -23
- package/src/typecheck.ts +0 -2143
- package/src/typeparsers.ts +0 -33
- package/template1.sql +0 -43
- package/test/test.ts +0 -1378
- package/tsconfig.json +0 -23
package/test/test.ts
DELETED
|
@@ -1,1378 +0,0 @@
|
|
|
1
|
-
import { Expect, Focus, IgnoreTest, Test, TestFixture } from "alsatian";
|
|
2
|
-
import { Name, parse, QName } from "pgsql-ast-parser";
|
|
3
|
-
import { Either, Left, Right } from "purify-ts";
|
|
4
|
-
import {
|
|
5
|
-
ArrayT,
|
|
6
|
-
BuiltinTypeConstructors,
|
|
7
|
-
BuiltinTypes,
|
|
8
|
-
doCreateFunction,
|
|
9
|
-
parseSetupScripts,
|
|
10
|
-
ScalarT,
|
|
11
|
-
RecordT,
|
|
12
|
-
SimpleT,
|
|
13
|
-
Type,
|
|
14
|
-
VoidT,
|
|
15
|
-
} from "../src/typecheck";
|
|
16
|
-
|
|
17
|
-
// https://github.com/alsatian-test/alsatian/blob/master/packages/alsatian/README.md
|
|
18
|
-
|
|
19
|
-
function testCreateFunction(
|
|
20
|
-
setupStr: string,
|
|
21
|
-
queryStr: string,
|
|
22
|
-
cont: (
|
|
23
|
-
a: Either<
|
|
24
|
-
Error,
|
|
25
|
-
{
|
|
26
|
-
name: QName;
|
|
27
|
-
inputs: { name: Name; type: SimpleT }[];
|
|
28
|
-
returns: Type | VoidT;
|
|
29
|
-
multipleRows: boolean;
|
|
30
|
-
}
|
|
31
|
-
>
|
|
32
|
-
) => void
|
|
33
|
-
) {
|
|
34
|
-
const g = parseSetupScripts(parse(setupStr));
|
|
35
|
-
const query = parse(queryStr);
|
|
36
|
-
if (query[0].type === "create function") {
|
|
37
|
-
try {
|
|
38
|
-
const res = doCreateFunction(g, { decls: [], froms: [] }, query[0]);
|
|
39
|
-
cont(Right(res));
|
|
40
|
-
} catch (err) {
|
|
41
|
-
cont(Left(err as Error));
|
|
42
|
-
}
|
|
43
|
-
} else {
|
|
44
|
-
throw new Error("Bad test setup");
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function expectInputs(
|
|
49
|
-
setupStr: string,
|
|
50
|
-
queryStr: string,
|
|
51
|
-
expectedInputTypes: {
|
|
52
|
-
name: Name;
|
|
53
|
-
type: SimpleT;
|
|
54
|
-
}[]
|
|
55
|
-
) {
|
|
56
|
-
testCreateFunction(setupStr, queryStr, (res) => {
|
|
57
|
-
res.caseOf({
|
|
58
|
-
Left: (err) => {
|
|
59
|
-
throw err;
|
|
60
|
-
},
|
|
61
|
-
Right: (res) => {
|
|
62
|
-
Expect(res.inputs.length).toEqual(expectedInputTypes.length);
|
|
63
|
-
expectedInputTypes.forEach((expectedInputType, i) => {
|
|
64
|
-
Expect(res.inputs[i]).toEqual(expectedInputType);
|
|
65
|
-
});
|
|
66
|
-
},
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function expectReturnType<T>(
|
|
72
|
-
setupStr: string,
|
|
73
|
-
queryStr: string,
|
|
74
|
-
expectedReturnType: RecordT | ScalarT | ArrayT<T> | VoidT
|
|
75
|
-
) {
|
|
76
|
-
testCreateFunction(setupStr, queryStr, (res) => {
|
|
77
|
-
res.caseOf({
|
|
78
|
-
Left: (err) => {
|
|
79
|
-
throw err;
|
|
80
|
-
},
|
|
81
|
-
Right: (res) => {
|
|
82
|
-
Expect(res.returns).toEqual(expectedReturnType);
|
|
83
|
-
},
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function expectThrowLike(
|
|
89
|
-
setupStr: string,
|
|
90
|
-
queryStr: string,
|
|
91
|
-
expectedError: string
|
|
92
|
-
) {
|
|
93
|
-
testCreateFunction(setupStr, queryStr, (res) => {
|
|
94
|
-
res.caseOf({
|
|
95
|
-
Left: (err) => {
|
|
96
|
-
Expect(err.message).toContain(expectedError);
|
|
97
|
-
},
|
|
98
|
-
Right: (_) => {
|
|
99
|
-
throw new Error("Should return error");
|
|
100
|
-
},
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
@TestFixture("Typechecker")
|
|
106
|
-
export class TypecheckerTests {
|
|
107
|
-
@Test()
|
|
108
|
-
public select() {
|
|
109
|
-
expectReturnType(
|
|
110
|
-
"create table testje ( id int not null, name text );",
|
|
111
|
-
`
|
|
112
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
113
|
-
SELECT id, name
|
|
114
|
-
FROM testje
|
|
115
|
-
$$ LANGUAGE sql;
|
|
116
|
-
`,
|
|
117
|
-
{
|
|
118
|
-
kind: "set",
|
|
119
|
-
fields: [
|
|
120
|
-
{
|
|
121
|
-
name: { name: "id" },
|
|
122
|
-
type: BuiltinTypes.Integer,
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
name: { name: "name" },
|
|
126
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
127
|
-
},
|
|
128
|
-
],
|
|
129
|
-
}
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
@Test()
|
|
133
|
-
public alias() {
|
|
134
|
-
expectReturnType(
|
|
135
|
-
"create table testje ( id int not null, name text );",
|
|
136
|
-
`
|
|
137
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
138
|
-
SELECT mytest.id as myid
|
|
139
|
-
FROM testje as mytest
|
|
140
|
-
$$ LANGUAGE sql;
|
|
141
|
-
`,
|
|
142
|
-
{
|
|
143
|
-
kind: "set",
|
|
144
|
-
fields: [
|
|
145
|
-
{
|
|
146
|
-
name: { name: "myid" },
|
|
147
|
-
type: BuiltinTypes.Integer,
|
|
148
|
-
},
|
|
149
|
-
],
|
|
150
|
-
}
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
@Test()
|
|
155
|
-
public inputTypes() {
|
|
156
|
-
expectInputs(
|
|
157
|
-
"create table testje ( id int not null, name text );",
|
|
158
|
-
`
|
|
159
|
-
CREATE FUNCTION myselect(myid int, myname text default null) RETURNS SETOF AS $$
|
|
160
|
-
SELECT id, name
|
|
161
|
-
FROM testje
|
|
162
|
-
WHERE id = myid
|
|
163
|
-
AND myname = name;
|
|
164
|
-
$$ LANGUAGE sql;
|
|
165
|
-
`,
|
|
166
|
-
[
|
|
167
|
-
{
|
|
168
|
-
name: { name: "myid" },
|
|
169
|
-
type: BuiltinTypes.Integer,
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
name: { name: "myname" },
|
|
173
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
174
|
-
},
|
|
175
|
-
]
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
@Test()
|
|
180
|
-
public unifyError() {
|
|
181
|
-
expectThrowLike(
|
|
182
|
-
"create table testje ( id int not null, name text );",
|
|
183
|
-
`
|
|
184
|
-
CREATE FUNCTION myselect(myname text) RETURNS SETOF AS $$
|
|
185
|
-
SELECT id, name
|
|
186
|
-
FROM testje
|
|
187
|
-
WHERE id = myname;
|
|
188
|
-
$$ LANGUAGE sql;
|
|
189
|
-
`,
|
|
190
|
-
'Can\'t apply operator "=" to integer and text'
|
|
191
|
-
);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
@Test()
|
|
195
|
-
public innerJoin() {
|
|
196
|
-
expectReturnType(
|
|
197
|
-
"create table testje ( id int not null, name text );",
|
|
198
|
-
`
|
|
199
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
200
|
-
SELECT testje.id as id1, testje2.id as id2, testje.name
|
|
201
|
-
FROM testje
|
|
202
|
-
JOIN testje AS testje2 ON testje.name = testje2.name
|
|
203
|
-
$$ LANGUAGE sql;
|
|
204
|
-
`,
|
|
205
|
-
{
|
|
206
|
-
kind: "set",
|
|
207
|
-
fields: [
|
|
208
|
-
{
|
|
209
|
-
name: { name: "id1" },
|
|
210
|
-
type: BuiltinTypes.Integer,
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
name: { name: "id2" },
|
|
214
|
-
type: BuiltinTypes.Integer,
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
name: { name: "name" },
|
|
218
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
219
|
-
},
|
|
220
|
-
],
|
|
221
|
-
}
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
@Test()
|
|
226
|
-
public leftJoin() {
|
|
227
|
-
expectReturnType(
|
|
228
|
-
"create table testje ( id int not null, name text );",
|
|
229
|
-
`
|
|
230
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
231
|
-
SELECT testje.id as id1, testje2.id as id2
|
|
232
|
-
FROM testje
|
|
233
|
-
LEFT OUTER JOIN testje AS testje2 ON testje.name = testje2.name
|
|
234
|
-
$$ LANGUAGE sql;
|
|
235
|
-
`,
|
|
236
|
-
{
|
|
237
|
-
kind: "set",
|
|
238
|
-
fields: [
|
|
239
|
-
{
|
|
240
|
-
name: { name: "id1" },
|
|
241
|
-
type: BuiltinTypes.Integer,
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
name: { name: "id2" },
|
|
245
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Integer),
|
|
246
|
-
},
|
|
247
|
-
],
|
|
248
|
-
}
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
@Test()
|
|
253
|
-
public rightJoin() {
|
|
254
|
-
expectReturnType(
|
|
255
|
-
"create table testje ( id int not null, name text );",
|
|
256
|
-
`
|
|
257
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
258
|
-
SELECT testje.id as id1, testje2.id as id2
|
|
259
|
-
FROM testje
|
|
260
|
-
RIGHT JOIN testje AS testje2 ON testje.name = testje2.name
|
|
261
|
-
$$ LANGUAGE sql;
|
|
262
|
-
`,
|
|
263
|
-
{
|
|
264
|
-
kind: "set",
|
|
265
|
-
fields: [
|
|
266
|
-
{
|
|
267
|
-
name: { name: "id1" },
|
|
268
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Integer),
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
name: { name: "id2" },
|
|
272
|
-
type: BuiltinTypes.Integer,
|
|
273
|
-
},
|
|
274
|
-
],
|
|
275
|
-
}
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
@Test()
|
|
280
|
-
public ambiguousIdentifier() {
|
|
281
|
-
expectThrowLike(
|
|
282
|
-
"create table testje ( id int not null, name text );",
|
|
283
|
-
`
|
|
284
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
285
|
-
SELECT name
|
|
286
|
-
FROM testje
|
|
287
|
-
JOIN testje AS testje2 ON testje.name = testje2.name
|
|
288
|
-
$$ LANGUAGE sql;
|
|
289
|
-
`,
|
|
290
|
-
`AmbiguousIdentifier name`
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
@Test()
|
|
295
|
-
public selectStar() {
|
|
296
|
-
expectReturnType(
|
|
297
|
-
`
|
|
298
|
-
create table testje ( id int not null, name text );
|
|
299
|
-
create table testje2 ( id2 int not null, name2 text );
|
|
300
|
-
`,
|
|
301
|
-
`
|
|
302
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
303
|
-
SELECT *
|
|
304
|
-
FROM testje
|
|
305
|
-
JOIN testje2 ON testje.id = testje2.id2
|
|
306
|
-
$$ LANGUAGE sql;
|
|
307
|
-
`,
|
|
308
|
-
{
|
|
309
|
-
kind: "set",
|
|
310
|
-
fields: [
|
|
311
|
-
{
|
|
312
|
-
name: { name: "id" },
|
|
313
|
-
type: BuiltinTypes.Integer,
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
name: { name: "name" },
|
|
317
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
318
|
-
},
|
|
319
|
-
{
|
|
320
|
-
name: { name: "id2" },
|
|
321
|
-
type: BuiltinTypes.Integer,
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
name: { name: "name2" },
|
|
325
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
326
|
-
},
|
|
327
|
-
],
|
|
328
|
-
}
|
|
329
|
-
);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
@Test()
|
|
333
|
-
public selectTableStar() {
|
|
334
|
-
expectReturnType(
|
|
335
|
-
`
|
|
336
|
-
create table testje ( id int not null, name text );
|
|
337
|
-
create table testje2 ( id2 int not null, name2 text );
|
|
338
|
-
`,
|
|
339
|
-
`
|
|
340
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
341
|
-
SELECT testje2.*
|
|
342
|
-
FROM testje
|
|
343
|
-
JOIN testje2 ON testje.id = testje2.id2
|
|
344
|
-
$$ LANGUAGE sql;
|
|
345
|
-
`,
|
|
346
|
-
{
|
|
347
|
-
kind: "set",
|
|
348
|
-
fields: [
|
|
349
|
-
{
|
|
350
|
-
name: { name: "id2" },
|
|
351
|
-
type: BuiltinTypes.Integer,
|
|
352
|
-
},
|
|
353
|
-
{
|
|
354
|
-
name: { name: "name2" },
|
|
355
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
356
|
-
},
|
|
357
|
-
],
|
|
358
|
-
}
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
@Test()
|
|
363
|
-
public dontUseEqualNull() {
|
|
364
|
-
expectThrowLike(
|
|
365
|
-
"create table testje ( id int not null, name text );",
|
|
366
|
-
`
|
|
367
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
368
|
-
SELECT id
|
|
369
|
-
FROM testje
|
|
370
|
-
WHERE id = NULL
|
|
371
|
-
$$ LANGUAGE sql;
|
|
372
|
-
`,
|
|
373
|
-
`Don't use "= NULL"`
|
|
374
|
-
);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
@Test()
|
|
378
|
-
public isNull() {
|
|
379
|
-
expectReturnType(
|
|
380
|
-
"create table testje ( id int not null, name text );",
|
|
381
|
-
`
|
|
382
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
383
|
-
SELECT id
|
|
384
|
-
FROM testje
|
|
385
|
-
WHERE id IS NULL
|
|
386
|
-
$$ LANGUAGE sql;
|
|
387
|
-
`,
|
|
388
|
-
{
|
|
389
|
-
kind: "set",
|
|
390
|
-
fields: [
|
|
391
|
-
{
|
|
392
|
-
name: { name: "id" },
|
|
393
|
-
type: BuiltinTypes.Integer,
|
|
394
|
-
},
|
|
395
|
-
],
|
|
396
|
-
}
|
|
397
|
-
);
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
@Test()
|
|
401
|
-
public operators() {
|
|
402
|
-
expectReturnType(
|
|
403
|
-
"create table testje ( id int not null, name text );",
|
|
404
|
-
`
|
|
405
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
406
|
-
SELECT -id + 2 as id
|
|
407
|
-
FROM testje
|
|
408
|
-
WHERE id + 5 < 7
|
|
409
|
-
$$ LANGUAGE sql;
|
|
410
|
-
`,
|
|
411
|
-
{
|
|
412
|
-
kind: "set",
|
|
413
|
-
fields: [
|
|
414
|
-
{
|
|
415
|
-
name: { name: "id" },
|
|
416
|
-
type: BuiltinTypes.Integer,
|
|
417
|
-
},
|
|
418
|
-
],
|
|
419
|
-
}
|
|
420
|
-
);
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
@Test()
|
|
424
|
-
public inList() {
|
|
425
|
-
expectReturnType(
|
|
426
|
-
"create table testje ( id int not null, name text );",
|
|
427
|
-
`
|
|
428
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
429
|
-
SELECT id
|
|
430
|
-
FROM testje
|
|
431
|
-
WHERE id IN (1, 2, 3)
|
|
432
|
-
$$ LANGUAGE sql;
|
|
433
|
-
`,
|
|
434
|
-
{
|
|
435
|
-
kind: "set",
|
|
436
|
-
fields: [
|
|
437
|
-
{
|
|
438
|
-
name: { name: "id" },
|
|
439
|
-
type: BuiltinTypes.Integer,
|
|
440
|
-
},
|
|
441
|
-
],
|
|
442
|
-
}
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
@Test()
|
|
447
|
-
public inListMismatch() {
|
|
448
|
-
expectThrowLike(
|
|
449
|
-
"create table testje ( id int not null, name text );",
|
|
450
|
-
`
|
|
451
|
-
CREATE FUNCTION myselect(mylist int[]) RETURNS SETOF AS $$
|
|
452
|
-
SELECT id
|
|
453
|
-
FROM testje
|
|
454
|
-
WHERE id IN ('hello')
|
|
455
|
-
$$ LANGUAGE sql;
|
|
456
|
-
`,
|
|
457
|
-
"TypeMismatch"
|
|
458
|
-
);
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
@Test()
|
|
462
|
-
public inListParameter() {
|
|
463
|
-
expectThrowLike(
|
|
464
|
-
"create table testje ( id int not null, name text );",
|
|
465
|
-
`
|
|
466
|
-
CREATE FUNCTION myselect(mylist int[]) RETURNS SETOF AS $$
|
|
467
|
-
SELECT id
|
|
468
|
-
FROM testje
|
|
469
|
-
WHERE id IN mylist
|
|
470
|
-
$$ LANGUAGE sql;
|
|
471
|
-
`,
|
|
472
|
-
"TypeMismatch"
|
|
473
|
-
);
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
@Test()
|
|
477
|
-
public equalAny() {
|
|
478
|
-
expectInputs(
|
|
479
|
-
"create table testje ( id int not null, name text );",
|
|
480
|
-
`
|
|
481
|
-
CREATE FUNCTION myselect(mylist int[]) RETURNS SETOF AS $$
|
|
482
|
-
SELECT id
|
|
483
|
-
FROM testje
|
|
484
|
-
WHERE id = ANY(mylist)
|
|
485
|
-
$$ LANGUAGE sql;
|
|
486
|
-
`,
|
|
487
|
-
[
|
|
488
|
-
{
|
|
489
|
-
name: { name: "mylist" },
|
|
490
|
-
type: BuiltinTypeConstructors.Array(BuiltinTypes.Integer),
|
|
491
|
-
},
|
|
492
|
-
]
|
|
493
|
-
);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
@Test()
|
|
497
|
-
public equalAnyMismatch() {
|
|
498
|
-
expectThrowLike(
|
|
499
|
-
"create table testje ( id int not null, name text );",
|
|
500
|
-
`
|
|
501
|
-
CREATE FUNCTION myselect(mylist text[]) RETURNS SETOF AS $$
|
|
502
|
-
SELECT id
|
|
503
|
-
FROM testje
|
|
504
|
-
WHERE id = ANY(mylist)
|
|
505
|
-
$$ LANGUAGE sql;
|
|
506
|
-
`,
|
|
507
|
-
"Can't apply operator"
|
|
508
|
-
);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
@Test()
|
|
512
|
-
public arraySelect() {
|
|
513
|
-
expectReturnType(
|
|
514
|
-
"create table testje ( id int not null, name text );",
|
|
515
|
-
`
|
|
516
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
517
|
-
SELECT ARRAY[1, 2]
|
|
518
|
-
$$ LANGUAGE sql;
|
|
519
|
-
`,
|
|
520
|
-
{
|
|
521
|
-
kind: "set",
|
|
522
|
-
fields: [
|
|
523
|
-
{
|
|
524
|
-
name: null,
|
|
525
|
-
type: BuiltinTypeConstructors.Array(BuiltinTypes.Integer),
|
|
526
|
-
},
|
|
527
|
-
],
|
|
528
|
-
}
|
|
529
|
-
);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
@Test()
|
|
533
|
-
public arraySelectWithSubquery() {
|
|
534
|
-
expectReturnType(
|
|
535
|
-
"create table testje ( id int not null, name text );",
|
|
536
|
-
`
|
|
537
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
538
|
-
SELECT ARRAY(SELECT id from testje)
|
|
539
|
-
$$ LANGUAGE sql;
|
|
540
|
-
`,
|
|
541
|
-
{
|
|
542
|
-
kind: "set",
|
|
543
|
-
fields: [
|
|
544
|
-
{
|
|
545
|
-
name: null,
|
|
546
|
-
type: BuiltinTypeConstructors.Array(BuiltinTypes.Integer),
|
|
547
|
-
},
|
|
548
|
-
],
|
|
549
|
-
}
|
|
550
|
-
);
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
@Test()
|
|
554
|
-
public arraySelectWithMulticolumnSubquery() {
|
|
555
|
-
expectThrowLike(
|
|
556
|
-
"create table testje ( id int not null, name text );",
|
|
557
|
-
`
|
|
558
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
559
|
-
SELECT ARRAY(SELECT id, name from testje)
|
|
560
|
-
$$ LANGUAGE sql;
|
|
561
|
-
`,
|
|
562
|
-
"TypeMismatch"
|
|
563
|
-
);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
@Test()
|
|
567
|
-
public extract() {
|
|
568
|
-
expectReturnType(
|
|
569
|
-
"create table testje ( id int not null, mystamp timestamp not null);",
|
|
570
|
-
`
|
|
571
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
572
|
-
SELECT EXTRACT(DAY FROM mystamp)
|
|
573
|
-
from testje
|
|
574
|
-
$$ LANGUAGE sql;
|
|
575
|
-
`,
|
|
576
|
-
{
|
|
577
|
-
kind: "set",
|
|
578
|
-
fields: [
|
|
579
|
-
{
|
|
580
|
-
name: null,
|
|
581
|
-
type: BuiltinTypes.Numeric,
|
|
582
|
-
},
|
|
583
|
-
],
|
|
584
|
-
}
|
|
585
|
-
);
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
@Test()
|
|
589
|
-
public extractError() {
|
|
590
|
-
expectThrowLike(
|
|
591
|
-
"create table testje ( id int not null, name text);",
|
|
592
|
-
`
|
|
593
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
594
|
-
SELECT EXTRACT(DAY FROM name)
|
|
595
|
-
from testje
|
|
596
|
-
$$ LANGUAGE sql;
|
|
597
|
-
`,
|
|
598
|
-
"TypeMismatch"
|
|
599
|
-
);
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
@Test()
|
|
603
|
-
public extractErrorWithWrongCasting() {
|
|
604
|
-
expectThrowLike(
|
|
605
|
-
"create table testje ( id int not null, mytime time not null);",
|
|
606
|
-
`
|
|
607
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
608
|
-
SELECT EXTRACT(DAY FROM mytime)
|
|
609
|
-
from testje
|
|
610
|
-
$$ LANGUAGE sql;
|
|
611
|
-
`,
|
|
612
|
-
"TypeMismatch"
|
|
613
|
-
);
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
@Test()
|
|
617
|
-
public jsonMember() {
|
|
618
|
-
expectReturnType(
|
|
619
|
-
"create table testje ( id int not null, myjson json);",
|
|
620
|
-
`
|
|
621
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
622
|
-
SELECT myjson->'bleb'
|
|
623
|
-
from testje
|
|
624
|
-
$$ LANGUAGE sql;
|
|
625
|
-
`,
|
|
626
|
-
{
|
|
627
|
-
kind: "set",
|
|
628
|
-
fields: [
|
|
629
|
-
{
|
|
630
|
-
name: null,
|
|
631
|
-
type: BuiltinTypes.AnyScalar,
|
|
632
|
-
},
|
|
633
|
-
],
|
|
634
|
-
}
|
|
635
|
-
);
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
@Test()
|
|
639
|
-
public jsonMemberError() {
|
|
640
|
-
expectThrowLike(
|
|
641
|
-
"create table testje ( id int not null, name text);",
|
|
642
|
-
`
|
|
643
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
644
|
-
SELECT name->'bleb'
|
|
645
|
-
from testje
|
|
646
|
-
$$ LANGUAGE sql;
|
|
647
|
-
`,
|
|
648
|
-
"TypeMismatch"
|
|
649
|
-
);
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
@Test()
|
|
653
|
-
public Coalesce() {
|
|
654
|
-
expectReturnType(
|
|
655
|
-
"create table testje ( id int not null, name text);",
|
|
656
|
-
`
|
|
657
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
658
|
-
SELECT COALESCE(name, 'hello')
|
|
659
|
-
from testje
|
|
660
|
-
$$ LANGUAGE sql;
|
|
661
|
-
`,
|
|
662
|
-
{
|
|
663
|
-
kind: "set",
|
|
664
|
-
fields: [
|
|
665
|
-
{
|
|
666
|
-
name: null,
|
|
667
|
-
type: BuiltinTypes.Text,
|
|
668
|
-
},
|
|
669
|
-
],
|
|
670
|
-
}
|
|
671
|
-
);
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
@Test()
|
|
675
|
-
public nullif() {
|
|
676
|
-
expectReturnType(
|
|
677
|
-
"create table testje ( id int not null, name text);",
|
|
678
|
-
`
|
|
679
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
680
|
-
SELECT NULLIF(name, 'hello')
|
|
681
|
-
from testje
|
|
682
|
-
$$ LANGUAGE sql;
|
|
683
|
-
`,
|
|
684
|
-
{
|
|
685
|
-
kind: "set",
|
|
686
|
-
fields: [
|
|
687
|
-
{
|
|
688
|
-
name: null,
|
|
689
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
690
|
-
},
|
|
691
|
-
],
|
|
692
|
-
}
|
|
693
|
-
);
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
@Test()
|
|
697
|
-
public CoalesceMismatch() {
|
|
698
|
-
expectThrowLike(
|
|
699
|
-
"create table testje ( id int not null, name text);",
|
|
700
|
-
`
|
|
701
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
702
|
-
SELECT COALESCE(name, 2)
|
|
703
|
-
from testje
|
|
704
|
-
$$ LANGUAGE sql;
|
|
705
|
-
`,
|
|
706
|
-
"TypeMismatch"
|
|
707
|
-
);
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
@Test()
|
|
711
|
-
public keyword() {
|
|
712
|
-
expectReturnType(
|
|
713
|
-
"create table testje ( id int not null, name text);",
|
|
714
|
-
`
|
|
715
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
716
|
-
SELECT CURRENT_TIMESTAMP
|
|
717
|
-
from testje
|
|
718
|
-
$$ LANGUAGE sql;
|
|
719
|
-
`,
|
|
720
|
-
{ kind: "set", fields: [{ name: null, type: BuiltinTypes.Timestamp }] }
|
|
721
|
-
);
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
@Test()
|
|
725
|
-
public arrayIndex() {
|
|
726
|
-
expectReturnType(
|
|
727
|
-
"create table testje ( id int not null, name text[]);",
|
|
728
|
-
`
|
|
729
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
730
|
-
SELECT name[1]
|
|
731
|
-
from testje
|
|
732
|
-
$$ LANGUAGE sql;
|
|
733
|
-
`,
|
|
734
|
-
{
|
|
735
|
-
kind: "set",
|
|
736
|
-
fields: [
|
|
737
|
-
{
|
|
738
|
-
name: null,
|
|
739
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
740
|
-
},
|
|
741
|
-
],
|
|
742
|
-
}
|
|
743
|
-
);
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
@Test()
|
|
747
|
-
public arrayIndexMismatch() {
|
|
748
|
-
expectThrowLike(
|
|
749
|
-
"create table testje ( id int not null, name text);",
|
|
750
|
-
`
|
|
751
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
752
|
-
SELECT name[1]
|
|
753
|
-
from testje
|
|
754
|
-
$$ LANGUAGE sql;
|
|
755
|
-
`,
|
|
756
|
-
"TypeMismatch"
|
|
757
|
-
);
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
@Test()
|
|
761
|
-
public caseWithValue() {
|
|
762
|
-
expectReturnType(
|
|
763
|
-
"create table testje ( id int not null, name text);",
|
|
764
|
-
`
|
|
765
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
766
|
-
SELECT CASE name WHEN '' THEN 2 ELSE 5 END
|
|
767
|
-
from testje
|
|
768
|
-
$$ LANGUAGE sql;
|
|
769
|
-
`,
|
|
770
|
-
{
|
|
771
|
-
kind: "set",
|
|
772
|
-
fields: [
|
|
773
|
-
{
|
|
774
|
-
name: null,
|
|
775
|
-
type: BuiltinTypes.Integer,
|
|
776
|
-
},
|
|
777
|
-
],
|
|
778
|
-
}
|
|
779
|
-
);
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
@Test()
|
|
783
|
-
public caseWithValueMismatchedValues() {
|
|
784
|
-
expectThrowLike(
|
|
785
|
-
"create table testje ( id int not null, name text);",
|
|
786
|
-
`
|
|
787
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
788
|
-
SELECT CASE name WHEN 7 THEN 2 ELSE 5 END
|
|
789
|
-
from testje
|
|
790
|
-
$$ LANGUAGE sql;
|
|
791
|
-
`,
|
|
792
|
-
"TypeMismatch"
|
|
793
|
-
);
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
@Test()
|
|
797
|
-
public caseWithValueMismatchedReturns() {
|
|
798
|
-
expectThrowLike(
|
|
799
|
-
"create table testje ( id int not null, name text);",
|
|
800
|
-
`
|
|
801
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
802
|
-
SELECT CASE name WHEN '' THEN 2 ELSE 'bleb' END
|
|
803
|
-
from testje
|
|
804
|
-
$$ LANGUAGE sql;
|
|
805
|
-
`,
|
|
806
|
-
"TypeMismatch"
|
|
807
|
-
);
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
@Test()
|
|
811
|
-
public caseWithoutValue() {
|
|
812
|
-
expectReturnType(
|
|
813
|
-
"create table testje ( id int not null, name text);",
|
|
814
|
-
`
|
|
815
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
816
|
-
SELECT CASE WHEN name = '' THEN 2 ELSE 5 END
|
|
817
|
-
from testje
|
|
818
|
-
$$ LANGUAGE sql;
|
|
819
|
-
`,
|
|
820
|
-
{
|
|
821
|
-
kind: "set",
|
|
822
|
-
fields: [
|
|
823
|
-
{
|
|
824
|
-
name: null,
|
|
825
|
-
type: BuiltinTypes.Integer,
|
|
826
|
-
},
|
|
827
|
-
],
|
|
828
|
-
}
|
|
829
|
-
);
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
@Test()
|
|
833
|
-
public caseWithoutValueMismatchedCondition() {
|
|
834
|
-
expectThrowLike(
|
|
835
|
-
"create table testje ( id int not null, name text);",
|
|
836
|
-
`
|
|
837
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
838
|
-
SELECT CASE WHEN name THEN 2 ELSE 5 END
|
|
839
|
-
from testje
|
|
840
|
-
$$ LANGUAGE sql;
|
|
841
|
-
`,
|
|
842
|
-
"TypeMismatch"
|
|
843
|
-
);
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
@Test()
|
|
847
|
-
public caseWithoutValueMismatchedReturns() {
|
|
848
|
-
expectThrowLike(
|
|
849
|
-
"create table testje ( id int not null, name text);",
|
|
850
|
-
`
|
|
851
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
852
|
-
SELECT CASE WHEN name = '' THEN 2 ELSE 'bleb' END
|
|
853
|
-
from testje
|
|
854
|
-
$$ LANGUAGE sql;
|
|
855
|
-
`,
|
|
856
|
-
"TypeMismatch"
|
|
857
|
-
);
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
@Test()
|
|
861
|
-
public selectExpr() {
|
|
862
|
-
expectReturnType(
|
|
863
|
-
"create table testje ( id int not null, name text);",
|
|
864
|
-
`
|
|
865
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
866
|
-
SELECT (SELECT t2.id from testje as t2)
|
|
867
|
-
from testje
|
|
868
|
-
$$ LANGUAGE sql;
|
|
869
|
-
`,
|
|
870
|
-
{
|
|
871
|
-
kind: "set",
|
|
872
|
-
fields: [
|
|
873
|
-
{
|
|
874
|
-
name: null,
|
|
875
|
-
type: BuiltinTypes.Integer,
|
|
876
|
-
},
|
|
877
|
-
],
|
|
878
|
-
}
|
|
879
|
-
);
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
@Test()
|
|
883
|
-
public selectUnion() {
|
|
884
|
-
expectReturnType(
|
|
885
|
-
"create table testje ( id int not null, name text);",
|
|
886
|
-
`
|
|
887
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
888
|
-
SELECT id, name
|
|
889
|
-
FROM testje
|
|
890
|
-
UNION
|
|
891
|
-
SELECT id + 1, name
|
|
892
|
-
FROM testje
|
|
893
|
-
$$ LANGUAGE sql;
|
|
894
|
-
`,
|
|
895
|
-
{
|
|
896
|
-
kind: "set",
|
|
897
|
-
fields: [
|
|
898
|
-
{
|
|
899
|
-
name: { name: "id" },
|
|
900
|
-
type: BuiltinTypes.Integer,
|
|
901
|
-
},
|
|
902
|
-
{
|
|
903
|
-
name: { name: "name" },
|
|
904
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
905
|
-
},
|
|
906
|
-
],
|
|
907
|
-
}
|
|
908
|
-
);
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
@Test()
|
|
912
|
-
public selectUnionAll() {
|
|
913
|
-
expectReturnType(
|
|
914
|
-
"create table testje ( id int not null, name text);",
|
|
915
|
-
`
|
|
916
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
917
|
-
SELECT id, name
|
|
918
|
-
FROM testje
|
|
919
|
-
UNION ALL
|
|
920
|
-
SELECT id + 1, name
|
|
921
|
-
FROM testje
|
|
922
|
-
$$ LANGUAGE sql;
|
|
923
|
-
`,
|
|
924
|
-
{
|
|
925
|
-
kind: "set",
|
|
926
|
-
fields: [
|
|
927
|
-
{
|
|
928
|
-
name: { name: "id" },
|
|
929
|
-
type: BuiltinTypes.Integer,
|
|
930
|
-
},
|
|
931
|
-
{
|
|
932
|
-
name: { name: "name" },
|
|
933
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
934
|
-
},
|
|
935
|
-
],
|
|
936
|
-
}
|
|
937
|
-
);
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
@Test()
|
|
941
|
-
@IgnoreTest("Haven't implemented column name resolution properly yet")
|
|
942
|
-
public fieldNameFromOperation() {
|
|
943
|
-
expectReturnType(
|
|
944
|
-
"create table testje ( id int not null, name text);",
|
|
945
|
-
`
|
|
946
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
947
|
-
SELECT id + 1
|
|
948
|
-
FROM testje
|
|
949
|
-
$$ LANGUAGE sql;
|
|
950
|
-
`,
|
|
951
|
-
{
|
|
952
|
-
kind: "set",
|
|
953
|
-
fields: [
|
|
954
|
-
{
|
|
955
|
-
name: { name: "id" },
|
|
956
|
-
type: BuiltinTypes.Integer,
|
|
957
|
-
},
|
|
958
|
-
],
|
|
959
|
-
}
|
|
960
|
-
);
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
@Test()
|
|
964
|
-
public selectUnionMismatch() {
|
|
965
|
-
expectThrowLike(
|
|
966
|
-
"create table testje ( id int not null, name text);",
|
|
967
|
-
`
|
|
968
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
969
|
-
SELECT id, name
|
|
970
|
-
FROM testje
|
|
971
|
-
UNION
|
|
972
|
-
SELECT name
|
|
973
|
-
FROM testje
|
|
974
|
-
$$ LANGUAGE sql;
|
|
975
|
-
`,
|
|
976
|
-
"TypeMismatch"
|
|
977
|
-
);
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
@Test()
|
|
981
|
-
public selectValues() {
|
|
982
|
-
expectReturnType(
|
|
983
|
-
"create table testje ( id int not null, name text);",
|
|
984
|
-
`
|
|
985
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
986
|
-
SELECT * FROM (VALUES (1, 'one'), (2, 'two')) AS vals
|
|
987
|
-
$$ LANGUAGE sql;
|
|
988
|
-
`,
|
|
989
|
-
{
|
|
990
|
-
kind: "set",
|
|
991
|
-
fields: [
|
|
992
|
-
{
|
|
993
|
-
name: null,
|
|
994
|
-
type: BuiltinTypes.Integer,
|
|
995
|
-
},
|
|
996
|
-
{
|
|
997
|
-
name: null,
|
|
998
|
-
type: BuiltinTypes.Text,
|
|
999
|
-
},
|
|
1000
|
-
],
|
|
1001
|
-
}
|
|
1002
|
-
);
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
@Test()
|
|
1006
|
-
public selectValuesMismatchLengths() {
|
|
1007
|
-
expectThrowLike(
|
|
1008
|
-
"create table testje ( id int not null, name text);",
|
|
1009
|
-
`
|
|
1010
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1011
|
-
SELECT * FROM (VALUES (1, 'one'), (2)) AS vals
|
|
1012
|
-
$$ LANGUAGE sql;
|
|
1013
|
-
`,
|
|
1014
|
-
"TypeMismatch"
|
|
1015
|
-
);
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
@Test()
|
|
1019
|
-
public selectValuesMismatchTypes() {
|
|
1020
|
-
expectThrowLike(
|
|
1021
|
-
"create table testje ( id int not null, name text);",
|
|
1022
|
-
`
|
|
1023
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1024
|
-
SELECT * FROM (VALUES (1, 'one'), (2, 5)) AS vals
|
|
1025
|
-
$$ LANGUAGE sql;
|
|
1026
|
-
`,
|
|
1027
|
-
"TypeMismatch"
|
|
1028
|
-
);
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
@Test()
|
|
1032
|
-
public ternary() {
|
|
1033
|
-
expectReturnType(
|
|
1034
|
-
"create table testje ( id int not null, name text);",
|
|
1035
|
-
`
|
|
1036
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1037
|
-
SELECT id
|
|
1038
|
-
FROM testje
|
|
1039
|
-
WHERE id BETWEEN 2 AND 5
|
|
1040
|
-
$$ LANGUAGE sql;
|
|
1041
|
-
`,
|
|
1042
|
-
{
|
|
1043
|
-
kind: "set",
|
|
1044
|
-
fields: [{ name: { name: "id" }, type: BuiltinTypes.Integer }],
|
|
1045
|
-
}
|
|
1046
|
-
);
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
@Test()
|
|
1050
|
-
public ternaryMismatch() {
|
|
1051
|
-
expectThrowLike(
|
|
1052
|
-
"create table testje ( id int not null, name text);",
|
|
1053
|
-
`
|
|
1054
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1055
|
-
SELECT id
|
|
1056
|
-
FROM testje
|
|
1057
|
-
WHERE id BETWEEN 2 AND '5'
|
|
1058
|
-
$$ LANGUAGE sql;
|
|
1059
|
-
`,
|
|
1060
|
-
"TypeMismatch"
|
|
1061
|
-
);
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
@Test()
|
|
1065
|
-
public substring() {
|
|
1066
|
-
expectReturnType(
|
|
1067
|
-
"create table testje ( id int not null, name text);",
|
|
1068
|
-
`
|
|
1069
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1070
|
-
SELECT SUBSTRING(name from 5 for 7) as name
|
|
1071
|
-
FROM testje
|
|
1072
|
-
WHERE id BETWEEN 2 AND 5
|
|
1073
|
-
$$ LANGUAGE sql;
|
|
1074
|
-
`,
|
|
1075
|
-
{
|
|
1076
|
-
kind: "set",
|
|
1077
|
-
fields: [
|
|
1078
|
-
{
|
|
1079
|
-
name: { name: "name" },
|
|
1080
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
1081
|
-
},
|
|
1082
|
-
],
|
|
1083
|
-
}
|
|
1084
|
-
);
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
@Test()
|
|
1088
|
-
public substringNotnullable() {
|
|
1089
|
-
expectReturnType(
|
|
1090
|
-
"create table testje ( id int not null, name text not null);",
|
|
1091
|
-
`
|
|
1092
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1093
|
-
SELECT SUBSTRING(name from 5 for 7) as name
|
|
1094
|
-
FROM testje
|
|
1095
|
-
WHERE id BETWEEN 2 AND 5
|
|
1096
|
-
$$ LANGUAGE sql;
|
|
1097
|
-
`,
|
|
1098
|
-
{
|
|
1099
|
-
kind: "set",
|
|
1100
|
-
fields: [
|
|
1101
|
-
{
|
|
1102
|
-
name: { name: "name" },
|
|
1103
|
-
type: BuiltinTypes.Text,
|
|
1104
|
-
},
|
|
1105
|
-
],
|
|
1106
|
-
}
|
|
1107
|
-
);
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
@Test()
|
|
1111
|
-
public substringMismatch() {
|
|
1112
|
-
expectThrowLike(
|
|
1113
|
-
"create table testje ( id int not null, name text);",
|
|
1114
|
-
`
|
|
1115
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1116
|
-
SELECT SUBSTRING(name from 5 for 'b') as name
|
|
1117
|
-
FROM testje
|
|
1118
|
-
$$ LANGUAGE sql;
|
|
1119
|
-
`,
|
|
1120
|
-
"TypeMismatch"
|
|
1121
|
-
);
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
@Test()
|
|
1125
|
-
public cast() {
|
|
1126
|
-
expectReturnType(
|
|
1127
|
-
"create table testje ( id int not null, name text);",
|
|
1128
|
-
`
|
|
1129
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1130
|
-
SELECT id::int as id, name::text as name
|
|
1131
|
-
from testje
|
|
1132
|
-
$$ LANGUAGE sql;
|
|
1133
|
-
`,
|
|
1134
|
-
{
|
|
1135
|
-
kind: "set",
|
|
1136
|
-
fields: [
|
|
1137
|
-
{
|
|
1138
|
-
name: { name: "id" },
|
|
1139
|
-
type: BuiltinTypes.Integer,
|
|
1140
|
-
},
|
|
1141
|
-
{
|
|
1142
|
-
name: { name: "name" },
|
|
1143
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Text),
|
|
1144
|
-
},
|
|
1145
|
-
],
|
|
1146
|
-
}
|
|
1147
|
-
);
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
@Test()
|
|
1151
|
-
public operatorOnNullable1() {
|
|
1152
|
-
expectReturnType(
|
|
1153
|
-
"create table testje ( id int not null, name text);",
|
|
1154
|
-
`
|
|
1155
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1156
|
-
SELECT id + NULL as id
|
|
1157
|
-
from testje
|
|
1158
|
-
$$ LANGUAGE sql;
|
|
1159
|
-
`,
|
|
1160
|
-
{
|
|
1161
|
-
kind: "set",
|
|
1162
|
-
fields: [
|
|
1163
|
-
{
|
|
1164
|
-
name: { name: "id" },
|
|
1165
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Integer),
|
|
1166
|
-
},
|
|
1167
|
-
],
|
|
1168
|
-
}
|
|
1169
|
-
);
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
@Test()
|
|
1173
|
-
public operatorOnNullable2() {
|
|
1174
|
-
expectReturnType(
|
|
1175
|
-
"create table testje ( id int );",
|
|
1176
|
-
`
|
|
1177
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1178
|
-
SELECT id + 5 as id
|
|
1179
|
-
from testje
|
|
1180
|
-
$$ LANGUAGE sql;
|
|
1181
|
-
`,
|
|
1182
|
-
{
|
|
1183
|
-
kind: "set",
|
|
1184
|
-
fields: [
|
|
1185
|
-
{
|
|
1186
|
-
name: { name: "id" },
|
|
1187
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Integer),
|
|
1188
|
-
},
|
|
1189
|
-
],
|
|
1190
|
-
}
|
|
1191
|
-
);
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
@Test()
|
|
1195
|
-
public operatorOnNullable3() {
|
|
1196
|
-
expectReturnType(
|
|
1197
|
-
"create table testje ( id int NOT NULL);",
|
|
1198
|
-
`
|
|
1199
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1200
|
-
SELECT id + 5 as id
|
|
1201
|
-
from testje
|
|
1202
|
-
$$ LANGUAGE sql;
|
|
1203
|
-
`,
|
|
1204
|
-
{
|
|
1205
|
-
kind: "set",
|
|
1206
|
-
fields: [
|
|
1207
|
-
{
|
|
1208
|
-
name: { name: "id" },
|
|
1209
|
-
type: BuiltinTypes.Integer,
|
|
1210
|
-
},
|
|
1211
|
-
],
|
|
1212
|
-
}
|
|
1213
|
-
);
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
@Test()
|
|
1217
|
-
public operatorOnNullable4() {
|
|
1218
|
-
expectReturnType(
|
|
1219
|
-
"create table testje ( id int NOT NULL, id2 int);",
|
|
1220
|
-
`
|
|
1221
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1222
|
-
SELECT id + id2 as id
|
|
1223
|
-
from testje
|
|
1224
|
-
$$ LANGUAGE sql;
|
|
1225
|
-
`,
|
|
1226
|
-
{
|
|
1227
|
-
kind: "set",
|
|
1228
|
-
fields: [
|
|
1229
|
-
{
|
|
1230
|
-
name: { name: "id" },
|
|
1231
|
-
type: BuiltinTypeConstructors.Nullable(BuiltinTypes.Integer),
|
|
1232
|
-
},
|
|
1233
|
-
],
|
|
1234
|
-
}
|
|
1235
|
-
);
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
@Test()
|
|
1239
|
-
public unification() {
|
|
1240
|
-
expectReturnType(
|
|
1241
|
-
"create table testje ( id int NOT NULL, id2 int);",
|
|
1242
|
-
`
|
|
1243
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1244
|
-
SELECT CASE id WHEN 0 THEN 5 ELSE 6.5 END as mynumber
|
|
1245
|
-
FROM testje
|
|
1246
|
-
$$ LANGUAGE sql;
|
|
1247
|
-
`,
|
|
1248
|
-
{
|
|
1249
|
-
kind: "set",
|
|
1250
|
-
fields: [
|
|
1251
|
-
{
|
|
1252
|
-
name: { name: "mynumber" },
|
|
1253
|
-
type: BuiltinTypes.Numeric,
|
|
1254
|
-
},
|
|
1255
|
-
],
|
|
1256
|
-
}
|
|
1257
|
-
);
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
@Test()
|
|
1261
|
-
public insert() {
|
|
1262
|
-
expectReturnType(
|
|
1263
|
-
"create table testje ( id int NOT NULL, name text);",
|
|
1264
|
-
`
|
|
1265
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1266
|
-
INSERT INTO testje (id, name) VALUES (1, 'hello');
|
|
1267
|
-
$$ LANGUAGE sql;
|
|
1268
|
-
`,
|
|
1269
|
-
{ kind: "void" }
|
|
1270
|
-
);
|
|
1271
|
-
}
|
|
1272
|
-
|
|
1273
|
-
@Test()
|
|
1274
|
-
public insertErro() {
|
|
1275
|
-
expectThrowLike(
|
|
1276
|
-
"create table testje ( id int NOT NULL, name text);",
|
|
1277
|
-
`
|
|
1278
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1279
|
-
INSERT INTO testje (id, name) VALUES (1, 2);
|
|
1280
|
-
$$ LANGUAGE sql;
|
|
1281
|
-
`,
|
|
1282
|
-
"TypeMismatch"
|
|
1283
|
-
);
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
@Test()
|
|
1287
|
-
public returning() {
|
|
1288
|
-
expectReturnType(
|
|
1289
|
-
"create table testje ( id int NOT NULL, name text);",
|
|
1290
|
-
`
|
|
1291
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1292
|
-
INSERT INTO testje (id, name) VALUES (1, 'hello') RETURNING id;
|
|
1293
|
-
$$ LANGUAGE sql;
|
|
1294
|
-
`,
|
|
1295
|
-
{
|
|
1296
|
-
kind: "set",
|
|
1297
|
-
fields: [
|
|
1298
|
-
{
|
|
1299
|
-
name: { name: "id" },
|
|
1300
|
-
type: BuiltinTypes.Integer,
|
|
1301
|
-
},
|
|
1302
|
-
],
|
|
1303
|
-
}
|
|
1304
|
-
);
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
@Test()
|
|
1308
|
-
public default_() {
|
|
1309
|
-
expectReturnType(
|
|
1310
|
-
"create table testje ( id int NOT NULL default 5, name text);",
|
|
1311
|
-
`
|
|
1312
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1313
|
-
INSERT INTO testje (id, name) VALUES (default, 'hello') RETURNING id;
|
|
1314
|
-
$$ LANGUAGE sql;
|
|
1315
|
-
`,
|
|
1316
|
-
{
|
|
1317
|
-
kind: "set",
|
|
1318
|
-
fields: [
|
|
1319
|
-
{
|
|
1320
|
-
name: { name: "id" },
|
|
1321
|
-
type: BuiltinTypes.Integer,
|
|
1322
|
-
},
|
|
1323
|
-
],
|
|
1324
|
-
}
|
|
1325
|
-
);
|
|
1326
|
-
}
|
|
1327
|
-
|
|
1328
|
-
@Test()
|
|
1329
|
-
public with() {
|
|
1330
|
-
expectReturnType(
|
|
1331
|
-
"create table testje ( id int NOT NULL);",
|
|
1332
|
-
`
|
|
1333
|
-
CREATE FUNCTION myselect() RETURNS SETOF AS $$
|
|
1334
|
-
WITH mycte AS (
|
|
1335
|
-
SELECT id from testje
|
|
1336
|
-
)
|
|
1337
|
-
SELECT * from mycte
|
|
1338
|
-
$$ LANGUAGE sql;
|
|
1339
|
-
`,
|
|
1340
|
-
{
|
|
1341
|
-
kind: "set",
|
|
1342
|
-
fields: [{ name: { name: "id" }, type: BuiltinTypes.Integer }],
|
|
1343
|
-
}
|
|
1344
|
-
);
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
|
-
@Test()
|
|
1348
|
-
public delete_() {
|
|
1349
|
-
expectReturnType(
|
|
1350
|
-
"create table testje ( id int NOT NULL);",
|
|
1351
|
-
`
|
|
1352
|
-
CREATE FUNCTION mydelete() RETURNS SETOF AS $$
|
|
1353
|
-
DELETE FROM testje
|
|
1354
|
-
WHERE id = 5
|
|
1355
|
-
RETURNING id
|
|
1356
|
-
$$ LANGUAGE sql;
|
|
1357
|
-
`,
|
|
1358
|
-
{
|
|
1359
|
-
kind: "set",
|
|
1360
|
-
fields: [{ name: { name: "id" }, type: BuiltinTypes.Integer }],
|
|
1361
|
-
}
|
|
1362
|
-
);
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
|
-
@Test()
|
|
1366
|
-
public deleteError() {
|
|
1367
|
-
expectThrowLike(
|
|
1368
|
-
"create table testje ( id int NOT NULL);",
|
|
1369
|
-
`
|
|
1370
|
-
CREATE FUNCTION mydelete() RETURNS SETOF AS $$
|
|
1371
|
-
DELETE FROM testje
|
|
1372
|
-
WHERE id = ''
|
|
1373
|
-
$$ LANGUAGE sql;
|
|
1374
|
-
`,
|
|
1375
|
-
"Can't apply operator"
|
|
1376
|
-
);
|
|
1377
|
-
}
|
|
1378
|
-
}
|