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.
- package/cli.js +5 -5
- package/cli.js.map +1 -1
- package/code-generator.d.ts +3 -3
- package/code-generator.d.ts.map +1 -1
- package/code-generator.js +4 -2
- package/code-generator.js.map +1 -1
- package/describe-dynamic-query.js +15 -12
- package/describe-dynamic-query.js.map +1 -1
- package/drivers/libsql.d.ts +1 -1
- package/drivers/libsql.d.ts.map +1 -1
- package/drivers/libsql.js +4 -1
- package/drivers/libsql.js.map +1 -1
- package/mysql-query-analyzer/types.d.ts +13 -2
- package/mysql-query-analyzer/types.d.ts.map +1 -1
- package/mysql-query-analyzer/unify.js +3 -3
- package/mysql-query-analyzer/unify.js.map +1 -1
- package/package.json +2 -2
- package/sqlite-query-analyzer/code-generator.d.ts.map +1 -1
- package/sqlite-query-analyzer/code-generator.js +72 -16
- package/sqlite-query-analyzer/code-generator.js.map +1 -1
- package/sqlite-query-analyzer/query-executor.d.ts +1 -1
- package/sqlite-query-analyzer/query-executor.d.ts.map +1 -1
- package/sqlite-query-analyzer/query-executor.js +4 -1
- package/sqlite-query-analyzer/query-executor.js.map +1 -1
- package/sqlite-query-analyzer/traverse-functions.d.ts +1 -0
- package/sqlite-query-analyzer/traverse-functions.d.ts.map +1 -0
- package/sqlite-query-analyzer/traverse-functions.js +2 -0
- package/sqlite-query-analyzer/traverse-functions.js.map +1 -0
- package/sqlite-query-analyzer/traverse.d.ts.map +1 -1
- package/sqlite-query-analyzer/traverse.js +727 -658
- package/sqlite-query-analyzer/traverse.js.map +1 -1
- package/sqlite-query-analyzer/types.d.ts +1 -1
- package/sqlite-query-analyzer/types.d.ts.map +1 -1
- package/types.d.ts +4 -0
- 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
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
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:
|
416
|
-
type:
|
417
|
-
notNull:
|
418
|
-
table:
|
417
|
+
name: type.columnName,
|
418
|
+
type: type.columnType,
|
419
|
+
notNull: type.notNull,
|
420
|
+
table: type.tableAlias || type.table
|
419
421
|
};
|
420
422
|
}
|
421
|
-
|
422
|
-
|
423
|
-
|
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:
|
426
|
-
type:
|
427
|
-
notNull:
|
428
|
-
table:
|
454
|
+
name: type.name,
|
455
|
+
type: type,
|
456
|
+
notNull: literal.NULL_() == null,
|
457
|
+
table: type.table || ''
|
429
458
|
};
|
430
459
|
}
|
431
|
-
if (
|
432
|
-
const
|
433
|
-
|
434
|
-
|
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:
|
438
|
-
type2:
|
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:
|
442
|
-
type:
|
443
|
-
notNull:
|
444
|
-
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 (
|
464
|
-
const
|
465
|
-
expr.
|
466
|
-
|
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:
|
469
|
-
type1:
|
470
|
-
type2:
|
516
|
+
expression: exprRight.getText(),
|
517
|
+
type1: returnType,
|
518
|
+
type2: typeRight.type
|
471
519
|
});
|
472
|
-
|
473
|
-
|
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:
|
478
|
-
type:
|
550
|
+
name: resultType.name,
|
551
|
+
type: resultType,
|
479
552
|
notNull: true,
|
480
|
-
table:
|
553
|
+
table: resultType.table || ''
|
481
554
|
};
|
482
555
|
}
|
483
|
-
if (
|
484
|
-
|
485
|
-
const
|
486
|
-
const
|
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:
|
490
|
-
type2:
|
565
|
+
type1: typeLeft.type,
|
566
|
+
type2: typeRight.type
|
491
567
|
});
|
492
|
-
|
493
|
-
functionType.table = paramType.table;
|
494
|
-
}
|
568
|
+
const type = (0, collect_constraints_1.freshVar)(expr.getText(), 'INTEGER');
|
495
569
|
return {
|
496
|
-
name:
|
497
|
-
type:
|
498
|
-
notNull:
|
499
|
-
table:
|
570
|
+
name: type.name,
|
571
|
+
type: type,
|
572
|
+
notNull: true,
|
573
|
+
table: type.table || ''
|
500
574
|
};
|
501
575
|
}
|
502
|
-
if (
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
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:
|
513
|
-
type:
|
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 (
|
528
|
-
const
|
529
|
-
const
|
530
|
-
const
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
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:
|
577
|
-
type1:
|
578
|
-
type2:
|
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:
|
594
|
-
type1:
|
595
|
-
type2:
|
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:
|
628
|
-
type1:
|
629
|
-
type2:
|
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 (
|
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
|
-
|
683
|
-
|
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 (
|
710
|
-
const
|
711
|
-
const
|
712
|
-
const
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
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
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
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:
|
756
|
-
type:
|
757
|
-
notNull:
|
758
|
-
table:
|
694
|
+
name: type.name,
|
695
|
+
type: type,
|
696
|
+
notNull: true,
|
697
|
+
table: type.table || ''
|
759
698
|
};
|
760
699
|
}
|
761
|
-
if (
|
762
|
-
const
|
763
|
-
const
|
764
|
-
const
|
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:
|
768
|
-
type2:
|
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:
|
772
|
-
type:
|
723
|
+
name: type.name,
|
724
|
+
type: type,
|
773
725
|
notNull: true,
|
774
|
-
table: ''
|
726
|
+
table: type.table || ''
|
775
727
|
};
|
776
728
|
}
|
777
|
-
if (
|
778
|
-
const
|
779
|
-
const
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
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:
|
801
|
-
type:
|
739
|
+
name: type.name,
|
740
|
+
type: type,
|
802
741
|
notNull: true,
|
803
|
-
table: ''
|
742
|
+
table: type.table || ''
|
804
743
|
};
|
805
744
|
}
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
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.
|
815
|
-
type: type
|
816
|
-
notNull:
|
817
|
-
table: type.
|
750
|
+
name: type.name,
|
751
|
+
type: type,
|
752
|
+
notNull: subQueryType.columns[0].notNull,
|
753
|
+
table: type.table || ''
|
818
754
|
};
|
819
755
|
}
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
const
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
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:
|
770
|
+
notNull: exprTypes.every((type) => type.notNull),
|
854
771
|
table: type.table || ''
|
855
772
|
};
|
856
773
|
}
|
857
|
-
if (expr.
|
858
|
-
const
|
859
|
-
|
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
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
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 (
|
875
|
-
const
|
876
|
-
const
|
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:
|
892
|
-
type:
|
893
|
-
notNull:
|
894
|
-
table:
|
831
|
+
name: expr.getText(),
|
832
|
+
type: paramType.type,
|
833
|
+
notNull: false,
|
834
|
+
table: paramType.table || ''
|
895
835
|
};
|
896
836
|
}
|
897
|
-
if (
|
898
|
-
const
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
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
|
-
|
911
|
-
|
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:
|
914
|
-
type1:
|
915
|
-
type2:
|
879
|
+
expression: expr.getText(),
|
880
|
+
type1: functionType,
|
881
|
+
type2: paramType.type
|
916
882
|
});
|
917
|
-
|
918
|
-
|
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:
|
948
|
-
type:
|
888
|
+
name: functionType.name,
|
889
|
+
type: functionType,
|
949
890
|
notNull: true,
|
950
|
-
table:
|
891
|
+
table: functionType.table || ''
|
951
892
|
};
|
952
893
|
}
|
953
|
-
if (
|
954
|
-
|
955
|
-
const
|
956
|
-
const
|
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:
|
963
|
-
type2:
|
900
|
+
type1: (0, collect_constraints_1.freshVar)(expr.getText(), '?'), //str or blob
|
901
|
+
type2: paramType.type
|
964
902
|
});
|
965
|
-
|
903
|
+
if (paramType.type.kind === 'TypeVar') {
|
904
|
+
functionType.table = paramType.table;
|
905
|
+
}
|
966
906
|
return {
|
967
|
-
name:
|
968
|
-
type:
|
969
|
-
notNull:
|
970
|
-
table:
|
907
|
+
name: functionType.name,
|
908
|
+
type: functionType,
|
909
|
+
notNull: false,
|
910
|
+
table: functionType.table || ''
|
971
911
|
};
|
972
912
|
}
|
973
|
-
if (
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
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:
|
993
|
-
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:
|
935
|
+
table: ''
|
996
936
|
};
|
997
937
|
}
|
998
|
-
if (
|
999
|
-
const
|
1000
|
-
const
|
1001
|
-
const
|
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:
|
1011
|
-
type2:
|
944
|
+
type1: functionType,
|
945
|
+
type2: param1Type.type
|
1012
946
|
});
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
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:
|
1020
|
-
type1:
|
1021
|
-
type2:
|
987
|
+
expression: paramExpr.getText(),
|
988
|
+
type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), 'DATE_TIME'),
|
989
|
+
type2: paramType.type
|
1022
990
|
});
|
1023
|
-
return
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
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 (
|
1032
|
-
const
|
1033
|
-
const
|
1034
|
-
const
|
1035
|
-
|
1036
|
-
|
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:
|
1046
|
-
type1:
|
1047
|
-
type2:
|
1006
|
+
expression: paramExpr.getText(),
|
1007
|
+
type1: (0, collect_constraints_1.freshVar)(paramExpr.getText(), dateType),
|
1008
|
+
type2: param1.type
|
1048
1009
|
});
|
1049
1010
|
}
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
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:
|
1058
|
-
type1:
|
1059
|
-
type2:
|
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
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
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
|
-
|
1082
|
+
return paramType;
|
1083
|
+
});
|
1090
1084
|
return {
|
1091
|
-
name:
|
1092
|
-
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:
|
1097
|
+
table: functionType.table || ''
|
1095
1098
|
};
|
1096
1099
|
}
|
1097
|
-
if (
|
1098
|
-
const
|
1099
|
-
const
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
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:
|
1111
|
-
type2:
|
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:
|
1116
|
-
type2:
|
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:
|
1121
|
-
type:
|
1135
|
+
name: expr.getText(),
|
1136
|
+
type: functionType,
|
1122
1137
|
notNull: true,
|
1123
|
-
table:
|
1138
|
+
table: ''
|
1124
1139
|
};
|
1125
1140
|
}
|
1126
|
-
if (
|
1127
|
-
const
|
1128
|
-
const
|
1129
|
-
const
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
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:
|
1137
|
-
type:
|
1138
|
-
notNull:
|
1139
|
-
table:
|
1187
|
+
name: expr.getText(),
|
1188
|
+
type: functionType,
|
1189
|
+
notNull: false,
|
1190
|
+
table: param0Expr.getText()
|
1140
1191
|
};
|
1141
1192
|
}
|
1142
|
-
|
1143
|
-
|
1144
|
-
const
|
1145
|
-
const
|
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:
|
1148
|
-
type:
|
1149
|
-
notNull:
|
1150
|
-
table:
|
1203
|
+
name: expr.getText(),
|
1204
|
+
type: functionType,
|
1205
|
+
notNull: true,
|
1206
|
+
table: ''
|
1151
1207
|
};
|
1152
1208
|
}
|
1153
|
-
if (
|
1154
|
-
const
|
1155
|
-
const
|
1156
|
-
|
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:
|
1159
|
-
type1:
|
1160
|
-
type2: type
|
1216
|
+
expression: expr.getText(),
|
1217
|
+
type1: (0, collect_constraints_1.freshVar)(expr.getText(), 'BLOB'),
|
1218
|
+
type2: param1Type.type
|
1161
1219
|
});
|
1162
|
-
|
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:
|
1166
|
-
type:
|
1167
|
-
notNull:
|
1168
|
-
table:
|
1232
|
+
name: expr.getText(),
|
1233
|
+
type: functionType,
|
1234
|
+
notNull: true,
|
1235
|
+
table: ''
|
1169
1236
|
};
|
1170
1237
|
}
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
whenTypes.push(type);
|
1238
|
+
const sqlean_uuid_functions = {
|
1239
|
+
'uuid4': {
|
1240
|
+
paramsTypes: [],
|
1241
|
+
returnType: {
|
1242
|
+
type: 'TEXT',
|
1243
|
+
notNull: true
|
1178
1244
|
}
|
1179
|
-
|
1180
|
-
|
1245
|
+
},
|
1246
|
+
'uuid7': {
|
1247
|
+
paramsTypes: [],
|
1248
|
+
returnType: {
|
1249
|
+
type: 'TEXT',
|
1250
|
+
notNull: true
|
1181
1251
|
}
|
1182
|
-
}
|
1183
|
-
|
1184
|
-
|
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:
|
1188
|
-
type2:
|
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:
|
1202
|
-
type:
|
1203
|
-
notNull:
|
1204
|
-
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:${
|
1276
|
+
throw Error(`traverse_expr: function not supported:${function_name}`);
|
1208
1277
|
}
|
1209
1278
|
function extractOriginalSql(rule) {
|
1210
1279
|
var _a, _b;
|