dsl-to-sql 1.0.0-fabric-1p-development.1
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/.turbo/turbo-build.log +9 -0
- package/.turbo/turbo-check-types.log +4 -0
- package/.turbo/turbo-lint.log +126 -0
- package/README.md +45 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +236 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/src/constants.ts.html +826 -0
- package/coverage/src/database_types.ts.html +136 -0
- package/coverage/src/epm-query-builder/EpmQueryBuilder.ts.html +166 -0
- package/coverage/src/epm-query-builder/base/BaseAdvancedAggregations.ts.html +568 -0
- package/coverage/src/epm-query-builder/base/BaseAnalyticalFunctions.ts.html +694 -0
- package/coverage/src/epm-query-builder/base/BaseCTEGenerator.ts.html +1459 -0
- package/coverage/src/epm-query-builder/base/BaseCountQueryBuilder.ts.html +400 -0
- package/coverage/src/epm-query-builder/base/BaseMeasureBuilder.ts.html +295 -0
- package/coverage/src/epm-query-builder/base/BaseOrderBuilder.ts.html +670 -0
- package/coverage/src/epm-query-builder/base/BasePaginationBuilder.ts.html +364 -0
- package/coverage/src/epm-query-builder/base/BaseQueryBuilder.ts.html +238 -0
- package/coverage/src/epm-query-builder/base/BaseRollupBuilder.ts.html +532 -0
- package/coverage/src/epm-query-builder/base/BaseSqlBuilder.ts.html +601 -0
- package/coverage/src/epm-query-builder/base/BaseSuperFilterBuilder.ts.html +1966 -0
- package/coverage/src/epm-query-builder/base/BaseUtilities.ts.html +1798 -0
- package/coverage/src/epm-query-builder/base/ColumnRefUtils.ts.html +211 -0
- package/coverage/src/epm-query-builder/base/RelationshipResolver.ts.html +706 -0
- package/coverage/src/epm-query-builder/base/SharedFilterBuilder.ts.html +1717 -0
- package/coverage/src/epm-query-builder/base/index.html +326 -0
- package/coverage/src/epm-query-builder/constants/Aggregations.ts.html +133 -0
- package/coverage/src/epm-query-builder/constants/Database.ts.html +103 -0
- package/coverage/src/epm-query-builder/constants/Source.ts.html +106 -0
- package/coverage/src/epm-query-builder/constants/index.html +146 -0
- package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbAdvancedAggregations.ts.html +286 -0
- package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbJoinBuilder.ts.html +280 -0
- package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbMeasureBuilder.ts.html +1924 -0
- package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbOrderBuilder.ts.html +769 -0
- package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbPaginationBuilder.ts.html +643 -0
- package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbQueryBuilder.ts.html +2644 -0
- package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbRollupBuilder.ts.html +478 -0
- package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbSuperFilterBuilder.ts.html +1195 -0
- package/coverage/src/epm-query-builder/dialects/duckdb/index.html +221 -0
- package/coverage/src/epm-query-builder/errors/QueryBuilderErrors.ts.html +280 -0
- package/coverage/src/epm-query-builder/errors/index.html +116 -0
- package/coverage/src/epm-query-builder/index.html +116 -0
- package/coverage/src/epm-query-builder/interfaces/IDatabaseQueryBuilder.ts.html +100 -0
- package/coverage/src/epm-query-builder/interfaces/index.html +131 -0
- package/coverage/src/epm-query-builder/interfaces/index.ts.html +88 -0
- package/coverage/src/epm-query-builder/utils/format.ts.html +151 -0
- package/coverage/src/epm-query-builder/utils/index.html +146 -0
- package/coverage/src/epm-query-builder/utils/sql.ts.html +247 -0
- package/coverage/src/epm-query-builder/utils/validation.ts.html +124 -0
- package/coverage/src/epm-query-builder/validation/QueryOptionsValidator.ts.html +631 -0
- package/coverage/src/epm-query-builder/validation/SqlQueryValidator.ts.html +475 -0
- package/coverage/src/epm-query-builder/validation/index.html +131 -0
- package/coverage/src/filters/FilterConditionBuilder.ts.html +427 -0
- package/coverage/src/filters/filter-types.ts.html +484 -0
- package/coverage/src/filters/index.html +131 -0
- package/coverage/src/index.html +176 -0
- package/coverage/src/index.ts.html +103 -0
- package/coverage/src/js-lib/JsToSqlParser.ts.html +736 -0
- package/coverage/src/js-lib/ParseContext.ts.html +532 -0
- package/coverage/src/js-lib/db/azuresql/AzureSqlCallExpressionVisitor.ts.html +196 -0
- package/coverage/src/js-lib/db/azuresql/index.html +116 -0
- package/coverage/src/js-lib/db/base/ArrayExpressionVisitor.ts.html +133 -0
- package/coverage/src/js-lib/db/base/AssignmentExpressionVisitor.ts.html +187 -0
- package/coverage/src/js-lib/db/base/BinaryExpressionVisitor.ts.html +223 -0
- package/coverage/src/js-lib/db/base/CallExpressionVisitor.ts.html +5479 -0
- package/coverage/src/js-lib/db/base/IdentifierVisitor.ts.html +283 -0
- package/coverage/src/js-lib/db/base/LiteralVisitor.ts.html +199 -0
- package/coverage/src/js-lib/db/base/MemberExpressionVisitor.ts.html +193 -0
- package/coverage/src/js-lib/db/base/ProgramVisitor.ts.html +139 -0
- package/coverage/src/js-lib/db/base/UnaryExpressionVisitor.ts.html +181 -0
- package/coverage/src/js-lib/db/base/VisitorInterface.ts.html +103 -0
- package/coverage/src/js-lib/db/base/index.html +251 -0
- package/coverage/src/js-lib/db/bigquery/BigQueryCallExpressionVisitor.ts.html +1747 -0
- package/coverage/src/js-lib/db/bigquery/index.html +116 -0
- package/coverage/src/js-lib/db/commonTransforms.ts.html +2074 -0
- package/coverage/src/js-lib/db/databricks/DatabricksCallExpressionVisitor.ts.html +1303 -0
- package/coverage/src/js-lib/db/databricks/index.html +116 -0
- package/coverage/src/js-lib/db/fabricsql/FabricSqlCallExpressionVisitor.ts.html +196 -0
- package/coverage/src/js-lib/db/fabricsql/index.html +116 -0
- package/coverage/src/js-lib/db/fabricwarehouse/FabricWarehouseCallExpressionVisitor.ts.html +292 -0
- package/coverage/src/js-lib/db/fabricwarehouse/index.html +116 -0
- package/coverage/src/js-lib/db/index.html +116 -0
- package/coverage/src/js-lib/db/postgresql/PostgreSqlCallExpressionVisitor.ts.html +985 -0
- package/coverage/src/js-lib/db/postgresql/index.html +116 -0
- package/coverage/src/js-lib/db/redshift/RedshiftCallExpressionVisitor.ts.html +685 -0
- package/coverage/src/js-lib/db/redshift/index.html +116 -0
- package/coverage/src/js-lib/db/sample/SampleCallExpressionVisitor.ts.html +196 -0
- package/coverage/src/js-lib/db/sample/index.html +116 -0
- package/coverage/src/js-lib/db/snowflake/SnowflakeCallExpressionVisitor.ts.html +1447 -0
- package/coverage/src/js-lib/db/snowflake/index.html +116 -0
- package/coverage/src/js-lib/db/validator/FormulaValidator.ts.html +4162 -0
- package/coverage/src/js-lib/db/validator/index.html +116 -0
- package/coverage/src/js-lib/index.html +131 -0
- package/coverage/src/js-lib/objects/BaseObject.ts.html +169 -0
- package/coverage/src/js-lib/objects/DateObject.ts.html +169 -0
- package/coverage/src/js-lib/objects/PctObject.ts.html +178 -0
- package/coverage/src/js-lib/objects/index.html +146 -0
- package/coverage/src/query-builder/PaginationBuilder.ts.html +142 -0
- package/coverage/src/query-builder/QueryBuilder.ts.html +3118 -0
- package/coverage/src/query-builder/SuperFilterBuilder.ts.html +1969 -0
- package/coverage/src/query-builder/index.html +146 -0
- package/coverage/src/runtime_var.ts.html +109 -0
- package/coverage/src/sql-lib/binary_expr.ts.html +133 -0
- package/coverage/src/sql-lib/case.ts.html +133 -0
- package/coverage/src/sql-lib/column.ts.html +139 -0
- package/coverage/src/sql-lib/else.ts.html +124 -0
- package/coverage/src/sql-lib/function.ts.html +112 -0
- package/coverage/src/sql-lib/index.html +251 -0
- package/coverage/src/sql-lib/join.ts.html +127 -0
- package/coverage/src/sql-lib/literal.ts.html +130 -0
- package/coverage/src/sql-lib/select.ts.html +547 -0
- package/coverage/src/sql-lib/unary_expr.ts.html +112 -0
- package/coverage/src/sql-lib/when.ts.html +130 -0
- package/coverage/src/sql_query_gen.ts.html +535 -0
- package/coverage/src/superFilter/DateFilterFactory.ts.html +625 -0
- package/coverage/src/superFilter/dateFunction.ts.html +193 -0
- package/coverage/src/superFilter/index.html +131 -0
- package/coverage/src/utils.ts.html +571 -0
- package/dist/index.cjs +8440 -0
- package/dist/index.d.cts +927 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +927 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8387 -0
- package/dist/index.js.map +1 -0
- package/eslint.config.js +4 -0
- package/jest.config.ts +44 -0
- package/package.json +45 -0
- package/src/constants.ts +247 -0
- package/src/epm-query-builder/EpmQueryBuilder.ts +27 -0
- package/src/epm-query-builder/base/BaseAdvancedAggregations.ts +161 -0
- package/src/epm-query-builder/base/BaseAnalyticalFunctions.ts +203 -0
- package/src/epm-query-builder/base/BaseCTEGenerator.ts +458 -0
- package/src/epm-query-builder/base/BaseCountQueryBuilder.ts +105 -0
- package/src/epm-query-builder/base/BaseMeasureBuilder.ts +87 -0
- package/src/epm-query-builder/base/BaseOrderBuilder.ts +195 -0
- package/src/epm-query-builder/base/BasePaginationBuilder.ts +93 -0
- package/src/epm-query-builder/base/BaseQueryBuilder.ts +51 -0
- package/src/epm-query-builder/base/BaseRollupBuilder.ts +149 -0
- package/src/epm-query-builder/base/BaseSqlBuilder.ts +172 -0
- package/src/epm-query-builder/base/BaseSuperFilterBuilder.ts +627 -0
- package/src/epm-query-builder/base/BaseUtilities.ts +571 -0
- package/src/epm-query-builder/base/ColumnRefUtils.ts +42 -0
- package/src/epm-query-builder/base/RelationshipResolver.ts +207 -0
- package/src/epm-query-builder/base/SharedFilterBuilder.ts +544 -0
- package/src/epm-query-builder/constants/Aggregations.ts +16 -0
- package/src/epm-query-builder/constants/Database.ts +6 -0
- package/src/epm-query-builder/constants/Source.ts +7 -0
- package/src/epm-query-builder/dialects/duckdb/DuckDbAdvancedAggregations.ts +67 -0
- package/src/epm-query-builder/dialects/duckdb/DuckDbJoinBuilder.ts +65 -0
- package/src/epm-query-builder/dialects/duckdb/DuckDbMeasureBuilder.ts +626 -0
- package/src/epm-query-builder/dialects/duckdb/DuckDbOrderBuilder.ts +228 -0
- package/src/epm-query-builder/dialects/duckdb/DuckDbPaginationBuilder.ts +186 -0
- package/src/epm-query-builder/dialects/duckdb/DuckDbQueryBuilder.ts +853 -0
- package/src/epm-query-builder/dialects/duckdb/DuckDbRollupBuilder.ts +131 -0
- package/src/epm-query-builder/dialects/duckdb/DuckDbSuperFilterBuilder.ts +370 -0
- package/src/epm-query-builder/errors/QueryBuilderErrors.ts +65 -0
- package/src/epm-query-builder/interfaces/IDatabaseQueryBuilder.ts +5 -0
- package/src/epm-query-builder/interfaces/index.ts +1 -0
- package/src/epm-query-builder/types/query-builder-types.d.ts +289 -0
- package/src/epm-query-builder/utils/format.ts +22 -0
- package/src/epm-query-builder/utils/sql.ts +54 -0
- package/src/epm-query-builder/utils/validation.ts +13 -0
- package/src/epm-query-builder/validation/QueryOptionsValidator.ts +182 -0
- package/src/epm-query-builder/validation/SqlQueryValidator.ts +130 -0
- package/src/filters/FilterConditionBuilder.ts +114 -0
- package/src/filters/filter-types.ts +133 -0
- package/src/index.ts +10 -0
- package/src/js-lib/JsToSqlParser.ts +217 -0
- package/src/js-lib/ParseContext.ts +149 -0
- package/src/js-lib/db/base/ArrayExpressionVisitor.ts +16 -0
- package/src/js-lib/db/base/AssignmentExpressionVisitor.ts +34 -0
- package/src/js-lib/db/base/BinaryExpressionVisitor.ts +46 -0
- package/src/js-lib/db/base/CallExpressionVisitor.ts +1798 -0
- package/src/js-lib/db/base/IdentifierVisitor.ts +66 -0
- package/src/js-lib/db/base/LiteralVisitor.ts +38 -0
- package/src/js-lib/db/base/MemberExpressionVisitor.ts +36 -0
- package/src/js-lib/db/base/ProgramVisitor.ts +18 -0
- package/src/js-lib/db/base/UnaryExpressionVisitor.ts +32 -0
- package/src/js-lib/db/base/VisitorInterface.ts +6 -0
- package/src/js-lib/db/validator/FormulaValidator.ts +1235 -0
- package/src/js-lib/objects/BaseObject.ts +28 -0
- package/src/js-lib/objects/DateObject.ts +28 -0
- package/src/js-lib/objects/PctObject.ts +31 -0
- package/src/query-builder/PaginationBuilder.ts +19 -0
- package/src/query-builder/QueryBuilder.ts +1035 -0
- package/src/query-builder/SuperFilterBuilder.ts +628 -0
- package/src/runtime_var.ts +8 -0
- package/src/sql-lib/binary_expr.ts +16 -0
- package/src/sql-lib/case.ts +16 -0
- package/src/sql-lib/column.ts +18 -0
- package/src/sql-lib/else.ts +13 -0
- package/src/sql-lib/function.ts +9 -0
- package/src/sql-lib/join.ts +14 -0
- package/src/sql-lib/literal.ts +15 -0
- package/src/sql-lib/select.ts +154 -0
- package/src/sql-lib/unary_expr.ts +9 -0
- package/src/sql-lib/when.ts +15 -0
- package/src/sql-types.d.ts +565 -0
- package/src/sql_query_gen.ts +150 -0
- package/src/superFilter/DateFilterFactory.ts +180 -0
- package/src/superFilter/dateFunction.ts +36 -0
- package/src/utils.ts +354 -0
- package/test-output/report/junit.xml +329 -0
- package/tests/JsToSqlParser.test.ts +163 -0
- package/tests/QueryBuilder.test.ts +1320 -0
- package/tests/js-lib/CallExpressionVisitor.test.ts +820 -0
- package/tests/mocks/MockQueryResolver.ts +14 -0
- package/tests/sanity.test.ts +146 -0
- package/tests/sql-lib/binary_expr.test.ts +75 -0
- package/tests/sql-lib/case.test.ts +117 -0
- package/tests/sql-lib/column.test.ts +87 -0
- package/tests/sql-lib/else.test.ts +56 -0
- package/tests/sql-lib/function.test.ts +96 -0
- package/tests/sql-lib/literal.test.ts +75 -0
- package/tests/sql-lib/select.test.ts +245 -0
- package/tests/sql-lib/unary_expr.test.ts +32 -0
- package/tests/utils.test.ts +13 -0
- package/tsconfig.json +24 -0
- package/tsdown.config.ts +23 -0
|
@@ -0,0 +1,820 @@
|
|
|
1
|
+
import { createJsToSqlParser } from '../../src/js-lib/JsToSqlParser';
|
|
2
|
+
import {
|
|
3
|
+
IMDMColumnConfigWithParsedMeta,
|
|
4
|
+
MDM_COLUMN_TYPE,
|
|
5
|
+
ParseContext,
|
|
6
|
+
} from '../../src/js-lib/ParseContext';
|
|
7
|
+
|
|
8
|
+
// Mock ParseContext for testing
|
|
9
|
+
function createMockContext(
|
|
10
|
+
columnNames: string[],
|
|
11
|
+
currentColumnId: string,
|
|
12
|
+
isCompositeKey: boolean = false,
|
|
13
|
+
): ParseContext {
|
|
14
|
+
const tableName = 'TestTable';
|
|
15
|
+
const columnConfigMap = columnNames.reduce(
|
|
16
|
+
(acc, columnName) => {
|
|
17
|
+
acc[columnName] = {
|
|
18
|
+
columnName,
|
|
19
|
+
columnType: MDM_COLUMN_TYPE.NUMBER,
|
|
20
|
+
columnMeta: { tableName },
|
|
21
|
+
};
|
|
22
|
+
return acc;
|
|
23
|
+
},
|
|
24
|
+
{} as Record<string, IMDMColumnConfigWithParsedMeta>,
|
|
25
|
+
);
|
|
26
|
+
const primaryKeyColumns = isCompositeKey ? ['PK1', 'PK2'] : ['PK'];
|
|
27
|
+
return new ParseContext({
|
|
28
|
+
columnConfigMap,
|
|
29
|
+
currentColumnId,
|
|
30
|
+
primaryKeyColumns,
|
|
31
|
+
tableName,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe('CallExpressionVisitor', () => {
|
|
36
|
+
describe('Logical Functions', () => {
|
|
37
|
+
test('should transform IF function to Sql case-when', () => {
|
|
38
|
+
const formula = `IF(Amount > 100, 'High', 'Low')`;
|
|
39
|
+
const expectedSql = `CASE WHEN [Amount] > 100 THEN 'High' ELSE 'Low' END`;
|
|
40
|
+
const context = createMockContext(['Amount'], 'Status');
|
|
41
|
+
const parser = createJsToSqlParser(context);
|
|
42
|
+
const ast = parser.parse(formula);
|
|
43
|
+
const sql = parser.toSql(ast);
|
|
44
|
+
expect(sql).toBe(expectedSql);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('should transform AND function to Sql AND operator', () => {
|
|
48
|
+
const formula = `AND(Amount > 100, Status == 'Active')`;
|
|
49
|
+
const expectedSql = `CASE WHEN [Amount] > 100 AND [Status] = 'Active' THEN 'true' ELSE 'false' END`;
|
|
50
|
+
const context = createMockContext(['Amount', 'Status'], 'Result');
|
|
51
|
+
const parser = createJsToSqlParser(context);
|
|
52
|
+
const ast = parser.parse(formula);
|
|
53
|
+
const sql = parser.toSql(ast);
|
|
54
|
+
expect(sql).toBe(expectedSql);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('should transform OR function to Sql OR operator', () => {
|
|
58
|
+
const formula = `OR(Amount > 100, Status == 'Active')`;
|
|
59
|
+
const expectedSql = `CASE WHEN [Amount] > 100 OR [Status] = 'Active' THEN 'true' ELSE 'false' END`;
|
|
60
|
+
const context = createMockContext(['Amount', 'Status'], 'Result');
|
|
61
|
+
const parser = createJsToSqlParser(context);
|
|
62
|
+
const ast = parser.parse(formula);
|
|
63
|
+
const sql = parser.toSql(ast);
|
|
64
|
+
expect(sql).toBe(expectedSql);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('should transform NOT function to Sql NOT operator', () => {
|
|
68
|
+
const formula = `NOT(Amount > 100)`;
|
|
69
|
+
const expectedSql = `CASE WHEN [Amount] > 100 THEN CAST(0 AS BIT) ELSE CAST(1 AS BIT) END`;
|
|
70
|
+
const context = createMockContext(['Amount'], 'Result');
|
|
71
|
+
const parser = createJsToSqlParser(context);
|
|
72
|
+
const ast = parser.parse(formula);
|
|
73
|
+
const sql = parser.toSql(ast);
|
|
74
|
+
expect(sql).toBe(expectedSql);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('should transform XOR function to Sql XOR operator', () => {
|
|
78
|
+
const formula = `XOR(Amount > 100, Status == 'Active')`;
|
|
79
|
+
const expectedSql = `CASE WHEN [Amount] > 100 AND NOT [Status] = 'Active' OR NOT [Amount] > 100 AND [Status] = 'Active' THEN '1' ELSE '0' END`;
|
|
80
|
+
const context = createMockContext(['Amount', 'Status'], 'Result');
|
|
81
|
+
const parser = createJsToSqlParser(context);
|
|
82
|
+
const ast = parser.parse(formula);
|
|
83
|
+
const sql = parser.toSql(ast);
|
|
84
|
+
expect(sql).toBe(expectedSql);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('Date Functions', () => {
|
|
89
|
+
test('should transform DATEADD function to Sql DATEADD function', () => {
|
|
90
|
+
const formula = `DATEADD(PurchaseDate, 10)`;
|
|
91
|
+
const expectedSql = `DATEADD(DAY, 10, [PurchaseDate])`;
|
|
92
|
+
const context = createMockContext(['PurchaseDate'], 'ExpirationDate');
|
|
93
|
+
const parser = createJsToSqlParser(context);
|
|
94
|
+
const ast = parser.parse(formula);
|
|
95
|
+
const sql = parser.toSql(ast);
|
|
96
|
+
expect(sql).toBe(expectedSql);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test('should transform DATEADD with TODAY() function to Sql DATEADD function', () => {
|
|
100
|
+
const formula = `DATEADD(TODAY(), 5)`;
|
|
101
|
+
const expectedSql = `DATEADD(DAY, 5, CURRENT_DATE)`;
|
|
102
|
+
const context = createMockContext([], 'FutureDate');
|
|
103
|
+
const parser = createJsToSqlParser(context);
|
|
104
|
+
const ast = parser.parse(formula);
|
|
105
|
+
const sql = parser.toSql(ast);
|
|
106
|
+
expect(sql).toBe(expectedSql);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('should transform DATEDIFF function to Sql DATEDIFF function', () => {
|
|
110
|
+
const formula = `DATEDIFF(StartDate, EndDate)`;
|
|
111
|
+
const expectedSql = `DATEDIFF(DAY, [StartDate], [EndDate])`;
|
|
112
|
+
const context = createMockContext(['StartDate', 'EndDate'], 'Duration');
|
|
113
|
+
const parser = createJsToSqlParser(context);
|
|
114
|
+
const ast = parser.parse(formula);
|
|
115
|
+
const sql = parser.toSql(ast);
|
|
116
|
+
expect(sql).toBe(expectedSql);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('should transform DATEDIFF with TODAY() function to Sql DATEDIFF function', () => {
|
|
120
|
+
const formula = `DATEDIFF(StartDate, TODAY())`;
|
|
121
|
+
const expectedSql = `DATEDIFF(DAY, [StartDate], CURRENT_DATE)`;
|
|
122
|
+
const context = createMockContext(['StartDate'], 'DaysUntilToday');
|
|
123
|
+
const parser = createJsToSqlParser(context);
|
|
124
|
+
const ast = parser.parse(formula);
|
|
125
|
+
const sql = parser.toSql(ast);
|
|
126
|
+
expect(sql).toBe(expectedSql);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('should transform DAY function to Sql DAY function', () => {
|
|
130
|
+
const formula = `DAY(PurchaseDate)`;
|
|
131
|
+
const expectedSql = `DAY([PurchaseDate])`;
|
|
132
|
+
const context = createMockContext(['PurchaseDate'], 'Day');
|
|
133
|
+
const parser = createJsToSqlParser(context);
|
|
134
|
+
const ast = parser.parse(formula);
|
|
135
|
+
const sql = parser.toSql(ast);
|
|
136
|
+
expect(sql).toBe(expectedSql);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('should transform EOMONTH function to Sql EOMONTH function', () => {
|
|
140
|
+
const formula = `EOMONTH(PurchaseDate)`;
|
|
141
|
+
const expectedSql = `EOMONTH([PurchaseDate])`;
|
|
142
|
+
const context = createMockContext(['PurchaseDate'], 'EndOfMonth');
|
|
143
|
+
const parser = createJsToSqlParser(context);
|
|
144
|
+
const ast = parser.parse(formula);
|
|
145
|
+
const sql = parser.toSql(ast);
|
|
146
|
+
expect(sql).toBe(expectedSql);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test('should transform MONTH function to Sql MONTH function', () => {
|
|
150
|
+
const formula = `MONTH(PurchaseDate)`;
|
|
151
|
+
const expectedSql = `MONTH([PurchaseDate])`;
|
|
152
|
+
const context = createMockContext(['PurchaseDate'], 'Month');
|
|
153
|
+
const parser = createJsToSqlParser(context);
|
|
154
|
+
const ast = parser.parse(formula);
|
|
155
|
+
const sql = parser.toSql(ast);
|
|
156
|
+
expect(sql).toBe(expectedSql);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('should transform NOW function to Sql NOW function', () => {
|
|
160
|
+
const formula = `NOW()`;
|
|
161
|
+
const expectedSql = `CURRENT_TIMESTAMP`;
|
|
162
|
+
const context = createMockContext([], 'CurrentTimestamp');
|
|
163
|
+
const parser = createJsToSqlParser(context);
|
|
164
|
+
const ast = parser.parse(formula);
|
|
165
|
+
const sql = parser.toSql(ast);
|
|
166
|
+
expect(sql).toBe(expectedSql);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('should transform TODAY function to Sql TODAY function', () => {
|
|
170
|
+
const formula = `TODAY()`;
|
|
171
|
+
const expectedSql = `CURRENT_DATE`;
|
|
172
|
+
const context = createMockContext([], 'CurrentDate');
|
|
173
|
+
const parser = createJsToSqlParser(context);
|
|
174
|
+
const ast = parser.parse(formula);
|
|
175
|
+
const sql = parser.toSql(ast);
|
|
176
|
+
expect(sql).toBe(expectedSql);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test('should transform YEAR function to Sql YEAR function', () => {
|
|
180
|
+
const formula = `YEAR(PurchaseDate)`;
|
|
181
|
+
const expectedSql = `YEAR([PurchaseDate])`;
|
|
182
|
+
const context = createMockContext(['PurchaseDate'], 'PurchaseYear');
|
|
183
|
+
const parser = createJsToSqlParser(context);
|
|
184
|
+
const ast = parser.parse(formula);
|
|
185
|
+
const sql = parser.toSql(ast);
|
|
186
|
+
expect(sql).toBe(expectedSql);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
describe('String Functions', () => {
|
|
191
|
+
test('should transform CONCATENATE function to Sql CONCAT function', () => {
|
|
192
|
+
const formula = `CONCATENATE(Name, LastName)`;
|
|
193
|
+
const expectedSql = `CONCAT([Name], [LastName])`;
|
|
194
|
+
const context = createMockContext(['Name', 'LastName'], 'FullName');
|
|
195
|
+
const parser = createJsToSqlParser(context);
|
|
196
|
+
const ast = parser.parse(formula);
|
|
197
|
+
const sql = parser.toSql(ast);
|
|
198
|
+
expect(sql).toBe(expectedSql);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test('should transform ISBLANK function to Sql case-when function', () => {
|
|
202
|
+
const formula = `ISBLANK(Name)`;
|
|
203
|
+
const expectedSql = `CASE WHEN [Name] IS NULL THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END`;
|
|
204
|
+
const context = createMockContext(['Name'], 'IsBlank');
|
|
205
|
+
const parser = createJsToSqlParser(context);
|
|
206
|
+
const ast = parser.parse(formula);
|
|
207
|
+
const sql = parser.toSql(ast);
|
|
208
|
+
expect(sql).toBe(expectedSql);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test('should transform ISEMPTY function to Sql case-when function', () => {
|
|
212
|
+
const formula = `ISEMPTY(Name)`;
|
|
213
|
+
const expectedSql = `CASE WHEN [Name] IS NULL THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END`;
|
|
214
|
+
const context = createMockContext(['Name'], 'IsEmpty');
|
|
215
|
+
const parser = createJsToSqlParser(context);
|
|
216
|
+
const ast = parser.parse(formula);
|
|
217
|
+
const sql = parser.toSql(ast);
|
|
218
|
+
expect(sql).toBe(expectedSql);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
test('should transform LEFT function to Sql LEFT function', () => {
|
|
222
|
+
const formula = `LEFT(Name, 3)`;
|
|
223
|
+
const expectedSql = `LEFT([Name], 3)`;
|
|
224
|
+
const context = createMockContext(['Name'], 'LeftName');
|
|
225
|
+
const parser = createJsToSqlParser(context);
|
|
226
|
+
const ast = parser.parse(formula);
|
|
227
|
+
const sql = parser.toSql(ast);
|
|
228
|
+
expect(sql).toBe(expectedSql);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test('should transform LEN function to Sql LEN function', () => {
|
|
232
|
+
const formula = `LEN(Name)`;
|
|
233
|
+
const expectedSql = `LEN([Name])`;
|
|
234
|
+
const context = createMockContext(['Name'], 'LenName');
|
|
235
|
+
const parser = createJsToSqlParser(context);
|
|
236
|
+
const ast = parser.parse(formula);
|
|
237
|
+
const sql = parser.toSql(ast);
|
|
238
|
+
expect(sql).toBe(expectedSql);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
test('should transform LOWER function to Sql LOWER function', () => {
|
|
242
|
+
const formula = `LOWER(Name)`;
|
|
243
|
+
const expectedSql = `LOWER([Name])`;
|
|
244
|
+
const context = createMockContext(['Name'], 'LowerName');
|
|
245
|
+
const parser = createJsToSqlParser(context);
|
|
246
|
+
const ast = parser.parse(formula);
|
|
247
|
+
const sql = parser.toSql(ast);
|
|
248
|
+
expect(sql).toBe(expectedSql);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
test('should transform MATCH function to Sql MATCH function', () => {
|
|
252
|
+
const formula = `MATCH(Name, 'John')`;
|
|
253
|
+
const expectedSql = `CASE WHEN [Name] LIKE 'John' THEN 'true' ELSE 'false' END`;
|
|
254
|
+
const context = createMockContext(['Name'], 'MatchName');
|
|
255
|
+
const parser = createJsToSqlParser(context);
|
|
256
|
+
const ast = parser.parse(formula);
|
|
257
|
+
const sql = parser.toSql(ast);
|
|
258
|
+
expect(sql).toBe(expectedSql);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
test('should transform MID function to Sql MID function', () => {
|
|
262
|
+
const formula = `MID(Name, 1, 3)`;
|
|
263
|
+
const expectedSql = `SUBSTRING([Name], 1, 3)`;
|
|
264
|
+
const context = createMockContext(['Name'], 'MidName');
|
|
265
|
+
const parser = createJsToSqlParser(context);
|
|
266
|
+
const ast = parser.parse(formula);
|
|
267
|
+
const sql = parser.toSql(ast);
|
|
268
|
+
expect(sql).toBe(expectedSql);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test('should transform NUMBERVALUE function to Sql NUMBERVALUE function', () => {
|
|
272
|
+
const formula = `NUMBERVALUE(Amount)`;
|
|
273
|
+
const expectedSql = `CAST([Amount] AS FLOAT)`;
|
|
274
|
+
const context = createMockContext(['Amount'], 'NumberValueAmount');
|
|
275
|
+
const parser = createJsToSqlParser(context);
|
|
276
|
+
const ast = parser.parse(formula);
|
|
277
|
+
const sql = parser.toSql(ast);
|
|
278
|
+
expect(sql).toBe(expectedSql);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
test('should transform REPLACE function to Sql REPLACE function', () => {
|
|
282
|
+
const formula = `REPLACE(Name,0, 2, 'SQL')`;
|
|
283
|
+
const expectedSql = `STUFF([Name], 0, 2, 'SQL')`;
|
|
284
|
+
const context = createMockContext(['Name'], 'ReplaceName');
|
|
285
|
+
const parser = createJsToSqlParser(context);
|
|
286
|
+
const ast = parser.parse(formula);
|
|
287
|
+
const sql = parser.toSql(ast);
|
|
288
|
+
expect(sql).toBe(expectedSql);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
test('should transform REPT function to Sql REPT function', () => {
|
|
292
|
+
const formula = `REPT('Hello', 3)`;
|
|
293
|
+
const expectedSql = `REPLICATE('Hello', 3)`;
|
|
294
|
+
const context = createMockContext([], 'ReptAmount');
|
|
295
|
+
const parser = createJsToSqlParser(context);
|
|
296
|
+
const ast = parser.parse(formula);
|
|
297
|
+
const sql = parser.toSql(ast);
|
|
298
|
+
expect(sql).toBe(expectedSql);
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
test('should transform RIGHT function to Sql RIGHT function', () => {
|
|
302
|
+
const formula = `RIGHT(Amount, 3)`;
|
|
303
|
+
const expectedSql = `RIGHT([Amount], 3)`;
|
|
304
|
+
const context = createMockContext(['Amount'], 'RightAmount');
|
|
305
|
+
const parser = createJsToSqlParser(context);
|
|
306
|
+
const ast = parser.parse(formula);
|
|
307
|
+
const sql = parser.toSql(ast);
|
|
308
|
+
expect(sql).toBe(expectedSql);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test('should transform TRIM function to Sql TRIM function', () => {
|
|
312
|
+
const formula = `TRIM(Amount)`;
|
|
313
|
+
const expectedSql = `TRIM([Amount])`;
|
|
314
|
+
const context = createMockContext(['Amount'], 'TrimAmount');
|
|
315
|
+
const parser = createJsToSqlParser(context);
|
|
316
|
+
const ast = parser.parse(formula);
|
|
317
|
+
const sql = parser.toSql(ast);
|
|
318
|
+
expect(sql).toBe(expectedSql);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test('should transform UPPER function to Sql UPPER function', () => {
|
|
322
|
+
const formula = `UPPER(Amount)`;
|
|
323
|
+
const expectedSql = `UPPER([Amount])`;
|
|
324
|
+
const context = createMockContext(['Amount'], 'UpperAmount');
|
|
325
|
+
const parser = createJsToSqlParser(context);
|
|
326
|
+
const ast = parser.parse(formula);
|
|
327
|
+
const sql = parser.toSql(ast);
|
|
328
|
+
expect(sql).toBe(expectedSql);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
test('should transform VALUE function to Sql VALUE function', () => {
|
|
332
|
+
const formula = `VALUE(Amount)`;
|
|
333
|
+
const expectedSql = `CAST([Amount] AS FLOAT)`;
|
|
334
|
+
const context = createMockContext(['Amount'], 'ValueAmount');
|
|
335
|
+
const parser = createJsToSqlParser(context);
|
|
336
|
+
const ast = parser.parse(formula);
|
|
337
|
+
const sql = parser.toSql(ast);
|
|
338
|
+
expect(sql).toBe(expectedSql);
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
test('should transform TEXT function to Sql TEXT function for date', () => {
|
|
342
|
+
const formula = `TEXT(ShipDate, 'mm/dd/yyyy')`;
|
|
343
|
+
const expectedSql = `FORMAT([ShipDate], 'MM/dd/yyyy', 'en-US')`;
|
|
344
|
+
const context = createMockContext(['ShipDate'], 'FormattedShipDate');
|
|
345
|
+
const parser = createJsToSqlParser(context);
|
|
346
|
+
const ast = parser.parse(formula);
|
|
347
|
+
const sql = parser.toSql(ast);
|
|
348
|
+
expect(sql).toBe(expectedSql);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
test('should transform TEXT function to Sql TEXT function for date to extract month', () => {
|
|
352
|
+
const formula = `TEXT(ShipDate, 'm')`;
|
|
353
|
+
const expectedSql = `FORMAT([ShipDate], '%M', 'en-US')`;
|
|
354
|
+
const context = createMockContext(['ShipDate'], 'FormattedShipDate');
|
|
355
|
+
const parser = createJsToSqlParser(context);
|
|
356
|
+
const ast = parser.parse(formula);
|
|
357
|
+
const sql = parser.toSql(ast);
|
|
358
|
+
expect(sql).toBe(expectedSql);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
test('should transform TEXT function to Sql TEXT function for number with currency', () => {
|
|
362
|
+
const formula = `TEXT(Amount, '$###,###.00')`;
|
|
363
|
+
const expectedSql = `FORMAT([Amount], '$###,###.00', 'en-US')`;
|
|
364
|
+
const context = createMockContext(['Amount'], 'FormattedAmount');
|
|
365
|
+
const parser = createJsToSqlParser(context);
|
|
366
|
+
const ast = parser.parse(formula);
|
|
367
|
+
const sql = parser.toSql(ast);
|
|
368
|
+
expect(sql).toBe(expectedSql);
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
describe('Math Functions', () => {
|
|
373
|
+
test('should transform ABS function to Sql ABS function', () => {
|
|
374
|
+
const formula = `ABS(Amount)`;
|
|
375
|
+
const expectedSql = `ABS([Amount])`;
|
|
376
|
+
const context = createMockContext(['Amount'], 'AbsAmount');
|
|
377
|
+
const parser = createJsToSqlParser(context);
|
|
378
|
+
const ast = parser.parse(formula);
|
|
379
|
+
const sql = parser.toSql(ast);
|
|
380
|
+
expect(sql).toBe(expectedSql);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
test('should transform AVERAGE function to Sql expression', () => {
|
|
384
|
+
const formula = `AVERAGE(M1, M2, M3)`;
|
|
385
|
+
const expectedSql = `CAST(((COALESCE([M1], 0) + COALESCE([M2], 0) + COALESCE([M3], 0))/3) AS FLOAT)`;
|
|
386
|
+
const context = createMockContext(['M1', 'M2', 'M3'], 'AvgAmount');
|
|
387
|
+
const parser = createJsToSqlParser(context);
|
|
388
|
+
const ast = parser.parse(formula);
|
|
389
|
+
const sql = parser.toSql(ast);
|
|
390
|
+
expect(sql).toBe(expectedSql);
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
test('should transform AVERAGEIF function to Sql expression', () => {
|
|
394
|
+
const formula = `AVERAGEIF([M1, M2, M3], '>1000')`;
|
|
395
|
+
const expectedSql = `cte_union_AvgAmount AS (SELECT PK, [M1] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME UNION ALL SELECT PK, [M2] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME UNION ALL SELECT PK, [M3] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME), cte_filter_AvgAmount AS (SELECT PK, val_AvgAmount FROM cte_union_AvgAmount WHERE [val_AvgAmount] > 1000), cte_avg_AvgAmount AS (SELECT PK, AVG(val_AvgAmount) AS AvgAmount FROM cte_filter_AvgAmount GROUP BY PK), cte_AvgAmount AS (SELECT $RUNTIME_TABLE_NAME.*, AvgAmount FROM $RUNTIME_TABLE_NAME INNER JOIN cte_avg_AvgAmount ON $RUNTIME_TABLE_NAME.PK = cte_avg_AvgAmount.PK)`;
|
|
396
|
+
const context = createMockContext(['M1', 'M2', 'M3'], 'AvgAmount');
|
|
397
|
+
const parser = createJsToSqlParser(context);
|
|
398
|
+
const ast = parser.parse(formula);
|
|
399
|
+
const sql = parser.toSql(ast);
|
|
400
|
+
expect(sql).toBe(expectedSql);
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
test('should transform AVERAGEXNEG function to Sql expression', () => {
|
|
404
|
+
const formula = `AVERAGEEXNEG([M1, M2, M3])`;
|
|
405
|
+
const expectedSql = `cte_union_AvgAmount AS (SELECT PK, [M1] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME UNION ALL SELECT PK, [M2] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME UNION ALL SELECT PK, [M3] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME), cte_filter_AvgAmount AS (SELECT PK, val_AvgAmount FROM cte_union_AvgAmount WHERE val_AvgAmount >= 0), cte_avg_AvgAmount AS (SELECT PK, AVG(val_AvgAmount) AS AvgAmount FROM cte_filter_AvgAmount GROUP BY PK), cte_AvgAmount AS (SELECT $RUNTIME_TABLE_NAME.*, AvgAmount FROM $RUNTIME_TABLE_NAME INNER JOIN cte_avg_AvgAmount ON $RUNTIME_TABLE_NAME.PK = cte_avg_AvgAmount.PK)`;
|
|
406
|
+
const context = createMockContext(['M1', 'M2', 'M3'], 'AvgAmount');
|
|
407
|
+
const parser = createJsToSqlParser(context);
|
|
408
|
+
const ast = parser.parse(formula);
|
|
409
|
+
const sql = parser.toSql(ast);
|
|
410
|
+
expect(sql).toBe(expectedSql);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
test('should transform AVERAGEXZERO function to Sql expression', () => {
|
|
414
|
+
const formula = `AVERAGEEXZERO([M1, M2, M3])`;
|
|
415
|
+
const expectedSql = `cte_union_AvgAmount AS (SELECT PK, [M1] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME UNION ALL SELECT PK, [M2] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME UNION ALL SELECT PK, [M3] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME), cte_filter_AvgAmount AS (SELECT PK, val_AvgAmount FROM cte_union_AvgAmount WHERE val_AvgAmount != 0), cte_avg_AvgAmount AS (SELECT PK, AVG(val_AvgAmount) AS AvgAmount FROM cte_filter_AvgAmount GROUP BY PK), cte_AvgAmount AS (SELECT $RUNTIME_TABLE_NAME.*, AvgAmount FROM $RUNTIME_TABLE_NAME INNER JOIN cte_avg_AvgAmount ON $RUNTIME_TABLE_NAME.PK = cte_avg_AvgAmount.PK)`;
|
|
416
|
+
const context = createMockContext(['M1', 'M2', 'M3'], 'AvgAmount');
|
|
417
|
+
const parser = createJsToSqlParser(context);
|
|
418
|
+
const ast = parser.parse(formula);
|
|
419
|
+
const sql = parser.toSql(ast);
|
|
420
|
+
expect(sql).toBe(expectedSql);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
test('should transform AVERAGEXZERONEG function to Sql expression', () => {
|
|
424
|
+
const formula = `AVERAGEEXZERONEG([M1, M2, M3])`;
|
|
425
|
+
const expectedSql = `cte_union_AvgAmount AS (SELECT PK, [M1] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME UNION ALL SELECT PK, [M2] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME UNION ALL SELECT PK, [M3] AS val_AvgAmount FROM $RUNTIME_TABLE_NAME), cte_filter_AvgAmount AS (SELECT PK, val_AvgAmount FROM cte_union_AvgAmount WHERE val_AvgAmount > 0), cte_avg_AvgAmount AS (SELECT PK, AVG(val_AvgAmount) AS AvgAmount FROM cte_filter_AvgAmount GROUP BY PK), cte_AvgAmount AS (SELECT $RUNTIME_TABLE_NAME.*, AvgAmount FROM $RUNTIME_TABLE_NAME INNER JOIN cte_avg_AvgAmount ON $RUNTIME_TABLE_NAME.PK = cte_avg_AvgAmount.PK)`;
|
|
426
|
+
const context = createMockContext(['M1', 'M2', 'M3'], 'AvgAmount');
|
|
427
|
+
const parser = createJsToSqlParser(context);
|
|
428
|
+
const ast = parser.parse(formula);
|
|
429
|
+
const sql = parser.toSql(ast);
|
|
430
|
+
expect(sql).toBe(expectedSql);
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
test('should transform DATE function to Sql expression', () => {
|
|
434
|
+
const formula = `DATE("date_column", "dd-MM-yyyy")`;
|
|
435
|
+
const expectedSql = `FORMAT('date_column', 'dd-MM-yyyy')`;
|
|
436
|
+
const context = createMockContext(['date_column'], 'dd-MM-yyyy');
|
|
437
|
+
const parser = createJsToSqlParser(context);
|
|
438
|
+
const ast = parser.parse(formula);
|
|
439
|
+
const sql = parser.toSql(ast);
|
|
440
|
+
expect(sql).toBe(expectedSql);
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
test('should transform CEILING function to Sql CEIL function', () => {
|
|
444
|
+
const formula = `CEILING(Amount)`;
|
|
445
|
+
const expectedSql = `CEILING([Amount])`;
|
|
446
|
+
const context = createMockContext(['Amount'], 'CeilAmount');
|
|
447
|
+
const parser = createJsToSqlParser(context);
|
|
448
|
+
const ast = parser.parse(formula);
|
|
449
|
+
const sql = parser.toSql(ast);
|
|
450
|
+
expect(sql).toBe(expectedSql);
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
test('should transform DIVIDE function to Sql DIVIDE function', () => {
|
|
454
|
+
const formula = `DIVIDE(Amount, 100)`;
|
|
455
|
+
const expectedSql = `CASE WHEN CAST(100 AS FLOAT) = 0 THEN NULL ELSE CAST([Amount] AS FLOAT) / CAST(100 AS FLOAT) END`;
|
|
456
|
+
const context = createMockContext(['Amount'], 'DivideAmount');
|
|
457
|
+
const parser = createJsToSqlParser(context);
|
|
458
|
+
const ast = parser.parse(formula);
|
|
459
|
+
const sql = parser.toSql(ast);
|
|
460
|
+
expect(sql).toBe(expectedSql);
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
test('should transform INDEXOF function to Sql INDEXOF function', () => {
|
|
464
|
+
const formula = `INDEXOF([Amount, 10000, 20000], 10000)`;
|
|
465
|
+
const expectedSql = `CASE WHEN [Amount] = 10000 THEN 0 WHEN 10000 = 10000 THEN 1 WHEN 20000 = 10000 THEN 2 ELSE -1 END`;
|
|
466
|
+
const context = createMockContext(['Amount'], 'IndexOfAmount');
|
|
467
|
+
const parser = createJsToSqlParser(context);
|
|
468
|
+
const ast = parser.parse(formula);
|
|
469
|
+
const sql = parser.toSql(ast);
|
|
470
|
+
expect(sql).toBe(expectedSql);
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
test('should transform IN function to Sql IN function', () => {
|
|
474
|
+
const formula = `IN(First_Name,['saranya','srinidhi'])`;
|
|
475
|
+
const expectedSql = `CASE WHEN [First_Name] IN ('saranya', 'srinidhi') THEN 1 ELSE 0 END`;
|
|
476
|
+
const context = createMockContext(['First_Name'], '[saranya,srinidhi]');
|
|
477
|
+
const parser = createJsToSqlParser(context);
|
|
478
|
+
const ast = parser.parse(formula);
|
|
479
|
+
const sql = parser.toSql(ast);
|
|
480
|
+
expect(sql).toBe(expectedSql);
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
test('should transform ISNUMBER function to Sql ISNUMERIC function', () => {
|
|
484
|
+
const formula = `ISNUMBER(Amount)`;
|
|
485
|
+
const expectedSql = `ISNUMERIC([Amount])`;
|
|
486
|
+
const context = createMockContext(['Amount'], 'IsNumericAmount');
|
|
487
|
+
const parser = createJsToSqlParser(context);
|
|
488
|
+
const ast = parser.parse(formula);
|
|
489
|
+
const sql = parser.toSql(ast);
|
|
490
|
+
expect(sql).toBe(expectedSql);
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
test('should transform EXP function to Sql EXP function', () => {
|
|
494
|
+
const formula = `EXP(Amount)`;
|
|
495
|
+
const expectedSql = `EXP([Amount])`;
|
|
496
|
+
const context = createMockContext(['Amount'], 'ExpAmount');
|
|
497
|
+
const parser = createJsToSqlParser(context);
|
|
498
|
+
const ast = parser.parse(formula);
|
|
499
|
+
const sql = parser.toSql(ast);
|
|
500
|
+
expect(sql).toBe(expectedSql);
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
test('should transform FLOOR function to Sql FLOOR function', () => {
|
|
504
|
+
const formula = `FLOOR(Amount)`;
|
|
505
|
+
const expectedSql = `FLOOR([Amount])`;
|
|
506
|
+
const context = createMockContext(['Amount'], 'FloorAmount');
|
|
507
|
+
const parser = createJsToSqlParser(context);
|
|
508
|
+
const ast = parser.parse(formula);
|
|
509
|
+
const sql = parser.toSql(ast);
|
|
510
|
+
expect(sql).toBe(expectedSql);
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
test('should transform LOG function to Sql LOG function', () => {
|
|
514
|
+
const formula = `LOG(Amount)`;
|
|
515
|
+
const expectedSql = `LOG([Amount])`;
|
|
516
|
+
const context = createMockContext(['Amount'], 'LogAmount');
|
|
517
|
+
const parser = createJsToSqlParser(context);
|
|
518
|
+
const ast = parser.parse(formula);
|
|
519
|
+
const sql = parser.toSql(ast);
|
|
520
|
+
expect(sql).toBe(expectedSql);
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
test('should transform MAX function to Sql MAX function', () => {
|
|
524
|
+
const formula = `MAX(M1, M2, M3)`;
|
|
525
|
+
const expectedSql = `GREATEST([M1], [M2], [M3])`;
|
|
526
|
+
const context = createMockContext(['M1', 'M2', 'M3'], 'MaxAmount');
|
|
527
|
+
const parser = createJsToSqlParser(context);
|
|
528
|
+
const ast = parser.parse(formula);
|
|
529
|
+
const sql = parser.toSql(ast);
|
|
530
|
+
expect(sql).toBe(expectedSql);
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
test('should transform MIN function to Sql MIN function', () => {
|
|
534
|
+
const formula = `MIN(M1, M2, M3)`;
|
|
535
|
+
const expectedSql = `LEAST([M1], [M2], [M3])`;
|
|
536
|
+
const context = createMockContext(['M1', 'M2', 'M3'], 'MinAmount');
|
|
537
|
+
const parser = createJsToSqlParser(context);
|
|
538
|
+
const ast = parser.parse(formula);
|
|
539
|
+
const sql = parser.toSql(ast);
|
|
540
|
+
expect(sql).toBe(expectedSql);
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
test('should transform MOD function to Sql MOD function', () => {
|
|
544
|
+
const formula = `MOD(Amount, 100)`;
|
|
545
|
+
const expectedSql = `[Amount] % 100`;
|
|
546
|
+
const context = createMockContext(['Amount'], 'ModAmount');
|
|
547
|
+
const parser = createJsToSqlParser(context);
|
|
548
|
+
const ast = parser.parse(formula);
|
|
549
|
+
const sql = parser.toSql(ast);
|
|
550
|
+
expect(sql).toBe(expectedSql);
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
test('should transform ODD function to Sql ODD function', () => {
|
|
554
|
+
const formula = `ODD(Amount)`;
|
|
555
|
+
const expectedSql = `CASE WHEN [Amount] % 2 = 1 THEN [Amount] ELSE [Amount] + 1 END`;
|
|
556
|
+
const context = createMockContext(['Amount'], 'OddAmount');
|
|
557
|
+
const parser = createJsToSqlParser(context);
|
|
558
|
+
const ast = parser.parse(formula);
|
|
559
|
+
const sql = parser.toSql(ast);
|
|
560
|
+
expect(sql).toBe(expectedSql);
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
test('should transform EVEN function to Sql EVEN function', () => {
|
|
564
|
+
const formula = `EVEN(Amount)`;
|
|
565
|
+
const expectedSql = `CASE WHEN CAST(FLOOR([Amount]) AS INT) % 2 = 0 THEN CAST(FLOOR([Amount]) AS INT) ELSE CAST(FLOOR([Amount]) AS INT) + 1 END`;
|
|
566
|
+
const context = createMockContext(['Amount'], 'EvenAmount');
|
|
567
|
+
const parser = createJsToSqlParser(context);
|
|
568
|
+
const ast = parser.parse(formula);
|
|
569
|
+
const sql = parser.toSql(ast);
|
|
570
|
+
expect(sql).toBe(expectedSql);
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
test('should transform SWITCH function to Sql SWITCH function', () => {
|
|
574
|
+
const formula = `SWITCH(Age, 30, "Young", 50, "Old", "Other")`;
|
|
575
|
+
const expectedSql = `CASE WHEN [Age] = 30 THEN 'Young' WHEN [Age] = 50 THEN 'Old' ELSE 'Other' END`;
|
|
576
|
+
const context = createMockContext(['Age'], 'switchColumn');
|
|
577
|
+
const parser = createJsToSqlParser(context);
|
|
578
|
+
const ast = parser.parse(formula);
|
|
579
|
+
const sql = parser.toSql(ast);
|
|
580
|
+
expect(sql).toBe(expectedSql);
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
test('should transform POW function to Sql POW function', () => {
|
|
584
|
+
const formula = `POW(Amount, 2)`;
|
|
585
|
+
const expectedSql = `POWER([Amount], 2)`;
|
|
586
|
+
const context = createMockContext(['Amount'], 'PowAmount');
|
|
587
|
+
const parser = createJsToSqlParser(context);
|
|
588
|
+
const ast = parser.parse(formula);
|
|
589
|
+
const sql = parser.toSql(ast);
|
|
590
|
+
expect(sql).toBe(expectedSql);
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
test('should transform PCT function to Sql PCT function', () => {
|
|
594
|
+
const formula = `Sales + PCT(15)`;
|
|
595
|
+
const expectedSql = `[Sales] * (1 + (CAST(15 AS FLOAT) / 100))`;
|
|
596
|
+
const context = createMockContext(['Sales'], 'PctAmount');
|
|
597
|
+
const parser = createJsToSqlParser(context);
|
|
598
|
+
const ast = parser.parse(formula);
|
|
599
|
+
const sql = parser.toSql(ast);
|
|
600
|
+
expect(sql).toBe(expectedSql);
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
test('should transform IFNA function to Sql IFNA function', () => {
|
|
604
|
+
const formula = `IFNA(Amount, 0)`;
|
|
605
|
+
const expectedSql = `COALESCE([Amount], 0)`;
|
|
606
|
+
const context = createMockContext(['Amount'], '0');
|
|
607
|
+
const parser = createJsToSqlParser(context);
|
|
608
|
+
const ast = parser.parse(formula);
|
|
609
|
+
const sql = parser.toSql(ast);
|
|
610
|
+
expect(sql).toBe(expectedSql);
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
test('should transform RAND function to Sql RAND function', () => {
|
|
614
|
+
const formula = `RAND()`;
|
|
615
|
+
const expectedSql = `RAND()`;
|
|
616
|
+
const context = createMockContext([], 'RandAmount');
|
|
617
|
+
const parser = createJsToSqlParser(context);
|
|
618
|
+
const ast = parser.parse(formula);
|
|
619
|
+
const sql = parser.toSql(ast);
|
|
620
|
+
expect(sql).toBe(expectedSql);
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
test('should transform RANDBETWEEN function to Sql RANDBETWEEN function', () => {
|
|
624
|
+
const formula = `RANDBETWEEN(100, 200)`;
|
|
625
|
+
const expectedSql = `(RAND() * (200 - 100) + 100)`;
|
|
626
|
+
const context = createMockContext([], 'RandBetweenAmount');
|
|
627
|
+
const parser = createJsToSqlParser(context);
|
|
628
|
+
const ast = parser.parse(formula);
|
|
629
|
+
const sql = parser.toSql(ast);
|
|
630
|
+
expect(sql).toBe(expectedSql);
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
test('should transform ROUND function to Sql ROUND function', () => {
|
|
634
|
+
const formula = `ROUND(Amount, 2)`;
|
|
635
|
+
const expectedSql = `ROUND([Amount], 2)`;
|
|
636
|
+
const context = createMockContext(['Amount'], 'RoundAmount');
|
|
637
|
+
const parser = createJsToSqlParser(context);
|
|
638
|
+
const ast = parser.parse(formula);
|
|
639
|
+
const sql = parser.toSql(ast);
|
|
640
|
+
expect(sql).toBe(expectedSql);
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
test('should transform SUM function to Sql SUM function', () => {
|
|
644
|
+
const formula = `SUM(M1, M2, M3)`;
|
|
645
|
+
const expectedSql = `(COALESCE([M1], 0) + COALESCE([M2], 0) + COALESCE([M3], 0))`;
|
|
646
|
+
const context = createMockContext(['M1', 'M2', 'M3'], 'SumAmount');
|
|
647
|
+
const parser = createJsToSqlParser(context);
|
|
648
|
+
const ast = parser.parse(formula);
|
|
649
|
+
const sql = parser.toSql(ast);
|
|
650
|
+
expect(sql).toBe(expectedSql);
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
test('should transform SQRT function to Sql SQRT function', () => {
|
|
654
|
+
const formula = `SQRT(Amount)`;
|
|
655
|
+
const expectedSql = `SQRT([Amount])`;
|
|
656
|
+
const context = createMockContext(['Amount'], 'SqrtAmount');
|
|
657
|
+
const parser = createJsToSqlParser(context);
|
|
658
|
+
const ast = parser.parse(formula);
|
|
659
|
+
const sql = parser.toSql(ast);
|
|
660
|
+
expect(sql).toBe(expectedSql);
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
test('should transform MEDIAN function to Sql MEDIAN function', () => {
|
|
664
|
+
const formula = `MEDIAN(M1, M2, M3)`;
|
|
665
|
+
const expectedSql = `[cte_union_Median_Amount] AS (SELECT PK, [M1] AS [val_Median_Amount] FROM $RUNTIME_TABLE_NAME UNION ALL SELECT PK, [M2] AS [val_Median_Amount] FROM $RUNTIME_TABLE_NAME UNION ALL SELECT PK, [M3] AS [val_Median_Amount] FROM $RUNTIME_TABLE_NAME), [cte_agg_Median_Amount] AS (SELECT DISTINCT PK, PERCENTILE_CONT(0.50) WITHIN GROUP(ORDER BY [val_Median_Amount]) OVER (PARTITION BY PK) AS Median_Amount FROM [cte_union_Median_Amount]), [cte_Median_Amount] AS (SELECT $RUNTIME_TABLE_NAME.*, Median_Amount FROM $RUNTIME_TABLE_NAME INNER JOIN [cte_agg_Median_Amount] ON $RUNTIME_TABLE_NAME.PK = [cte_agg_Median_Amount].PK)`;
|
|
666
|
+
const context = createMockContext(['M1', 'M2', 'M3'], 'Median_Amount');
|
|
667
|
+
const parser = createJsToSqlParser(context);
|
|
668
|
+
const ast = parser.parse(formula);
|
|
669
|
+
const sql = parser.toSql(ast);
|
|
670
|
+
expect(sql).toBe(expectedSql);
|
|
671
|
+
});
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
test('should throw error for unsupported function', () => {
|
|
675
|
+
const formula = `UNSUPPORTED_FUNCTION([Amount] > 100)`;
|
|
676
|
+
const context = createMockContext(['Amount'], 'Result');
|
|
677
|
+
const parser = createJsToSqlParser(context);
|
|
678
|
+
expect(() => parser.parse(formula)).toThrow('Unsupported function: UNSUPPORTED_FUNCTION');
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
test('should transform LOGGEDIN_EMAIL function to Sql $RUNTIME_LOGGEDIN_EMAIL function', () => {
|
|
682
|
+
const formula = `LOGGEDIN_EMAIL`;
|
|
683
|
+
const expectedSql = `'$RUNTIME_LOGGEDIN_EMAIL'`;
|
|
684
|
+
const context = createMockContext([], 'Email');
|
|
685
|
+
const parser = createJsToSqlParser(context);
|
|
686
|
+
const ast = parser.parse(formula);
|
|
687
|
+
const sql = parser.toSql(ast);
|
|
688
|
+
expect(sql).toBe(expectedSql);
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
test('should transform CURRENT_DATE function to Sql $RUNTIME_CURRENT_DATE function', () => {
|
|
692
|
+
const formula = `{{CURRENT_DATE}}`;
|
|
693
|
+
const expectedSql = `'$RUNTIME_CURRENT_DATE'`;
|
|
694
|
+
const context = createMockContext([], 'CurrentDate');
|
|
695
|
+
const parser = createJsToSqlParser(context);
|
|
696
|
+
const ast = parser.parse(formula);
|
|
697
|
+
const sql = parser.toSql(ast);
|
|
698
|
+
expect(sql).toBe(expectedSql);
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
test('should transform CURRENT_DATE function to Sql $RUNTIME_CURRENT_DATETIME function', () => {
|
|
702
|
+
const formula = `{{CURRENT_DATETIME}}`;
|
|
703
|
+
const expectedSql = `'$RUNTIME_CURRENT_DATETIME'`;
|
|
704
|
+
const context = createMockContext([], 'CurrentDateTime');
|
|
705
|
+
const parser = createJsToSqlParser(context);
|
|
706
|
+
const ast = parser.parse(formula);
|
|
707
|
+
const sql = parser.toSql(ast);
|
|
708
|
+
expect(sql).toBe(expectedSql);
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
test('should transform LOGGEDIN_NAME function to Sql $RUNTIME_LOGGEDIN_NAME function', () => {
|
|
712
|
+
const formula = `{{LOGGEDIN_NAME}}`;
|
|
713
|
+
const expectedSql = `'$RUNTIME_LOGGEDIN_NAME'`;
|
|
714
|
+
const context = createMockContext([], 'Person');
|
|
715
|
+
const parser = createJsToSqlParser(context);
|
|
716
|
+
const ast = parser.parse(formula);
|
|
717
|
+
const sql = parser.toSql(ast);
|
|
718
|
+
expect(sql).toBe(expectedSql);
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
test('should transform LOGGEDIN_EMAIL function to Sql $RUNTIME_LOGGEDIN_EMAIL function', () => {
|
|
722
|
+
const formula = `{{LOGGEDIN_EMAIL}}`;
|
|
723
|
+
const expectedSql = `'$RUNTIME_LOGGEDIN_EMAIL'`;
|
|
724
|
+
const context = createMockContext([], 'Email');
|
|
725
|
+
const parser = createJsToSqlParser(context);
|
|
726
|
+
const ast = parser.parse(formula);
|
|
727
|
+
const sql = parser.toSql(ast);
|
|
728
|
+
expect(sql).toBe(expectedSql);
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
test('should transform UUID function to Sql NEWID() function', () => {
|
|
732
|
+
const formula = `UUID`;
|
|
733
|
+
const expectedSql = `NEWID()`;
|
|
734
|
+
const context = createMockContext([], 'UniqueId');
|
|
735
|
+
const parser = createJsToSqlParser(context);
|
|
736
|
+
const ast = parser.parse(formula);
|
|
737
|
+
const sql = parser.toSql(ast);
|
|
738
|
+
expect(sql).toBe(expectedSql);
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
test('should transform FROMEXCELDATE function to Sql DATEADD() function', () => {
|
|
742
|
+
const formula = `FROMEXCELDATE(123)`;
|
|
743
|
+
const expectedSql = `DATEADD(DAY, 123 - 2, '1900-01-01')`;
|
|
744
|
+
const context = createMockContext([], '123');
|
|
745
|
+
const parser = createJsToSqlParser(context);
|
|
746
|
+
const ast = parser.parse(formula);
|
|
747
|
+
const sql = parser.toSql(ast);
|
|
748
|
+
expect(sql).toBe(expectedSql);
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
test('should transform HAS function to Sql HAS() function', () => {
|
|
752
|
+
const formula = `HAS([id,employee_id],1)`;
|
|
753
|
+
const expectedSql = `CASE WHEN [id] = 1 OR [employee_id] = 1 THEN 1 ELSE 0 END`;
|
|
754
|
+
const context = createMockContext(['id', 'employee_id'], '1');
|
|
755
|
+
const parser = createJsToSqlParser(context);
|
|
756
|
+
const ast = parser.parse(formula);
|
|
757
|
+
const sql = parser.toSql(ast);
|
|
758
|
+
expect(sql).toBe(expectedSql);
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
test('should transform HAS_SOME function to Sql HAS_SOME() function', () => {
|
|
762
|
+
const formula = `HAS_SOME([id,employee_id],[1,2])`;
|
|
763
|
+
const expectedSql = `CASE WHEN [id] = 1 OR [id] = 2 OR [employee_id] = 1 OR [employee_id] = 2 THEN 1 ELSE 0 END`;
|
|
764
|
+
const context = createMockContext(['id', 'employee_id'], '[1,2]');
|
|
765
|
+
const parser = createJsToSqlParser(context);
|
|
766
|
+
const ast = parser.parse(formula);
|
|
767
|
+
const sql = parser.toSql(ast);
|
|
768
|
+
expect(sql).toBe(expectedSql);
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
test('should transform HAS_ALL function to Sql HAS_ALL() function', () => {
|
|
772
|
+
const formula = `HAS_ALL([id,employee_id],[1,2])`;
|
|
773
|
+
const expectedSql = `CASE WHEN [id] = 1 OR [employee_id] = 1 OR [id] = 2 OR [employee_id] = 2 THEN 1 ELSE 0 END`;
|
|
774
|
+
const context = createMockContext(['id', 'employee_id'], '[1,2]');
|
|
775
|
+
const parser = createJsToSqlParser(context);
|
|
776
|
+
const ast = parser.parse(formula);
|
|
777
|
+
const sql = parser.toSql(ast);
|
|
778
|
+
expect(sql).toBe(expectedSql);
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
test('should transform FIND function to SQL', () => {
|
|
782
|
+
const formula = `FIND("T", Name)`;
|
|
783
|
+
const expectedSql = `CHARINDEX('T', [Name])`;
|
|
784
|
+
const context = createMockContext(['Name'], 'FindName');
|
|
785
|
+
const parser = createJsToSqlParser(context);
|
|
786
|
+
const ast = parser.parse(formula);
|
|
787
|
+
const sql = parser.toSql(ast);
|
|
788
|
+
expect(sql).toBe(expectedSql);
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
test('should transform FIND with start argument to SQL', () => {
|
|
792
|
+
const formula = `FIND("T", Name, 5)`;
|
|
793
|
+
const expectedSql = `CHARINDEX('T', [Name], 5)`;
|
|
794
|
+
const context = createMockContext(['Name'], 'FindNameStart');
|
|
795
|
+
const parser = createJsToSqlParser(context);
|
|
796
|
+
const ast = parser.parse(formula);
|
|
797
|
+
const sql = parser.toSql(ast);
|
|
798
|
+
expect(sql).toBe(expectedSql);
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
test('should transform nested FIND inside LEFT', () => {
|
|
802
|
+
const formula = `LEFT(Name, FIND("T", Name) - 1)`;
|
|
803
|
+
const expectedSql = `LEFT([Name], (COALESCE(CHARINDEX('T', [Name]), 0) - COALESCE(1, 0)))`;
|
|
804
|
+
const context = createMockContext(['Name'], 'FindNested');
|
|
805
|
+
const parser = createJsToSqlParser(context);
|
|
806
|
+
const ast = parser.parse(formula);
|
|
807
|
+
const sql = parser.toSql(ast);
|
|
808
|
+
expect(sql).toBe(expectedSql);
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
test('should transform nested FIND inside MID', () => {
|
|
812
|
+
const formula = `MID(Name, FIND("T", Name) + 1, LEN(Name))`;
|
|
813
|
+
const expectedSql = `SUBSTRING([Name], (COALESCE(CHARINDEX('T', [Name]), 0) + COALESCE(1, 0)), LEN([Name]))`;
|
|
814
|
+
const context = createMockContext(['Name'], 'FindMid');
|
|
815
|
+
const parser = createJsToSqlParser(context);
|
|
816
|
+
const ast = parser.parse(formula);
|
|
817
|
+
const sql = parser.toSql(ast);
|
|
818
|
+
expect(sql).toBe(expectedSql);
|
|
819
|
+
});
|
|
820
|
+
});
|