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/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
- }