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