typesql-cli 0.10.6 → 0.10.7

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.
@@ -406,433 +406,8 @@ function traverse_table_or_subquery(table_or_subquery_list, join_constraint_list
406
406
  function traverse_expr(expr, traverseContext) {
407
407
  var _a, _b;
408
408
  const function_name = (_a = expr.function_name()) === null || _a === void 0 ? void 0 : _a.getText().toLowerCase();
409
- if (function_name === 'avg') {
410
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'REAL');
411
- const sumParamExpr = expr.expr(0);
412
- const paramType = traverse_expr(sumParamExpr, traverseContext);
413
- if (paramType.type.kind === 'TypeVar') {
414
- functionType.table = paramType.table;
415
- }
416
- return {
417
- name: functionType.name,
418
- type: functionType,
419
- notNull: paramType.notNull,
420
- table: functionType.table || ''
421
- };
422
- }
423
- if (function_name === 'sum') {
424
- const sumParamExpr = expr.expr(0);
425
- const paramType = traverse_expr(sumParamExpr, traverseContext);
426
- return {
427
- name: expr.getText(),
428
- type: paramType.type,
429
- notNull: false,
430
- table: paramType.table || ''
431
- };
432
- }
433
- if (function_name === 'min' || function_name === 'max') {
434
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
435
- let paramNotNull = false;
436
- expr.expr_list().forEach((exprParam, index, array) => {
437
- const paramType = traverse_expr(exprParam, traverseContext);
438
- if (array.length == 1 && index == 0) {
439
- paramNotNull = paramType.notNull;
440
- }
441
- traverseContext.constraints.push({
442
- expression: expr.getText(),
443
- type1: functionType,
444
- type2: paramType.type
445
- });
446
- });
447
- return {
448
- name: functionType.name,
449
- type: functionType,
450
- notNull: paramNotNull,
451
- table: functionType.table || ''
452
- };
453
- }
454
- if (function_name === 'count') {
455
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
456
- if (expr.expr_list().length === 1) {
457
- const sumParamExpr = expr.expr(0);
458
- const paramType = traverse_expr(sumParamExpr, traverseContext);
459
- if (paramType.type.kind === 'TypeVar') {
460
- functionType.table = paramType.table;
461
- }
462
- }
463
- return {
464
- name: functionType.name,
465
- type: functionType,
466
- notNull: true,
467
- table: functionType.table || ''
468
- };
469
- }
470
- if (function_name === 'concat') {
471
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT');
472
- expr.expr_list().forEach((paramExpr) => {
473
- const paramType = traverse_expr(paramExpr, traverseContext);
474
- traverseContext.constraints.push({
475
- expression: expr.getText(),
476
- type1: functionType,
477
- type2: paramType.type
478
- });
479
- if (paramType.type.kind === 'TypeVar') {
480
- functionType.table = paramType.table;
481
- }
482
- });
483
- return {
484
- name: functionType.name,
485
- type: functionType,
486
- notNull: true,
487
- table: functionType.table || ''
488
- };
489
- }
490
- if (function_name === 'length') {
491
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
492
- const paramExpr = expr.expr(0);
493
- const paramType = traverse_expr(paramExpr, traverseContext);
494
- traverseContext.constraints.push({
495
- expression: expr.getText(),
496
- type1: (0, collect_constraints_1.freshVar)(expr.getText(), '?'), //str or blob
497
- type2: paramType.type
498
- });
499
- if (paramType.type.kind === 'TypeVar') {
500
- functionType.table = paramType.table;
501
- }
502
- return {
503
- name: functionType.name,
504
- type: functionType,
505
- notNull: false,
506
- table: functionType.table || ''
507
- };
508
- }
509
- if (function_name === 'group_concat') {
510
- expr.expr_list().forEach((paramExpr) => {
511
- const param1Type = traverse_expr(paramExpr, traverseContext);
512
- traverseContext.constraints.push({
513
- expression: expr.getText(),
514
- type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT'),
515
- type2: param1Type.type
516
- });
517
- });
518
- return {
519
- name: expr.getText(),
520
- type: (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT'),
521
- notNull: false,
522
- table: ''
523
- };
524
- }
525
- if (function_name === 'random') {
526
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
527
- return {
528
- name: functionType.name,
529
- type: functionType,
530
- notNull: true,
531
- table: ''
532
- };
533
- }
534
- if (function_name === 'round') {
535
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'REAL');
536
- const param1Expr = expr.expr(0);
537
- const param1Type = traverse_expr(param1Expr, traverseContext);
538
- traverseContext.constraints.push({
539
- expression: expr.getText(),
540
- type1: functionType,
541
- type2: param1Type.type
542
- });
543
- const param2Expr = expr.expr(1);
544
- if (param2Expr) {
545
- const param2Type = traverse_expr(param2Expr, traverseContext);
546
- traverseContext.constraints.push({
547
- expression: expr.getText(),
548
- type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER'),
549
- type2: param2Type.type
550
- });
551
- }
552
- return {
553
- name: functionType.name,
554
- type: functionType,
555
- notNull: param1Type.notNull,
556
- table: param1Type.table || ''
557
- };
558
- }
559
- if (function_name === 'coalesce') {
560
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
561
- const paramTypes = expr.expr_list().map((paramExpr) => {
562
- const paramType = traverse_expr(paramExpr, traverseContext);
563
- traverseContext.constraints.push({
564
- expression: expr.getText(),
565
- type1: functionType,
566
- type2: paramType.type
567
- });
568
- return paramType;
569
- });
570
- return {
571
- name: functionType.name,
572
- type: functionType,
573
- notNull: paramTypes.some((param) => param.notNull),
574
- table: functionType.table || ''
575
- };
576
- }
577
- if (function_name === 'strftime') {
578
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT');
579
- const paramExpr = expr.expr(1);
580
- const paramType = traverse_expr(paramExpr, traverseContext);
581
- paramType.notNull = true;
582
- traverseContext.constraints.push({
583
- expression: paramExpr.getText(),
584
- type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), 'DATE_TIME'),
585
- type2: paramType.type
586
- });
587
- return {
588
- name: functionType.name,
589
- type: functionType,
590
- notNull: false,
591
- table: functionType.table || ''
592
- };
593
- }
594
- if (function_name === 'date' || function_name === 'time' || function_name === 'datetime') {
595
- const dateType = function_name === 'date' ? 'DATE' : 'DATE_TIME';
596
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), dateType);
597
- const param1 = traverse_expr(expr.expr(0), traverseContext);
598
- param1.notNull = true;
599
- expr.expr_list().forEach((paramExpr, index, arr) => {
600
- if (index === 0 && arr.length === 1) {
601
- traverseContext.constraints.push({
602
- expression: paramExpr.getText(),
603
- type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), dateType),
604
- type2: param1.type
605
- });
606
- }
607
- else if (index > 0) {
608
- const paramType = traverse_expr(paramExpr, traverseContext);
609
- if (index === 1) {
610
- if (paramType.name === "'auto'" || paramType.name === "'unixepoch'") {
611
- traverseContext.constraints.push({
612
- expression: paramExpr.getText(),
613
- type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), 'NUMERIC'),
614
- type2: param1.type
615
- });
616
- }
617
- }
618
- traverseContext.constraints.push({
619
- expression: paramExpr.getText(),
620
- type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), 'TEXT'),
621
- type2: paramType.type
622
- });
623
- }
624
- });
625
- return {
626
- name: functionType.name,
627
- type: functionType,
628
- notNull: false,
629
- table: functionType.table || ''
630
- };
631
- }
632
- if (function_name === 'julianday') {
633
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'REAL');
634
- const paramExpr = expr.expr(0);
635
- const notNull = paramExpr.getText().toLowerCase() === `'now'`;
636
- const paramType = traverse_expr(paramExpr, traverseContext);
637
- traverseContext.constraints.push({
638
- expression: paramExpr.getText(),
639
- type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), 'DATE'),
640
- type2: paramType.type
641
- });
642
- return {
643
- name: functionType.name,
644
- type: functionType,
645
- notNull,
646
- table: functionType.table || ''
647
- };
648
- }
649
- if (function_name === 'unixepoch') {
650
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
651
- const paramExpr = expr.expr(0);
652
- const notNull = paramExpr.getText().toLowerCase() === `'now'`;
653
- const paramType = traverse_expr(paramExpr, traverseContext);
654
- traverseContext.constraints.push({
655
- expression: paramExpr.getText(),
656
- type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), 'DATE'),
657
- type2: paramType.type
658
- });
659
- return {
660
- name: functionType.name,
661
- type: functionType,
662
- notNull,
663
- table: functionType.table || ''
664
- };
665
- }
666
- if (function_name === 'ifnull') {
667
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
668
- const paramTypes = expr.expr_list().map((paramExpr) => {
669
- const paramType = traverse_expr(paramExpr, traverseContext);
670
- if (paramType.name === '?') {
671
- paramType.notNull = false;
672
- }
673
- traverseContext.constraints.push({
674
- expression: expr.getText(),
675
- type1: functionType,
676
- type2: paramType.type
677
- });
678
- return paramType;
679
- });
680
- return {
681
- name: functionType.name,
682
- type: functionType,
683
- notNull: paramTypes.every((param) => param.notNull),
684
- table: functionType.table || ''
685
- };
686
- }
687
- if (function_name === 'row_number' || function_name === 'rank' || function_name === 'dense_rank') {
688
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
689
- return {
690
- name: functionType.name,
691
- type: functionType,
692
- notNull: true,
693
- table: functionType.table || ''
694
- };
695
- }
696
- if (function_name === 'first_value' || function_name === 'last_value') {
697
- const paramExpr = expr.expr(0);
698
- const paramType = traverse_expr(paramExpr, traverseContext);
699
- return paramType;
700
- }
701
- if (function_name === 'lead' || function_name === 'lag') {
702
- const paramExpr = expr.expr(0);
703
- const paramType = traverse_expr(paramExpr, traverseContext);
704
- return Object.assign(Object.assign({}, paramType), { notNull: false });
705
- }
706
- if (function_name === 'iif') {
707
- const expr1 = expr.expr(0);
708
- traverse_expr(expr1, traverseContext);
709
- const expr2 = expr.expr(1);
710
- const expr2Type = traverse_expr(expr2, traverseContext);
711
- const expr3 = expr.expr(2);
712
- const expr3Type = traverse_expr(expr3, traverseContext);
713
- traverseContext.constraints.push({
714
- expression: expr.getText(),
715
- type1: expr2Type.type,
716
- type2: expr3Type.type
717
- });
718
- return Object.assign(Object.assign({}, expr2Type), { notNull: expr2Type.notNull && expr3Type.notNull });
719
- }
720
- if (function_name === 'vector') {
721
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'BLOB');
722
- const param1Expr = expr.expr(0);
723
- const param1Type = traverse_expr(param1Expr, traverseContext);
724
- param1Type.notNull = true;
725
- traverseContext.constraints.push({
726
- expression: expr.getText(),
727
- type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT'),
728
- type2: param1Type.type
729
- });
730
- return {
731
- name: expr.getText(),
732
- type: functionType,
733
- notNull: true,
734
- table: ''
735
- };
736
- }
737
- if (function_name === 'highlight' || function_name === 'snippet') {
738
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT');
739
- const param0Expr = expr.expr(0);
740
- const param1Expr = expr.expr(1);
741
- const param1Type = traverse_expr(param1Expr, traverseContext);
742
- param1Type.notNull = true;
743
- traverseContext.constraints.push({
744
- expression: param1Expr.getText(),
745
- type1: (0, collect_constraints_1.freshVar)(param1Expr.getText(), 'INTEGER'),
746
- type2: param1Type.type
747
- });
748
- const param2Expr = expr.expr(2);
749
- const param2Type = traverse_expr(param2Expr, traverseContext);
750
- param2Type.notNull = true;
751
- traverseContext.constraints.push({
752
- expression: param2Expr.getText(),
753
- type1: (0, collect_constraints_1.freshVar)(param2Expr.getText(), 'TEXT'),
754
- type2: param2Type.type
755
- });
756
- const param3Expr = expr.expr(3);
757
- const param3Type = traverse_expr(param3Expr, traverseContext);
758
- param3Type.notNull = true;
759
- traverseContext.constraints.push({
760
- expression: param3Expr.getText(),
761
- type1: (0, collect_constraints_1.freshVar)(param3Expr.getText(), 'TEXT'),
762
- type2: param3Type.type
763
- });
764
- if (function_name === 'snippet') {
765
- const param4Expr = expr.expr(4);
766
- const param4Type = traverse_expr(param4Expr, traverseContext);
767
- param4Type.notNull = true;
768
- traverseContext.constraints.push({
769
- expression: param4Expr.getText(),
770
- type1: (0, collect_constraints_1.freshVar)(param4Expr.getText(), 'TEXT'),
771
- type2: param4Type.type
772
- });
773
- const param5Expr = expr.expr(5);
774
- const param5Type = traverse_expr(param5Expr, traverseContext);
775
- param5Type.notNull = true;
776
- traverseContext.constraints.push({
777
- expression: param5Expr.getText(),
778
- type1: (0, collect_constraints_1.freshVar)(param5Expr.getText(), 'INTEGER'),
779
- type2: param5Type.type
780
- });
781
- }
782
- return {
783
- name: expr.getText(),
784
- type: functionType,
785
- notNull: false,
786
- table: param0Expr.getText()
787
- };
788
- }
789
- if (function_name === 'vector_extract') {
790
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT');
791
- const param1Expr = expr.expr(0);
792
- const param1Type = traverse_expr(param1Expr, traverseContext);
793
- traverseContext.constraints.push({
794
- expression: expr.getText(),
795
- type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'BLOB'),
796
- type2: param1Type.type
797
- });
798
- return {
799
- name: expr.getText(),
800
- type: functionType,
801
- notNull: true,
802
- table: ''
803
- };
804
- }
805
- if (function_name === 'vector_distance_cos') {
806
- const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'REAL');
807
- const param1Expr = expr.expr(0);
808
- if (param1Expr) {
809
- const param1Type = traverse_expr(param1Expr, traverseContext);
810
- param1Type.notNull = true;
811
- traverseContext.constraints.push({
812
- expression: expr.getText(),
813
- type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'BLOB'),
814
- type2: param1Type.type
815
- });
816
- }
817
- const param2Expr = expr.expr(1);
818
- if (param2Expr) {
819
- const param2Type = traverse_expr(param2Expr, traverseContext);
820
- param2Type.notNull = true;
821
- traverseContext.constraints.push({
822
- expression: expr.getText(),
823
- type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT'),
824
- type2: param2Type.type
825
- });
826
- }
827
- return {
828
- name: expr.getText(),
829
- type: functionType,
830
- notNull: true,
831
- table: ''
832
- };
833
- }
834
409
  if (function_name) {
835
- throw Error(`traverse_expr: function not supported:${function_name}`);
410
+ return traverse_function(expr, function_name, traverseContext);
836
411
  }
837
412
  const column_name = expr.column_name();
838
413
  const table_name = expr.table_name();
@@ -865,374 +440,840 @@ function traverse_expr(expr, traverseContext) {
865
440
  table: type.table || ''
866
441
  };
867
442
  }
868
- if (literal.TRUE_() || literal.FALSE_()) {
869
- const type = (0, collect_constraints_1.freshVar)(literal.getText(), 'BOOLEAN');
870
- return {
871
- name: type.name,
872
- type: type,
873
- notNull: true,
874
- table: type.table || ''
875
- };
443
+ if (literal.TRUE_() || literal.FALSE_()) {
444
+ const type = (0, collect_constraints_1.freshVar)(literal.getText(), 'BOOLEAN');
445
+ return {
446
+ name: type.name,
447
+ type: type,
448
+ notNull: true,
449
+ table: type.table || ''
450
+ };
451
+ }
452
+ const type = (0, collect_constraints_1.freshVar)(literal.getText(), '?');
453
+ return {
454
+ name: type.name,
455
+ type: type,
456
+ notNull: literal.NULL_() == null,
457
+ table: type.table || ''
458
+ };
459
+ }
460
+ if (expr.unary_operator()) {
461
+ const exprRight = expr.expr(0);
462
+ return traverse_expr(exprRight, traverseContext);
463
+ }
464
+ const parameter = expr.BIND_PARAMETER();
465
+ if (parameter) {
466
+ const param = (0, collect_constraints_1.freshVar)('?', '?');
467
+ const type = {
468
+ name: param.name,
469
+ type: param,
470
+ notNull: undefined,
471
+ table: param.table || '',
472
+ paramIndex: parameter.symbol.start
473
+ };
474
+ traverseContext.parameters.push(type);
475
+ return type;
476
+ }
477
+ if (expr.STAR() || expr.DIV() || expr.MOD()) {
478
+ const exprLeft = expr.expr(0);
479
+ const exprRight = expr.expr(1);
480
+ const typeLeft = traverse_expr(exprLeft, traverseContext);
481
+ const typeRight = traverse_expr(exprRight, traverseContext);
482
+ const returnType = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
483
+ traverseContext.constraints.push({
484
+ expression: expr.getText(),
485
+ type1: typeLeft.type,
486
+ type2: returnType
487
+ });
488
+ traverseContext.constraints.push({
489
+ expression: expr.getText(),
490
+ type1: typeRight.type,
491
+ type2: returnType
492
+ });
493
+ return {
494
+ name: returnType.name,
495
+ type: returnType,
496
+ notNull: typeLeft.notNull && typeRight.notNull,
497
+ table: returnType.table || ''
498
+ };
499
+ }
500
+ if (expr.PLUS() || expr.MINUS()) {
501
+ const returnType = (0, collect_constraints_1.freshVar)(expr.getText(), 'REAL'); //NUMERIC
502
+ const exprLeft = expr.expr(0);
503
+ const exprRight = expr.expr(1);
504
+ const typeLeft = traverse_expr(exprLeft, traverseContext);
505
+ const typeRight = traverse_expr(exprRight, traverseContext);
506
+ typeLeft.table = '';
507
+ typeRight.table = '';
508
+ traverseContext.constraints.push({
509
+ expression: exprLeft.getText(),
510
+ type1: returnType,
511
+ type2: typeLeft.type
512
+ });
513
+ const isDateFunctionContext = expr.parentCtx instanceof sqlite_1.ExprContext && ((_b = expr.parentCtx.function_name()) === null || _b === void 0 ? void 0 : _b.getText().toLowerCase()) === 'date';
514
+ if (!isDateFunctionContext) {
515
+ traverseContext.constraints.push({
516
+ expression: exprRight.getText(),
517
+ type1: returnType,
518
+ type2: typeRight.type
519
+ });
520
+ }
521
+ return Object.assign(Object.assign({}, typeLeft), { notNull: typeLeft.notNull && typeRight.notNull });
522
+ }
523
+ if (expr.LT2() ||
524
+ expr.GT2() ||
525
+ expr.AMP() ||
526
+ expr.PIPE() ||
527
+ expr.LT() ||
528
+ expr.LT_EQ() ||
529
+ expr.GT() ||
530
+ expr.GT_EQ() ||
531
+ expr.NOT_EQ1() ||
532
+ expr.NOT_EQ2()) {
533
+ const exprLeft = expr.expr(0);
534
+ const exprRight = expr.expr(1);
535
+ const typeLeft = traverse_expr(exprLeft, traverseContext);
536
+ const typeRight = traverse_expr(exprRight, traverseContext);
537
+ if (typeLeft.name === '?') {
538
+ typeLeft.notNull = true;
539
+ }
540
+ if (typeRight.name === '?') {
541
+ typeRight.notNull = true;
542
+ }
543
+ traverseContext.constraints.push({
544
+ expression: expr.getText(),
545
+ type1: typeLeft.type,
546
+ type2: typeRight.type
547
+ });
548
+ const resultType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
549
+ return {
550
+ name: resultType.name,
551
+ type: resultType,
552
+ notNull: true,
553
+ table: resultType.table || ''
554
+ };
555
+ }
556
+ if (expr.IS_()) {
557
+ //is null/is not null/is true, is false
558
+ const exprLeft = expr.expr(0);
559
+ const typeLeft = traverse_expr(exprLeft, traverseContext);
560
+ const exprRight = expr.expr(1);
561
+ const typeRight = traverse_expr(exprRight, traverseContext);
562
+ typeLeft.notNull = typeRight.notNull;
563
+ traverseContext.constraints.push({
564
+ expression: expr.getText(),
565
+ type1: typeLeft.type,
566
+ type2: typeRight.type
567
+ });
568
+ const type = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
569
+ return {
570
+ name: type.name,
571
+ type: type,
572
+ notNull: true,
573
+ table: type.table || ''
574
+ };
575
+ }
576
+ if (expr.ASSIGN()) {
577
+ //=
578
+ const exprLeft = expr.expr(0);
579
+ const exprRight = expr.expr(1);
580
+ const typeLeft = traverse_expr(exprLeft, traverseContext);
581
+ const typeRight = traverse_expr(exprRight, traverseContext);
582
+ if (typeLeft.name === '?') {
583
+ typeLeft.notNull = true;
584
+ }
585
+ if (typeRight.name === '?') {
586
+ typeRight.notNull = true;
587
+ }
588
+ traverseContext.constraints.push({
589
+ expression: expr.getText(),
590
+ type1: typeLeft.type,
591
+ type2: typeRight.type
592
+ });
593
+ const type = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
594
+ return {
595
+ name: type.name,
596
+ type: type,
597
+ notNull: true,
598
+ table: type.table || ''
599
+ };
600
+ }
601
+ if (expr.BETWEEN_()) {
602
+ const exprType = traverse_expr(expr.expr(0), traverseContext);
603
+ const between1 = traverse_expr(expr.expr(1), traverseContext);
604
+ const between2 = traverse_expr(expr.expr(2), traverseContext);
605
+ if (between1.name === '?') {
606
+ between1.notNull = true;
607
+ }
608
+ if (between2.name === '?') {
609
+ between2.notNull = true;
610
+ }
611
+ traverseContext.constraints.push({
612
+ expression: expr.getText(),
613
+ type1: exprType.type,
614
+ type2: between1.type
615
+ });
616
+ traverseContext.constraints.push({
617
+ expression: expr.getText(),
618
+ type1: exprType.type,
619
+ type2: between2.type
620
+ });
621
+ traverseContext.constraints.push({
622
+ expression: expr.getText(),
623
+ type1: between1.type,
624
+ type2: between2.type
625
+ });
626
+ return exprType;
627
+ }
628
+ if (expr.OR_() || expr.AND_()) {
629
+ const expr1 = expr.expr(0);
630
+ const expr2 = expr.expr(1);
631
+ traverse_expr(expr1, traverseContext);
632
+ return traverse_expr(expr2, traverseContext);
633
+ }
634
+ if (expr.IN_()) {
635
+ const exprList = expr.expr_list();
636
+ const inExprLeft = exprList[0];
637
+ const typeLeft = traverse_expr(inExprLeft, traverseContext);
638
+ if (typeLeft.name === '?') {
639
+ typeLeft.notNull = true;
640
+ }
641
+ if (expr.NOT_()) {
642
+ //NOT IN (SELECT...)
643
+ const select_stmt = expr.select_stmt();
644
+ if (select_stmt) {
645
+ const select_stmt_type = traverse_select_stmt(select_stmt, traverseContext, true);
646
+ const selectType = select_stmt_type.columns[0];
647
+ traverseContext.constraints.push({
648
+ expression: expr.getText(),
649
+ type1: typeLeft.type,
650
+ type2: Object.assign(Object.assign({}, selectType.type), { list: true })
651
+ });
652
+ }
653
+ //NOT IN (1, 2, 3)
654
+ exprList.slice(1).forEach((inExpr) => {
655
+ const typeRight = traverse_expr(inExpr, traverseContext);
656
+ if (typeRight.name === '?') {
657
+ typeRight.notNull = true;
658
+ }
659
+ traverseContext.constraints.push({
660
+ expression: expr.getText(),
661
+ type1: typeLeft.type,
662
+ type2: Object.assign(Object.assign({}, typeRight.type), { list: true })
663
+ });
664
+ });
665
+ }
666
+ else {
667
+ const rightExpr = exprList[1];
668
+ //IN (SELECT...)
669
+ const select_stmt2 = rightExpr.select_stmt();
670
+ if (select_stmt2) {
671
+ const select_stmt_type = traverse_select_stmt(select_stmt2, traverseContext, true);
672
+ const selectType2 = select_stmt_type.columns[0];
673
+ traverseContext.constraints.push({
674
+ expression: expr.getText(),
675
+ type1: typeLeft.type,
676
+ type2: Object.assign(Object.assign({}, selectType2.type), { list: true })
677
+ });
678
+ }
679
+ //IN (1, 2, 3)
680
+ rightExpr.expr_list().forEach((inExpr2) => {
681
+ const typeRight = traverse_expr(inExpr2, traverseContext);
682
+ if (typeRight.name === '?') {
683
+ typeRight.notNull = true;
684
+ }
685
+ traverseContext.constraints.push({
686
+ expression: expr.getText(),
687
+ type1: typeLeft.type,
688
+ type2: Object.assign(Object.assign({}, typeRight.type), { list: true })
689
+ });
690
+ });
876
691
  }
877
- const type = (0, collect_constraints_1.freshVar)(literal.getText(), '?');
692
+ const type = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
878
693
  return {
879
694
  name: type.name,
880
695
  type: type,
881
- notNull: literal.NULL_() == null,
696
+ notNull: true,
882
697
  table: type.table || ''
883
698
  };
884
699
  }
885
- if (expr.unary_operator()) {
886
- const exprRight = expr.expr(0);
887
- return traverse_expr(exprRight, traverseContext);
888
- }
889
- const parameter = expr.BIND_PARAMETER();
890
- if (parameter) {
891
- const param = (0, collect_constraints_1.freshVar)('?', '?');
892
- const type = {
893
- name: param.name,
894
- type: param,
895
- notNull: undefined,
896
- table: param.table || '',
897
- paramIndex: parameter.symbol.start
898
- };
899
- traverseContext.parameters.push(type);
900
- return type;
901
- }
902
- if (expr.STAR() || expr.DIV() || expr.MOD()) {
700
+ if (expr.LIKE_() || expr.GLOB_()) {
903
701
  const exprLeft = expr.expr(0);
904
702
  const exprRight = expr.expr(1);
905
703
  const typeLeft = traverse_expr(exprLeft, traverseContext);
906
704
  const typeRight = traverse_expr(exprRight, traverseContext);
907
- const returnType = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
705
+ if (typeLeft.name === '?') {
706
+ typeLeft.notNull = true;
707
+ }
708
+ if (typeRight.name === '?') {
709
+ typeRight.notNull = true;
710
+ }
908
711
  traverseContext.constraints.push({
909
712
  expression: expr.getText(),
910
713
  type1: typeLeft.type,
911
- type2: returnType
714
+ type2: typeRight.type
912
715
  });
913
716
  traverseContext.constraints.push({
914
717
  expression: expr.getText(),
915
- type1: typeRight.type,
916
- type2: returnType
718
+ type1: typeLeft.type,
719
+ type2: (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT')
917
720
  });
721
+ const type = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
918
722
  return {
919
- name: returnType.name,
920
- type: returnType,
921
- notNull: typeLeft.notNull && typeRight.notNull,
922
- table: returnType.table || ''
723
+ name: type.name,
724
+ type: type,
725
+ notNull: true,
726
+ table: type.table || ''
923
727
  };
924
728
  }
925
- if (expr.PLUS() || expr.MINUS()) {
926
- const returnType = (0, collect_constraints_1.freshVar)(expr.getText(), 'REAL'); //NUMERIC
729
+ if (expr.MATCH_()) {
927
730
  const exprLeft = expr.expr(0);
928
731
  const exprRight = expr.expr(1);
929
- const typeLeft = traverse_expr(exprLeft, traverseContext);
930
732
  const typeRight = traverse_expr(exprRight, traverseContext);
931
- typeLeft.table = '';
932
- typeRight.table = '';
933
- traverseContext.constraints.push({
934
- expression: exprLeft.getText(),
935
- type1: returnType,
936
- type2: typeLeft.type
733
+ if (typeRight.name === '?') {
734
+ typeRight.notNull = true;
735
+ typeRight.type = (0, collect_constraints_1.freshVar)(exprRight.getText(), 'TEXT');
736
+ }
737
+ const type = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
738
+ return {
739
+ name: type.name,
740
+ type: type,
741
+ notNull: true,
742
+ table: type.table || ''
743
+ };
744
+ }
745
+ const select_stmt = expr.select_stmt();
746
+ if (select_stmt) {
747
+ const subQueryType = traverse_select_stmt(select_stmt, Object.assign(Object.assign({}, traverseContext), { subQuery: true }), true);
748
+ const type = Object.assign(Object.assign({}, subQueryType.columns[0].type), { table: '' });
749
+ return {
750
+ name: type.name,
751
+ type: type,
752
+ notNull: subQueryType.columns[0].notNull,
753
+ table: type.table || ''
754
+ };
755
+ }
756
+ if (expr.OPEN_PAR() && expr.CLOSE_PAR()) {
757
+ const type = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
758
+ const exprTypes = expr.expr_list().map((innerExpr) => {
759
+ const exprType = traverse_expr(innerExpr, traverseContext);
760
+ traverseContext.constraints.push({
761
+ expression: innerExpr.getText(),
762
+ type1: exprType.type,
763
+ type2: type
764
+ });
765
+ return exprType;
937
766
  });
938
- const isDateFunctionContext = expr.parentCtx instanceof sqlite_1.ExprContext && ((_b = expr.parentCtx.function_name()) === null || _b === void 0 ? void 0 : _b.getText().toLowerCase()) === 'date';
939
- if (!isDateFunctionContext) {
767
+ return {
768
+ name: type.name,
769
+ type: type,
770
+ notNull: exprTypes.every((type) => type.notNull),
771
+ table: type.table || ''
772
+ };
773
+ }
774
+ if (expr.CASE_()) {
775
+ const resultTypes = []; //then and else
776
+ const whenTypes = [];
777
+ expr.expr_list().forEach((expr_, index) => {
778
+ const type = traverse_expr(expr_, traverseContext);
779
+ if (index % 2 === 0 && (!expr.ELSE_() || index < expr.expr_list().length - 1)) {
780
+ whenTypes.push(type);
781
+ }
782
+ else {
783
+ resultTypes.push(type);
784
+ }
785
+ });
786
+ resultTypes.forEach((resultType, index) => {
787
+ if (index > 0) {
788
+ traverseContext.constraints.push({
789
+ expression: expr.getText(),
790
+ type1: resultTypes[0].type,
791
+ type2: resultType.type
792
+ });
793
+ }
794
+ });
795
+ whenTypes.forEach((whenType) => {
940
796
  traverseContext.constraints.push({
941
- expression: exprRight.getText(),
942
- type1: returnType,
943
- type2: typeRight.type
797
+ expression: expr.getText(),
798
+ type1: (0, collect_constraints_1.freshVar)('INTEGER', 'INTEGER'),
799
+ type2: whenType.type
944
800
  });
945
- }
946
- return Object.assign(Object.assign({}, typeLeft), { notNull: typeLeft.notNull && typeRight.notNull });
801
+ });
802
+ const type = resultTypes[0];
803
+ return {
804
+ name: extractOriginalSql(expr),
805
+ type: type.type,
806
+ notNull: expr.ELSE_() ? resultTypes.every((type) => type.notNull) : false,
807
+ table: type.table || ''
808
+ };
947
809
  }
948
- if (expr.LT2() ||
949
- expr.GT2() ||
950
- expr.AMP() ||
951
- expr.PIPE() ||
952
- expr.LT() ||
953
- expr.LT_EQ() ||
954
- expr.GT() ||
955
- expr.GT_EQ() ||
956
- expr.NOT_EQ1() ||
957
- expr.NOT_EQ2()) {
958
- const exprLeft = expr.expr(0);
959
- const exprRight = expr.expr(1);
960
- const typeLeft = traverse_expr(exprLeft, traverseContext);
961
- const typeRight = traverse_expr(exprRight, traverseContext);
962
- if (typeLeft.name === '?') {
963
- typeLeft.notNull = true;
810
+ throw Error(`traverse_expr not supported:${expr.getText()}`);
811
+ }
812
+ function traverse_function(expr, function_name, traverseContext) {
813
+ if (function_name === 'avg') {
814
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'REAL');
815
+ const sumParamExpr = expr.expr(0);
816
+ const paramType = traverse_expr(sumParamExpr, traverseContext);
817
+ if (paramType.type.kind === 'TypeVar') {
818
+ functionType.table = paramType.table;
964
819
  }
965
- if (typeRight.name === '?') {
966
- typeRight.notNull = true;
820
+ return {
821
+ name: functionType.name,
822
+ type: functionType,
823
+ notNull: paramType.notNull,
824
+ table: functionType.table || ''
825
+ };
826
+ }
827
+ if (function_name === 'sum') {
828
+ const sumParamExpr = expr.expr(0);
829
+ const paramType = traverse_expr(sumParamExpr, traverseContext);
830
+ return {
831
+ name: expr.getText(),
832
+ type: paramType.type,
833
+ notNull: false,
834
+ table: paramType.table || ''
835
+ };
836
+ }
837
+ if (function_name === 'min' || function_name === 'max') {
838
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
839
+ let paramNotNull = false;
840
+ expr.expr_list().forEach((exprParam, index, array) => {
841
+ const paramType = traverse_expr(exprParam, traverseContext);
842
+ if (array.length == 1 && index == 0) {
843
+ paramNotNull = paramType.notNull;
844
+ }
845
+ traverseContext.constraints.push({
846
+ expression: expr.getText(),
847
+ type1: functionType,
848
+ type2: paramType.type
849
+ });
850
+ });
851
+ return {
852
+ name: functionType.name,
853
+ type: functionType,
854
+ notNull: paramNotNull,
855
+ table: functionType.table || ''
856
+ };
857
+ }
858
+ if (function_name === 'count') {
859
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
860
+ if (expr.expr_list().length === 1) {
861
+ const sumParamExpr = expr.expr(0);
862
+ const paramType = traverse_expr(sumParamExpr, traverseContext);
863
+ if (paramType.type.kind === 'TypeVar') {
864
+ functionType.table = paramType.table;
865
+ }
967
866
  }
968
- traverseContext.constraints.push({
969
- expression: expr.getText(),
970
- type1: typeLeft.type,
971
- type2: typeRight.type
867
+ return {
868
+ name: functionType.name,
869
+ type: functionType,
870
+ notNull: true,
871
+ table: functionType.table || ''
872
+ };
873
+ }
874
+ if (function_name === 'concat') {
875
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT');
876
+ expr.expr_list().forEach((paramExpr) => {
877
+ const paramType = traverse_expr(paramExpr, traverseContext);
878
+ traverseContext.constraints.push({
879
+ expression: expr.getText(),
880
+ type1: functionType,
881
+ type2: paramType.type
882
+ });
883
+ if (paramType.type.kind === 'TypeVar') {
884
+ functionType.table = paramType.table;
885
+ }
972
886
  });
973
- const resultType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
974
887
  return {
975
- name: resultType.name,
976
- type: resultType,
888
+ name: functionType.name,
889
+ type: functionType,
977
890
  notNull: true,
978
- table: resultType.table || ''
891
+ table: functionType.table || ''
979
892
  };
980
893
  }
981
- if (expr.IS_()) {
982
- //is null/is not null/is true, is false
983
- const exprLeft = expr.expr(0);
984
- const typeLeft = traverse_expr(exprLeft, traverseContext);
985
- const exprRight = expr.expr(1);
986
- const typeRight = traverse_expr(exprRight, traverseContext);
987
- typeLeft.notNull = typeRight.notNull;
894
+ if (function_name === 'length') {
895
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
896
+ const paramExpr = expr.expr(0);
897
+ const paramType = traverse_expr(paramExpr, traverseContext);
988
898
  traverseContext.constraints.push({
989
899
  expression: expr.getText(),
990
- type1: typeLeft.type,
991
- type2: typeRight.type
900
+ type1: (0, collect_constraints_1.freshVar)(expr.getText(), '?'), //str or blob
901
+ type2: paramType.type
992
902
  });
993
- const type = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
903
+ if (paramType.type.kind === 'TypeVar') {
904
+ functionType.table = paramType.table;
905
+ }
994
906
  return {
995
- name: type.name,
996
- type: type,
997
- notNull: true,
998
- table: type.table || ''
907
+ name: functionType.name,
908
+ type: functionType,
909
+ notNull: false,
910
+ table: functionType.table || ''
999
911
  };
1000
912
  }
1001
- if (expr.ASSIGN()) {
1002
- //=
1003
- const exprLeft = expr.expr(0);
1004
- const exprRight = expr.expr(1);
1005
- const typeLeft = traverse_expr(exprLeft, traverseContext);
1006
- const typeRight = traverse_expr(exprRight, traverseContext);
1007
- if (typeLeft.name === '?') {
1008
- typeLeft.notNull = true;
1009
- }
1010
- if (typeRight.name === '?') {
1011
- typeRight.notNull = true;
1012
- }
1013
- traverseContext.constraints.push({
1014
- expression: expr.getText(),
1015
- type1: typeLeft.type,
1016
- type2: typeRight.type
913
+ if (function_name === 'group_concat') {
914
+ expr.expr_list().forEach((paramExpr) => {
915
+ const param1Type = traverse_expr(paramExpr, traverseContext);
916
+ traverseContext.constraints.push({
917
+ expression: expr.getText(),
918
+ type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT'),
919
+ type2: param1Type.type
920
+ });
1017
921
  });
1018
- const type = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
1019
922
  return {
1020
- name: type.name,
1021
- type: type,
923
+ name: expr.getText(),
924
+ type: (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT'),
925
+ notNull: false,
926
+ table: ''
927
+ };
928
+ }
929
+ if (function_name === 'random') {
930
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
931
+ return {
932
+ name: functionType.name,
933
+ type: functionType,
1022
934
  notNull: true,
1023
- table: type.table || ''
935
+ table: ''
1024
936
  };
1025
937
  }
1026
- if (expr.BETWEEN_()) {
1027
- const exprType = traverse_expr(expr.expr(0), traverseContext);
1028
- const between1 = traverse_expr(expr.expr(1), traverseContext);
1029
- const between2 = traverse_expr(expr.expr(2), traverseContext);
1030
- if (between1.name === '?') {
1031
- between1.notNull = true;
1032
- }
1033
- if (between2.name === '?') {
1034
- between2.notNull = true;
1035
- }
938
+ if (function_name === 'round') {
939
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'REAL');
940
+ const param1Expr = expr.expr(0);
941
+ const param1Type = traverse_expr(param1Expr, traverseContext);
1036
942
  traverseContext.constraints.push({
1037
943
  expression: expr.getText(),
1038
- type1: exprType.type,
1039
- type2: between1.type
944
+ type1: functionType,
945
+ type2: param1Type.type
1040
946
  });
1041
- traverseContext.constraints.push({
1042
- expression: expr.getText(),
1043
- type1: exprType.type,
1044
- type2: between2.type
947
+ const param2Expr = expr.expr(1);
948
+ if (param2Expr) {
949
+ const param2Type = traverse_expr(param2Expr, traverseContext);
950
+ traverseContext.constraints.push({
951
+ expression: expr.getText(),
952
+ type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER'),
953
+ type2: param2Type.type
954
+ });
955
+ }
956
+ return {
957
+ name: functionType.name,
958
+ type: functionType,
959
+ notNull: param1Type.notNull,
960
+ table: param1Type.table || ''
961
+ };
962
+ }
963
+ if (function_name === 'coalesce') {
964
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
965
+ const paramTypes = expr.expr_list().map((paramExpr) => {
966
+ const paramType = traverse_expr(paramExpr, traverseContext);
967
+ traverseContext.constraints.push({
968
+ expression: expr.getText(),
969
+ type1: functionType,
970
+ type2: paramType.type
971
+ });
972
+ return paramType;
1045
973
  });
974
+ return {
975
+ name: functionType.name,
976
+ type: functionType,
977
+ notNull: paramTypes.some((param) => param.notNull),
978
+ table: functionType.table || ''
979
+ };
980
+ }
981
+ if (function_name === 'strftime') {
982
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT');
983
+ const paramExpr = expr.expr(1);
984
+ const paramType = traverse_expr(paramExpr, traverseContext);
985
+ paramType.notNull = true;
1046
986
  traverseContext.constraints.push({
1047
- expression: expr.getText(),
1048
- type1: between1.type,
1049
- type2: between2.type
987
+ expression: paramExpr.getText(),
988
+ type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), 'DATE_TIME'),
989
+ type2: paramType.type
1050
990
  });
1051
- return exprType;
1052
- }
1053
- if (expr.OR_() || expr.AND_()) {
1054
- const expr1 = expr.expr(0);
1055
- const expr2 = expr.expr(1);
1056
- traverse_expr(expr1, traverseContext);
1057
- return traverse_expr(expr2, traverseContext);
991
+ return {
992
+ name: functionType.name,
993
+ type: functionType,
994
+ notNull: false,
995
+ table: functionType.table || ''
996
+ };
1058
997
  }
1059
- if (expr.IN_()) {
1060
- const exprList = expr.expr_list();
1061
- const inExprLeft = exprList[0];
1062
- const typeLeft = traverse_expr(inExprLeft, traverseContext);
1063
- if (typeLeft.name === '?') {
1064
- typeLeft.notNull = true;
1065
- }
1066
- if (expr.NOT_()) {
1067
- //NOT IN (SELECT...)
1068
- const select_stmt = expr.select_stmt();
1069
- if (select_stmt) {
1070
- const select_stmt_type = traverse_select_stmt(select_stmt, traverseContext, true);
1071
- const selectType = select_stmt_type.columns[0];
998
+ if (function_name === 'date' || function_name === 'time' || function_name === 'datetime') {
999
+ const dateType = function_name === 'date' ? 'DATE' : 'DATE_TIME';
1000
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), dateType);
1001
+ const param1 = traverse_expr(expr.expr(0), traverseContext);
1002
+ param1.notNull = true;
1003
+ expr.expr_list().forEach((paramExpr, index, arr) => {
1004
+ if (index === 0 && arr.length === 1) {
1072
1005
  traverseContext.constraints.push({
1073
- expression: expr.getText(),
1074
- type1: typeLeft.type,
1075
- type2: Object.assign(Object.assign({}, selectType.type), { list: true })
1006
+ expression: paramExpr.getText(),
1007
+ type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), dateType),
1008
+ type2: param1.type
1076
1009
  });
1077
1010
  }
1078
- //NOT IN (1, 2, 3)
1079
- exprList.slice(1).forEach((inExpr) => {
1080
- const typeRight = traverse_expr(inExpr, traverseContext);
1081
- if (typeRight.name === '?') {
1082
- typeRight.notNull = true;
1011
+ else if (index > 0) {
1012
+ const paramType = traverse_expr(paramExpr, traverseContext);
1013
+ if (index === 1) {
1014
+ if (paramType.name === "'auto'" || paramType.name === "'unixepoch'") {
1015
+ traverseContext.constraints.push({
1016
+ expression: paramExpr.getText(),
1017
+ type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), 'NUMERIC'),
1018
+ type2: param1.type
1019
+ });
1020
+ }
1083
1021
  }
1084
1022
  traverseContext.constraints.push({
1085
- expression: expr.getText(),
1086
- type1: typeLeft.type,
1087
- type2: Object.assign(Object.assign({}, typeRight.type), { list: true })
1088
- });
1089
- });
1090
- }
1091
- else {
1092
- const rightExpr = exprList[1];
1093
- //IN (SELECT...)
1094
- const select_stmt2 = rightExpr.select_stmt();
1095
- if (select_stmt2) {
1096
- const select_stmt_type = traverse_select_stmt(select_stmt2, traverseContext, true);
1097
- const selectType2 = select_stmt_type.columns[0];
1098
- traverseContext.constraints.push({
1099
- expression: expr.getText(),
1100
- type1: typeLeft.type,
1101
- type2: Object.assign(Object.assign({}, selectType2.type), { list: true })
1023
+ expression: paramExpr.getText(),
1024
+ type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), 'TEXT'),
1025
+ type2: paramType.type
1102
1026
  });
1103
1027
  }
1104
- //IN (1, 2, 3)
1105
- rightExpr.expr_list().forEach((inExpr2) => {
1106
- const typeRight = traverse_expr(inExpr2, traverseContext);
1107
- if (typeRight.name === '?') {
1108
- typeRight.notNull = true;
1109
- }
1110
- traverseContext.constraints.push({
1111
- expression: expr.getText(),
1112
- type1: typeLeft.type,
1113
- type2: Object.assign(Object.assign({}, typeRight.type), { list: true })
1114
- });
1028
+ });
1029
+ return {
1030
+ name: functionType.name,
1031
+ type: functionType,
1032
+ notNull: false,
1033
+ table: functionType.table || ''
1034
+ };
1035
+ }
1036
+ if (function_name === 'julianday') {
1037
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'REAL');
1038
+ const paramExpr = expr.expr(0);
1039
+ const notNull = paramExpr.getText().toLowerCase() === `'now'`;
1040
+ const paramType = traverse_expr(paramExpr, traverseContext);
1041
+ traverseContext.constraints.push({
1042
+ expression: paramExpr.getText(),
1043
+ type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), 'DATE'),
1044
+ type2: paramType.type
1045
+ });
1046
+ return {
1047
+ name: functionType.name,
1048
+ type: functionType,
1049
+ notNull,
1050
+ table: functionType.table || ''
1051
+ };
1052
+ }
1053
+ if (function_name === 'unixepoch') {
1054
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
1055
+ const paramExpr = expr.expr(0);
1056
+ const notNull = paramExpr.getText().toLowerCase() === `'now'`;
1057
+ const paramType = traverse_expr(paramExpr, traverseContext);
1058
+ traverseContext.constraints.push({
1059
+ expression: paramExpr.getText(),
1060
+ type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), 'DATE'),
1061
+ type2: paramType.type
1062
+ });
1063
+ return {
1064
+ name: functionType.name,
1065
+ type: functionType,
1066
+ notNull,
1067
+ table: functionType.table || ''
1068
+ };
1069
+ }
1070
+ if (function_name === 'ifnull') {
1071
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
1072
+ const paramTypes = expr.expr_list().map((paramExpr) => {
1073
+ const paramType = traverse_expr(paramExpr, traverseContext);
1074
+ if (paramType.name === '?') {
1075
+ paramType.notNull = false;
1076
+ }
1077
+ traverseContext.constraints.push({
1078
+ expression: expr.getText(),
1079
+ type1: functionType,
1080
+ type2: paramType.type
1115
1081
  });
1116
- }
1117
- const type = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
1082
+ return paramType;
1083
+ });
1118
1084
  return {
1119
- name: type.name,
1120
- type: type,
1085
+ name: functionType.name,
1086
+ type: functionType,
1087
+ notNull: paramTypes.every((param) => param.notNull),
1088
+ table: functionType.table || ''
1089
+ };
1090
+ }
1091
+ if (function_name === 'row_number' || function_name === 'rank' || function_name === 'dense_rank') {
1092
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
1093
+ return {
1094
+ name: functionType.name,
1095
+ type: functionType,
1121
1096
  notNull: true,
1122
- table: type.table || ''
1097
+ table: functionType.table || ''
1123
1098
  };
1124
1099
  }
1125
- if (expr.LIKE_() || expr.GLOB_()) {
1126
- const exprLeft = expr.expr(0);
1127
- const exprRight = expr.expr(1);
1128
- const typeLeft = traverse_expr(exprLeft, traverseContext);
1129
- const typeRight = traverse_expr(exprRight, traverseContext);
1130
- if (typeLeft.name === '?') {
1131
- typeLeft.notNull = true;
1132
- }
1133
- if (typeRight.name === '?') {
1134
- typeRight.notNull = true;
1135
- }
1100
+ if (function_name === 'first_value' || function_name === 'last_value') {
1101
+ const paramExpr = expr.expr(0);
1102
+ const paramType = traverse_expr(paramExpr, traverseContext);
1103
+ return paramType;
1104
+ }
1105
+ if (function_name === 'lead' || function_name === 'lag') {
1106
+ const paramExpr = expr.expr(0);
1107
+ const paramType = traverse_expr(paramExpr, traverseContext);
1108
+ return Object.assign(Object.assign({}, paramType), { notNull: false });
1109
+ }
1110
+ if (function_name === 'iif') {
1111
+ const expr1 = expr.expr(0);
1112
+ traverse_expr(expr1, traverseContext);
1113
+ const expr2 = expr.expr(1);
1114
+ const expr2Type = traverse_expr(expr2, traverseContext);
1115
+ const expr3 = expr.expr(2);
1116
+ const expr3Type = traverse_expr(expr3, traverseContext);
1136
1117
  traverseContext.constraints.push({
1137
1118
  expression: expr.getText(),
1138
- type1: typeLeft.type,
1139
- type2: typeRight.type
1119
+ type1: expr2Type.type,
1120
+ type2: expr3Type.type
1140
1121
  });
1122
+ return Object.assign(Object.assign({}, expr2Type), { notNull: expr2Type.notNull && expr3Type.notNull });
1123
+ }
1124
+ if (function_name === 'vector') {
1125
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'BLOB');
1126
+ const param1Expr = expr.expr(0);
1127
+ const param1Type = traverse_expr(param1Expr, traverseContext);
1128
+ param1Type.notNull = true;
1141
1129
  traverseContext.constraints.push({
1142
1130
  expression: expr.getText(),
1143
- type1: typeLeft.type,
1144
- type2: (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT')
1131
+ type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT'),
1132
+ type2: param1Type.type
1145
1133
  });
1146
- const type = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
1147
1134
  return {
1148
- name: type.name,
1149
- type: type,
1135
+ name: expr.getText(),
1136
+ type: functionType,
1150
1137
  notNull: true,
1151
- table: type.table || ''
1138
+ table: ''
1152
1139
  };
1153
1140
  }
1154
- if (expr.MATCH_()) {
1155
- const exprLeft = expr.expr(0);
1156
- const exprRight = expr.expr(1);
1157
- const typeRight = traverse_expr(exprRight, traverseContext);
1158
- if (typeRight.name === '?') {
1159
- typeRight.notNull = true;
1160
- typeRight.type = (0, collect_constraints_1.freshVar)(exprRight.getText(), 'TEXT');
1141
+ if (function_name === 'highlight' || function_name === 'snippet') {
1142
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT');
1143
+ const param0Expr = expr.expr(0);
1144
+ const param1Expr = expr.expr(1);
1145
+ const param1Type = traverse_expr(param1Expr, traverseContext);
1146
+ param1Type.notNull = true;
1147
+ traverseContext.constraints.push({
1148
+ expression: param1Expr.getText(),
1149
+ type1: (0, collect_constraints_1.freshVar)(param1Expr.getText(), 'INTEGER'),
1150
+ type2: param1Type.type
1151
+ });
1152
+ const param2Expr = expr.expr(2);
1153
+ const param2Type = traverse_expr(param2Expr, traverseContext);
1154
+ param2Type.notNull = true;
1155
+ traverseContext.constraints.push({
1156
+ expression: param2Expr.getText(),
1157
+ type1: (0, collect_constraints_1.freshVar)(param2Expr.getText(), 'TEXT'),
1158
+ type2: param2Type.type
1159
+ });
1160
+ const param3Expr = expr.expr(3);
1161
+ const param3Type = traverse_expr(param3Expr, traverseContext);
1162
+ param3Type.notNull = true;
1163
+ traverseContext.constraints.push({
1164
+ expression: param3Expr.getText(),
1165
+ type1: (0, collect_constraints_1.freshVar)(param3Expr.getText(), 'TEXT'),
1166
+ type2: param3Type.type
1167
+ });
1168
+ if (function_name === 'snippet') {
1169
+ const param4Expr = expr.expr(4);
1170
+ const param4Type = traverse_expr(param4Expr, traverseContext);
1171
+ param4Type.notNull = true;
1172
+ traverseContext.constraints.push({
1173
+ expression: param4Expr.getText(),
1174
+ type1: (0, collect_constraints_1.freshVar)(param4Expr.getText(), 'TEXT'),
1175
+ type2: param4Type.type
1176
+ });
1177
+ const param5Expr = expr.expr(5);
1178
+ const param5Type = traverse_expr(param5Expr, traverseContext);
1179
+ param5Type.notNull = true;
1180
+ traverseContext.constraints.push({
1181
+ expression: param5Expr.getText(),
1182
+ type1: (0, collect_constraints_1.freshVar)(param5Expr.getText(), 'INTEGER'),
1183
+ type2: param5Type.type
1184
+ });
1161
1185
  }
1162
- const type = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
1163
1186
  return {
1164
- name: type.name,
1165
- type: type,
1166
- notNull: true,
1167
- table: type.table || ''
1187
+ name: expr.getText(),
1188
+ type: functionType,
1189
+ notNull: false,
1190
+ table: param0Expr.getText()
1168
1191
  };
1169
1192
  }
1170
- const select_stmt = expr.select_stmt();
1171
- if (select_stmt) {
1172
- const subQueryType = traverse_select_stmt(select_stmt, Object.assign(Object.assign({}, traverseContext), { subQuery: true }), true);
1173
- const type = Object.assign(Object.assign({}, subQueryType.columns[0].type), { table: '' });
1193
+ if (function_name === 'vector_extract') {
1194
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT');
1195
+ const param1Expr = expr.expr(0);
1196
+ const param1Type = traverse_expr(param1Expr, traverseContext);
1197
+ traverseContext.constraints.push({
1198
+ expression: expr.getText(),
1199
+ type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'BLOB'),
1200
+ type2: param1Type.type
1201
+ });
1174
1202
  return {
1175
- name: type.name,
1176
- type: type,
1177
- notNull: subQueryType.columns[0].notNull,
1178
- table: type.table || ''
1203
+ name: expr.getText(),
1204
+ type: functionType,
1205
+ notNull: true,
1206
+ table: ''
1179
1207
  };
1180
1208
  }
1181
- if (expr.OPEN_PAR() && expr.CLOSE_PAR()) {
1182
- const type = (0, collect_constraints_1.freshVar)(expr.getText(), '?');
1183
- const exprTypes = expr.expr_list().map((innerExpr) => {
1184
- const exprType = traverse_expr(innerExpr, traverseContext);
1209
+ if (function_name === 'vector_distance_cos') {
1210
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), 'REAL');
1211
+ const param1Expr = expr.expr(0);
1212
+ if (param1Expr) {
1213
+ const param1Type = traverse_expr(param1Expr, traverseContext);
1214
+ param1Type.notNull = true;
1185
1215
  traverseContext.constraints.push({
1186
- expression: innerExpr.getText(),
1187
- type1: exprType.type,
1188
- type2: type
1216
+ expression: expr.getText(),
1217
+ type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'BLOB'),
1218
+ type2: param1Type.type
1189
1219
  });
1190
- return exprType;
1191
- });
1220
+ }
1221
+ const param2Expr = expr.expr(1);
1222
+ if (param2Expr) {
1223
+ const param2Type = traverse_expr(param2Expr, traverseContext);
1224
+ param2Type.notNull = true;
1225
+ traverseContext.constraints.push({
1226
+ expression: expr.getText(),
1227
+ type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'TEXT'),
1228
+ type2: param2Type.type
1229
+ });
1230
+ }
1192
1231
  return {
1193
- name: type.name,
1194
- type: type,
1195
- notNull: exprTypes.every((type) => type.notNull),
1196
- table: type.table || ''
1232
+ name: expr.getText(),
1233
+ type: functionType,
1234
+ notNull: true,
1235
+ table: ''
1197
1236
  };
1198
1237
  }
1199
- if (expr.CASE_()) {
1200
- const resultTypes = []; //then and else
1201
- const whenTypes = [];
1202
- expr.expr_list().forEach((expr_, index) => {
1203
- const type = traverse_expr(expr_, traverseContext);
1204
- if (index % 2 === 0 && (!expr.ELSE_() || index < expr.expr_list().length - 1)) {
1205
- whenTypes.push(type);
1238
+ const sqlean_uuid_functions = {
1239
+ 'uuid4': {
1240
+ paramsTypes: [],
1241
+ returnType: {
1242
+ type: 'TEXT',
1243
+ notNull: true
1206
1244
  }
1207
- else {
1208
- resultTypes.push(type);
1245
+ },
1246
+ 'uuid7': {
1247
+ paramsTypes: [],
1248
+ returnType: {
1249
+ type: 'TEXT',
1250
+ notNull: true
1209
1251
  }
1210
- });
1211
- resultTypes.forEach((resultType, index) => {
1212
- if (index > 0) {
1252
+ }
1253
+ };
1254
+ const functionCatalog = sqlean_uuid_functions[function_name];
1255
+ if (functionCatalog) {
1256
+ const functionType = (0, collect_constraints_1.freshVar)(expr.getText(), functionCatalog.returnType.type);
1257
+ expr.expr_list().forEach((exprParam, index) => {
1258
+ const paramType = traverse_expr(exprParam, traverseContext);
1259
+ const catalogType = functionCatalog.paramsTypes[index];
1260
+ if (catalogType) {
1261
+ paramType.notNull = catalogType.notNull;
1213
1262
  traverseContext.constraints.push({
1214
1263
  expression: expr.getText(),
1215
- type1: resultTypes[0].type,
1216
- type2: resultType.type
1264
+ type1: (0, collect_constraints_1.freshVar)(expr.getText(), catalogType.type),
1265
+ type2: paramType.type
1217
1266
  });
1218
1267
  }
1219
1268
  });
1220
- whenTypes.forEach((whenType) => {
1221
- traverseContext.constraints.push({
1222
- expression: expr.getText(),
1223
- type1: (0, collect_constraints_1.freshVar)('INTEGER', 'INTEGER'),
1224
- type2: whenType.type
1225
- });
1226
- });
1227
- const type = resultTypes[0];
1228
1269
  return {
1229
- name: extractOriginalSql(expr),
1230
- type: type.type,
1231
- notNull: expr.ELSE_() ? resultTypes.every((type) => type.notNull) : false,
1232
- table: type.table || ''
1270
+ name: expr.getText(),
1271
+ type: functionType,
1272
+ notNull: functionCatalog.returnType.notNull,
1273
+ table: ''
1233
1274
  };
1234
1275
  }
1235
- throw Error(`traverse_expr not supported:${expr.getText()}`);
1276
+ throw Error(`traverse_expr: function not supported:${function_name}`);
1236
1277
  }
1237
1278
  function extractOriginalSql(rule) {
1238
1279
  var _a, _b;