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,180 @@
|
|
|
1
|
+
// DateFilterFactory.ts
|
|
2
|
+
import { IGroupFilter } from '../filters/filter-types';
|
|
3
|
+
import { EDateRangeRelativeFilterCondition } from '../query-builder/SuperFilterBuilder';
|
|
4
|
+
import { getDateFunctions } from './dateFunction';
|
|
5
|
+
|
|
6
|
+
type PeriodConfig = {
|
|
7
|
+
startExpr: () => string;
|
|
8
|
+
shiftFn: (expr: string, amount: number) => string;
|
|
9
|
+
isCalendar: boolean;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export enum Period {
|
|
13
|
+
DAYS = 'DAYS',
|
|
14
|
+
WEEKS = 'WEEKS',
|
|
15
|
+
CALENDER_WEEKS = 'CALENDER_WEEKS',
|
|
16
|
+
MONTHS = 'MONTHS',
|
|
17
|
+
CALENDER_MONTHS = 'CALENDER_MONTHS',
|
|
18
|
+
CALENDER_QUARTERS = 'CALENDER_QUARTERS',
|
|
19
|
+
CALENDER_YEARS = 'CALENDER_YEARS',
|
|
20
|
+
FISCAL_QUARTER = 'FISCAL_QUARTER',
|
|
21
|
+
FISCAL_YEAR = 'FISCAL_YEAR',
|
|
22
|
+
YEARS = 'YEARS',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Centralized period configs
|
|
27
|
+
* @param today :today expression
|
|
28
|
+
* @param fiscalShift :fiscal shift
|
|
29
|
+
* @returns :period configs <object <string, PeriodConfig>>
|
|
30
|
+
*/
|
|
31
|
+
const getPeriodConfigs = (today: string, fiscalShift = 0): Record<Period, PeriodConfig> => {
|
|
32
|
+
const fns = getDateFunctions();
|
|
33
|
+
return {
|
|
34
|
+
[Period.DAYS]: {
|
|
35
|
+
startExpr: () => today,
|
|
36
|
+
shiftFn: (e, a) => fns.dateAdd(e, a, 'day'),
|
|
37
|
+
isCalendar: false,
|
|
38
|
+
},
|
|
39
|
+
[Period.WEEKS]: {
|
|
40
|
+
startExpr: () => today,
|
|
41
|
+
shiftFn: (e, a) => fns.dateAdd(e, a * 7, 'day'),
|
|
42
|
+
isCalendar: false,
|
|
43
|
+
},
|
|
44
|
+
[Period.CALENDER_WEEKS]: {
|
|
45
|
+
startExpr: () => fns.startOfWeek!(today),
|
|
46
|
+
shiftFn: (e, a) => fns.dateAdd(e, a * 7, 'day'),
|
|
47
|
+
isCalendar: true,
|
|
48
|
+
},
|
|
49
|
+
[Period.MONTHS]: {
|
|
50
|
+
startExpr: () => today,
|
|
51
|
+
shiftFn: (e, a) => fns.dateAdd(e, a, 'month'),
|
|
52
|
+
isCalendar: false,
|
|
53
|
+
},
|
|
54
|
+
[Period.CALENDER_MONTHS]: {
|
|
55
|
+
startExpr: () => fns.dateTrunc('month', today),
|
|
56
|
+
shiftFn: (e, a) => fns.dateAdd(e, a, 'month'),
|
|
57
|
+
isCalendar: true,
|
|
58
|
+
},
|
|
59
|
+
[Period.CALENDER_QUARTERS]: {
|
|
60
|
+
startExpr: () => fns.dateTrunc('quarter', today),
|
|
61
|
+
shiftFn: (e, a) => fns.dateAdd(e, a * 3, 'month'),
|
|
62
|
+
isCalendar: true,
|
|
63
|
+
},
|
|
64
|
+
[Period.CALENDER_YEARS]: {
|
|
65
|
+
startExpr: () => fns.dateTrunc('year', today),
|
|
66
|
+
shiftFn: (e, a) => fns.dateAdd(e, a, 'year'),
|
|
67
|
+
isCalendar: true,
|
|
68
|
+
},
|
|
69
|
+
[Period.FISCAL_QUARTER]: {
|
|
70
|
+
startExpr: () =>
|
|
71
|
+
fns.dateAdd(
|
|
72
|
+
fns.dateTrunc('quarter', fns.dateAdd(today, -fiscalShift, 'month')),
|
|
73
|
+
fiscalShift,
|
|
74
|
+
'month',
|
|
75
|
+
),
|
|
76
|
+
shiftFn: (e, a) => fns.dateAdd(e, a * 3, 'month'),
|
|
77
|
+
isCalendar: true,
|
|
78
|
+
},
|
|
79
|
+
[Period.FISCAL_YEAR]: {
|
|
80
|
+
startExpr: () =>
|
|
81
|
+
fns.dateAdd(
|
|
82
|
+
fns.dateTrunc('year', fns.dateAdd(today, -fiscalShift, 'month')),
|
|
83
|
+
fiscalShift,
|
|
84
|
+
'month',
|
|
85
|
+
),
|
|
86
|
+
shiftFn: (e, a) => fns.dateAdd(e, a, 'year'),
|
|
87
|
+
isCalendar: true,
|
|
88
|
+
},
|
|
89
|
+
[Period.YEARS]: {
|
|
90
|
+
startExpr: () => today,
|
|
91
|
+
shiftFn: (e, a) => fns.dateAdd(e, a, 'year'),
|
|
92
|
+
isCalendar: false,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// Base class for date filter factor
|
|
98
|
+
export class DateFilterFactory {
|
|
99
|
+
static build(column: string, filter: IGroupFilter): string {
|
|
100
|
+
const fns = getDateFunctions();
|
|
101
|
+
const today = fns.today;
|
|
102
|
+
|
|
103
|
+
const dt = filter.dateTimeFilter;
|
|
104
|
+
if (!dt || !dt.period || !dt.relativeDateFilter) throw new Error('Invalid date filter');
|
|
105
|
+
|
|
106
|
+
const fiscalShift = dt.fiscalYearStartMonth ?? 0;
|
|
107
|
+
const configs = getPeriodConfigs(today, fiscalShift);
|
|
108
|
+
|
|
109
|
+
const periodKey = this.resolvePeriodKey(dt.period, dt.relativeDateFilter);
|
|
110
|
+
const cfg = configs[periodKey];
|
|
111
|
+
if (!cfg) throw new Error(`Unsupported period: ${periodKey}`);
|
|
112
|
+
|
|
113
|
+
const duration = dt.duration ?? 1;
|
|
114
|
+
|
|
115
|
+
const { startExpr, endExpr } = this.resolveDateRangeExpressions({
|
|
116
|
+
relativeDateFilter: dt.relativeDateFilter,
|
|
117
|
+
cfg,
|
|
118
|
+
fns,
|
|
119
|
+
today,
|
|
120
|
+
duration,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return `(${column} >= ${startExpr} AND ${column} < ${endExpr})`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private static resolvePeriodKey(
|
|
127
|
+
period: string,
|
|
128
|
+
relativeDateFilter: EDateRangeRelativeFilterCondition,
|
|
129
|
+
): Period {
|
|
130
|
+
if (relativeDateFilter === EDateRangeRelativeFilterCondition.IS_IN_THIS) {
|
|
131
|
+
switch (period) {
|
|
132
|
+
case Period.WEEKS:
|
|
133
|
+
return Period.CALENDER_WEEKS;
|
|
134
|
+
case Period.MONTHS:
|
|
135
|
+
return Period.CALENDER_MONTHS;
|
|
136
|
+
case 'QUARTERS':
|
|
137
|
+
return Period.CALENDER_QUARTERS;
|
|
138
|
+
case Period.YEARS:
|
|
139
|
+
return Period.CALENDER_YEARS;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return period as Period;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private static resolveDateRangeExpressions(params: {
|
|
146
|
+
relativeDateFilter: EDateRangeRelativeFilterCondition;
|
|
147
|
+
cfg: PeriodConfig;
|
|
148
|
+
fns: ReturnType<typeof getDateFunctions>;
|
|
149
|
+
today: string;
|
|
150
|
+
duration: number;
|
|
151
|
+
}): { startExpr: string; endExpr: string } {
|
|
152
|
+
const { relativeDateFilter, cfg, fns, today, duration } = params;
|
|
153
|
+
const startOfPeriod = cfg.startExpr();
|
|
154
|
+
|
|
155
|
+
switch (relativeDateFilter) {
|
|
156
|
+
case EDateRangeRelativeFilterCondition.IS_IN_THIS:
|
|
157
|
+
return {
|
|
158
|
+
startExpr: startOfPeriod,
|
|
159
|
+
endExpr: cfg.shiftFn(startOfPeriod, 1),
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
case EDateRangeRelativeFilterCondition.IS_IN_THE_LAST:
|
|
163
|
+
return {
|
|
164
|
+
startExpr: cfg.shiftFn(cfg.isCalendar ? startOfPeriod : today, -duration),
|
|
165
|
+
endExpr: cfg.isCalendar ? startOfPeriod : today,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
case EDateRangeRelativeFilterCondition.IS_IN_THE_NEXT:
|
|
169
|
+
const baseNext = cfg.isCalendar ? startOfPeriod : today;
|
|
170
|
+
const startExpr = cfg.isCalendar ? cfg.shiftFn(baseNext, 1) : fns.dateAdd(today, 1, 'day');
|
|
171
|
+
return {
|
|
172
|
+
startExpr,
|
|
173
|
+
endExpr: cfg.shiftFn(startExpr, duration),
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
default:
|
|
177
|
+
throw new Error(`Unsupported relative date filter: ${relativeDateFilter}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// dateFunctions.ts
|
|
2
|
+
|
|
3
|
+
export interface DateFunctions {
|
|
4
|
+
today: string;
|
|
5
|
+
dateAdd(expr: string, amount: number, unit: string): string;
|
|
6
|
+
dateTrunc(unit: string, expr: string): string;
|
|
7
|
+
startOfWeek?(expr: string): string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
abstract class BaseDateFunctions implements DateFunctions {
|
|
11
|
+
abstract today: string;
|
|
12
|
+
abstract dateAdd(expr: string, amount: number, unit: string): string;
|
|
13
|
+
abstract dateTrunc(unit: string, expr: string): string;
|
|
14
|
+
startOfWeek?(expr: string): string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class FabricSQLDateFunctions extends BaseDateFunctions {
|
|
18
|
+
today = 'CURRENT_DATE';
|
|
19
|
+
dateAdd = (expr: any, amount: any, unit: string) =>
|
|
20
|
+
`DATEADD(${unit.toUpperCase()}, ${amount}, ${expr})`;
|
|
21
|
+
dateTrunc(unit: string, expr: string) {
|
|
22
|
+
const truncMap: Record<string, string> = {
|
|
23
|
+
week: `DATEADD(DAY, -DATEPART(WEEKDAY, ${expr}) + 1, ${expr})`,
|
|
24
|
+
month: `DATEFROMPARTS(YEAR(${expr}), MONTH(${expr}), 1)`,
|
|
25
|
+
quarter: `DATEADD(QUARTER, DATEDIFF(QUARTER, 0, ${expr}), 0)`,
|
|
26
|
+
year: `DATEFROMPARTS(YEAR(${expr}), 1, 1)`,
|
|
27
|
+
};
|
|
28
|
+
return truncMap[unit] ?? expr;
|
|
29
|
+
}
|
|
30
|
+
startOfWeek = (expr: any) => `DATEADD(DAY, -DATEPART(WEEKDAY, ${expr}) + 1, ${expr})`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Factory function
|
|
34
|
+
export const getDateFunctions = (): DateFunctions => {
|
|
35
|
+
return new FabricSQLDateFunctions();
|
|
36
|
+
};
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { JoinExpressions } from './filters/filter-types';
|
|
2
|
+
import { IMDMColumnConfigWithParsedMeta, ParseContext } from './js-lib/ParseContext';
|
|
3
|
+
import { RuntimeVariables } from './query-builder/QueryBuilder';
|
|
4
|
+
import XXH from 'xxhashjs';
|
|
5
|
+
import { Binary, Case, ExpressionValue, SqlFunction } from './sql-types';
|
|
6
|
+
import {
|
|
7
|
+
COLUMN_TYPE_TO_STRING,
|
|
8
|
+
COMPARISON_OPERATORS,
|
|
9
|
+
ECustomColumnType,
|
|
10
|
+
EDataType,
|
|
11
|
+
ESqlDateExpression,
|
|
12
|
+
ESqlMathExpression,
|
|
13
|
+
ESqlWindowExpression,
|
|
14
|
+
FUNCTION_RETURN_TYPE,
|
|
15
|
+
MATH_OPERATORS,
|
|
16
|
+
NullableValueType,
|
|
17
|
+
OPERATOR_MAP,
|
|
18
|
+
} from './constants';
|
|
19
|
+
import { RUNTIME_CURRENT_DATE } from './runtime_var';
|
|
20
|
+
|
|
21
|
+
function wrapPart(part: string, wrapper: string): string {
|
|
22
|
+
if (wrapper === '`') return `\`${part}\``;
|
|
23
|
+
if (wrapper === '[') return `[${part}]`;
|
|
24
|
+
return `"${part}"`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function formatNameByWrapper(name: string, wrapper: string): string {
|
|
28
|
+
return name
|
|
29
|
+
.split('.')
|
|
30
|
+
.map((part) => wrapPart(part, wrapper))
|
|
31
|
+
.join('.');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function formatDBEntityName(name: string): string {
|
|
35
|
+
return formatNameByWrapper(name, '[');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function getEntityNameFormatter(): (name: string, type?: string) => string {
|
|
39
|
+
const baseFormatter = (name: string) => {
|
|
40
|
+
return formatNameByWrapper(name, '[');
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
return (name: string, type?: string) => {
|
|
44
|
+
if (type === 'bit') {
|
|
45
|
+
return `CAST(${baseFormatter(name)} AS int) as ${baseFormatter(name)}`;
|
|
46
|
+
}
|
|
47
|
+
return baseFormatter(name);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function resolveRuntimeVariables(expr: string, runtimeVariables: RuntimeVariables): string {
|
|
52
|
+
// regular expression to match words starting with $ and containing only word characters
|
|
53
|
+
return expr.replace(
|
|
54
|
+
/\$\w+/g,
|
|
55
|
+
(match) => runtimeVariables[match as keyof RuntimeVariables] ?? match,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function hashEncrypt(text: string): string {
|
|
60
|
+
const seed = 0xabcd;
|
|
61
|
+
const hash64 = XXH.h64(text, seed);
|
|
62
|
+
return hash64.toString(16).slice(0, 8).padStart(8, '0');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function getDeprecatedFormulaId(columnName: string): string {
|
|
66
|
+
return columnName.replace(/\W+/g, '__');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function getFormulaId(columnName: string): string {
|
|
70
|
+
const sanitizedName = columnName.replace(/\W+/g, '__');
|
|
71
|
+
const hashKey = hashEncrypt(columnName).slice(0, 8);
|
|
72
|
+
return `${sanitizedName}_${hashKey}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function getDeprecatedFormulaIdColumnMap(
|
|
76
|
+
columnConfigMap: Record<string, IMDMColumnConfigWithParsedMeta>,
|
|
77
|
+
): Record<string, string> {
|
|
78
|
+
const formulaIdColumnMap = Object.values(columnConfigMap as Record<string, any>).reduce(
|
|
79
|
+
(acc, column) => {
|
|
80
|
+
const columnName = column?.columnName;
|
|
81
|
+
const sanitizedColumnName = getDeprecatedFormulaId(columnName);
|
|
82
|
+
if (sanitizedColumnName && columnName) {
|
|
83
|
+
acc[sanitizedColumnName] = columnName;
|
|
84
|
+
}
|
|
85
|
+
return acc;
|
|
86
|
+
},
|
|
87
|
+
{} as Record<string, string>,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
return formulaIdColumnMap;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function getFormulaIdColumnMap(
|
|
94
|
+
columnConfigMap: Record<string, IMDMColumnConfigWithParsedMeta>,
|
|
95
|
+
): Record<string, string> {
|
|
96
|
+
const formulaIdColumnMap = Object.values(columnConfigMap as Record<string, any>).reduce(
|
|
97
|
+
(acc, column) => {
|
|
98
|
+
const columnName = column?.columnName;
|
|
99
|
+
const sanitizedColumnName = getFormulaId(columnName);
|
|
100
|
+
if (sanitizedColumnName && columnName) {
|
|
101
|
+
acc[sanitizedColumnName] = columnName;
|
|
102
|
+
}
|
|
103
|
+
return acc;
|
|
104
|
+
},
|
|
105
|
+
{} as Record<string, string>,
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
return formulaIdColumnMap;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function getFormattedTableName(databaseDetails: Record<string, any>): string {
|
|
112
|
+
const { database, schema, dataTableName } = databaseDetails;
|
|
113
|
+
|
|
114
|
+
const tableName = `${database}.${schema}.${dataTableName}`;
|
|
115
|
+
return formatDBEntityName(tableName);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function getCurrentDate(): string {
|
|
119
|
+
return new Date().toISOString().split('T')[0];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function getCurrentDateTime(): string {
|
|
123
|
+
return new Date().toISOString();
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Gets the join expressions from the join config
|
|
127
|
+
* @returns An array of join expressions in SQL format
|
|
128
|
+
*/
|
|
129
|
+
export function getJoinExpressions(
|
|
130
|
+
joinClauses: JoinExpressions,
|
|
131
|
+
databaseDetails: Record<string, string>,
|
|
132
|
+
): string[] {
|
|
133
|
+
const { joinRelation, alias } = joinClauses || {};
|
|
134
|
+
|
|
135
|
+
if (!Array.isArray(joinRelation) || joinRelation.length === 0) {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
const entityNameFormatter = getEntityNameFormatter();
|
|
139
|
+
const { database } = databaseDetails;
|
|
140
|
+
const formattedDatabaseName = database ? `${entityNameFormatter(database)}.` : '';
|
|
141
|
+
const mainTablePrefix = alias ? `${entityNameFormatter(alias)}.` : '';
|
|
142
|
+
|
|
143
|
+
return joinRelation.map((join) => {
|
|
144
|
+
const formattedSchema = join?.schema ? entityNameFormatter(join.schema) : undefined;
|
|
145
|
+
const formattedTable = entityNameFormatter(join.table);
|
|
146
|
+
const qualifiedJoinTable = formattedSchema
|
|
147
|
+
? `${formattedDatabaseName}${formattedSchema}.${formattedTable}`
|
|
148
|
+
: formattedTable;
|
|
149
|
+
const joinAlias = entityNameFormatter(join.alias ?? join.table);
|
|
150
|
+
|
|
151
|
+
// Build left & right columns
|
|
152
|
+
const leftCol = `${mainTablePrefix}${entityNameFormatter(join.id)}`;
|
|
153
|
+
const rightCol = `${joinAlias}.${entityNameFormatter(join.joinId)}`;
|
|
154
|
+
|
|
155
|
+
// Build join target: always alias the table
|
|
156
|
+
const joinTarget = `${qualifiedJoinTable} ${joinAlias}`;
|
|
157
|
+
|
|
158
|
+
return `${join.joinType.toUpperCase()} JOIN ${joinTarget} ON ${leftCol} = ${rightCol}`;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Strips the 'WHERE' clause from the SQL query.
|
|
164
|
+
* - If where clause is not present, returns the original query.
|
|
165
|
+
* - If where clause is present, returns the part of the query after the 'WHERE' clause.
|
|
166
|
+
*/
|
|
167
|
+
export function stripWhereClause(sqlQuery: string): string {
|
|
168
|
+
const queryInUpperCase = sqlQuery.toUpperCase();
|
|
169
|
+
const whereLabel = 'WHERE';
|
|
170
|
+
// since query generated by Knex starts with 'SELECT' and includes 'WHERE' in the query,
|
|
171
|
+
// we need to slice that part out to just get the filter condition.
|
|
172
|
+
const startIndex = queryInUpperCase.indexOf(whereLabel);
|
|
173
|
+
if (startIndex === -1) {
|
|
174
|
+
return sqlQuery;
|
|
175
|
+
}
|
|
176
|
+
return sqlQuery.slice(startIndex + whereLabel.length).trim();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Extracts the target type of a CAST expression from a given Binary expression.
|
|
181
|
+
* The target type is the right-hand side of the AS operator, e.g. 'INT' in 'CAST(x AS INT)'.
|
|
182
|
+
* If the given expression does not represent a CAST expression, returns null.
|
|
183
|
+
* @param {Binary} arg - The Binary expression to extract the target type from.
|
|
184
|
+
* @returns {string | null} - The target type of the CAST expression, or null if it is not a CAST expression.
|
|
185
|
+
*/
|
|
186
|
+
export function extractCastTargetType(arg: Binary): string | null {
|
|
187
|
+
if (arg?.type === 'binary_expr' && arg.operator === 'AS' && arg.right?.type === 'default') {
|
|
188
|
+
return arg.right.value;
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Maps a SQL cast type to a Fabric data type
|
|
195
|
+
* @param {string} type - The SQL cast type to map.
|
|
196
|
+
* @returns {NullableValueType} - The corresponding Fabric data type.
|
|
197
|
+
*/
|
|
198
|
+
export function mapSqlTypeToDataType(type: string): NullableValueType {
|
|
199
|
+
// Convert SQL type to Fabric data type
|
|
200
|
+
const dataType = String(type)
|
|
201
|
+
.replace(/\(.*\)/, '')
|
|
202
|
+
.trim()
|
|
203
|
+
.toUpperCase();
|
|
204
|
+
switch (dataType) {
|
|
205
|
+
// Numeric types supported in Fabric
|
|
206
|
+
case 'INT':
|
|
207
|
+
case 'INTEGER':
|
|
208
|
+
case 'BIGINT':
|
|
209
|
+
case 'FLOAT':
|
|
210
|
+
case 'DOUBLE':
|
|
211
|
+
case 'DECIMAL':
|
|
212
|
+
case 'NUMERIC':
|
|
213
|
+
return EDataType.NUMBER;
|
|
214
|
+
|
|
215
|
+
// Date and time types supported in Fabric
|
|
216
|
+
case 'DATE':
|
|
217
|
+
case 'TIMESTAMP':
|
|
218
|
+
case 'DATETIME':
|
|
219
|
+
return EDataType.DATE;
|
|
220
|
+
|
|
221
|
+
// Boolean types supported in Fabric
|
|
222
|
+
case 'BOOLEAN':
|
|
223
|
+
case 'BOOL':
|
|
224
|
+
case 'BIT':
|
|
225
|
+
return EDataType.BOOLEAN;
|
|
226
|
+
|
|
227
|
+
// String types supported in Fabric
|
|
228
|
+
case 'STRING':
|
|
229
|
+
case 'TEXT':
|
|
230
|
+
case 'VARCHAR':
|
|
231
|
+
case 'CHAR':
|
|
232
|
+
case 'NVARCHAR':
|
|
233
|
+
return EDataType.STRING;
|
|
234
|
+
|
|
235
|
+
default:
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export function isValidDate(value: string): boolean {
|
|
241
|
+
if (typeof value !== 'string') return false;
|
|
242
|
+
if (RUNTIME_CURRENT_DATE === value) return true;
|
|
243
|
+
const isoDateRegex = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/;
|
|
244
|
+
if (!isoDateRegex.test(value)) return false;
|
|
245
|
+
|
|
246
|
+
const date = new Date(value);
|
|
247
|
+
if (isNaN(date.getTime())) return false;
|
|
248
|
+
|
|
249
|
+
const [year, month, day] = value.split('-').map(Number);
|
|
250
|
+
return (
|
|
251
|
+
date.getUTCFullYear() === year && date.getUTCMonth() + 1 === month && date.getUTCDate() === day
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export function getArgType(arg: ExpressionValue, context: ParseContext): NullableValueType {
|
|
256
|
+
if (arg.type === 'column_ref') {
|
|
257
|
+
const columnName = (arg as Record<string, string>).column.replace(/[`[\]"]/g, '');
|
|
258
|
+
const column = context.columnConfigMap[columnName];
|
|
259
|
+
if (!column) return null;
|
|
260
|
+
// Handle formula columns by returning their resolved data type
|
|
261
|
+
if ((column.columnType as number) === ECustomColumnType.FORMULA) {
|
|
262
|
+
const dataType = column.columnMeta?.formulaColumnDetails?.dataType;
|
|
263
|
+
return dataType ?? null;
|
|
264
|
+
}
|
|
265
|
+
return COLUMN_TYPE_TO_STRING[column.columnType] ?? null;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (arg.type === EDataType.STRING) {
|
|
269
|
+
return isValidDate(arg.value) ? EDataType.DATE : EDataType.STRING;
|
|
270
|
+
}
|
|
271
|
+
if (arg.type === EDataType.NUMBER) return EDataType.NUMBER;
|
|
272
|
+
if (arg.type === EDataType.BOOLEAN) return EDataType.BOOLEAN;
|
|
273
|
+
if (arg.type === EDataType.NULL) return null;
|
|
274
|
+
|
|
275
|
+
if (arg.type === 'case') {
|
|
276
|
+
const resultTypes = (arg as Case).args.map((branch) =>
|
|
277
|
+
branch.type === 'when' || branch.type === 'else'
|
|
278
|
+
? getArgType(branch.result as ExpressionValue, context)
|
|
279
|
+
: null,
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
const unique = [...new Set(resultTypes)];
|
|
283
|
+
return unique.length === 1 ? unique[0] : null;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (arg.type === 'binary_expr') {
|
|
287
|
+
const operator = OPERATOR_MAP.get((arg as Binary).operator) ?? (arg as Binary).operator;
|
|
288
|
+
|
|
289
|
+
const leftType = getArgType((arg as Binary).left, context);
|
|
290
|
+
const rightType = getArgType((arg as Binary).right, context);
|
|
291
|
+
|
|
292
|
+
// Math operators
|
|
293
|
+
if (MATH_OPERATORS.has(operator)) {
|
|
294
|
+
if (leftType !== EDataType.NUMBER || rightType !== EDataType.NUMBER) {
|
|
295
|
+
context.isValid = false;
|
|
296
|
+
context.error = `Operator "${operator}" requires both operands to be numbers`;
|
|
297
|
+
}
|
|
298
|
+
return EDataType.NUMBER;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Comparison operators
|
|
302
|
+
if (COMPARISON_OPERATORS.has(operator)) {
|
|
303
|
+
if (leftType !== rightType && leftType !== null && rightType !== null) {
|
|
304
|
+
context.isValid = false;
|
|
305
|
+
context.error = `Please ensure both sides of the comparison are of the same type`;
|
|
306
|
+
}
|
|
307
|
+
return EDataType.BOOLEAN;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (arg.type === 'expr_list') {
|
|
314
|
+
const types = (arg.value as ExpressionValue[]).map((v) => getArgType(v, context));
|
|
315
|
+
return types.find((t) => t !== null) || null;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (arg.type === 'function') {
|
|
319
|
+
const fnName = (arg as SqlFunction).name.name[0].value.toUpperCase();
|
|
320
|
+
const args =
|
|
321
|
+
(arg as SqlFunction).args?.type === 'expr_list'
|
|
322
|
+
? (arg as SqlFunction).args.value
|
|
323
|
+
: [(arg as SqlFunction).args];
|
|
324
|
+
|
|
325
|
+
// Handle specific SQL functions
|
|
326
|
+
if (fnName === 'COALESCE') {
|
|
327
|
+
const types = args.map((a) => getArgType(a, context));
|
|
328
|
+
return types.find((t) => t !== null) || null;
|
|
329
|
+
} else if (fnName === 'CAST') {
|
|
330
|
+
const targetType = extractCastTargetType(args[0] as Binary);
|
|
331
|
+
return targetType ? mapSqlTypeToDataType(targetType) : null;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Resolve return type for precomputed functions
|
|
335
|
+
const returnType = FUNCTION_RETURN_TYPE[fnName];
|
|
336
|
+
if (returnType) return returnType;
|
|
337
|
+
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Handle SQL expressions
|
|
342
|
+
if (arg.type === 'sql_expr') {
|
|
343
|
+
const sqlValue = (arg as any).value;
|
|
344
|
+
|
|
345
|
+
if (Object.values(ESqlDateExpression).includes(sqlValue)) return EDataType.DATE;
|
|
346
|
+
if (Object.values(ESqlMathExpression).includes(sqlValue)) return EDataType.NUMBER;
|
|
347
|
+
if (Object.values(ESqlWindowExpression).some((expr) => sqlValue.includes(expr)))
|
|
348
|
+
return EDataType.NUMBER;
|
|
349
|
+
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return null;
|
|
354
|
+
}
|