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.
Files changed (225) hide show
  1. package/.turbo/turbo-build.log +9 -0
  2. package/.turbo/turbo-check-types.log +4 -0
  3. package/.turbo/turbo-lint.log +126 -0
  4. package/README.md +45 -0
  5. package/coverage/base.css +224 -0
  6. package/coverage/block-navigation.js +87 -0
  7. package/coverage/favicon.png +0 -0
  8. package/coverage/index.html +236 -0
  9. package/coverage/prettify.css +1 -0
  10. package/coverage/prettify.js +2 -0
  11. package/coverage/sort-arrow-sprite.png +0 -0
  12. package/coverage/sorter.js +210 -0
  13. package/coverage/src/constants.ts.html +826 -0
  14. package/coverage/src/database_types.ts.html +136 -0
  15. package/coverage/src/epm-query-builder/EpmQueryBuilder.ts.html +166 -0
  16. package/coverage/src/epm-query-builder/base/BaseAdvancedAggregations.ts.html +568 -0
  17. package/coverage/src/epm-query-builder/base/BaseAnalyticalFunctions.ts.html +694 -0
  18. package/coverage/src/epm-query-builder/base/BaseCTEGenerator.ts.html +1459 -0
  19. package/coverage/src/epm-query-builder/base/BaseCountQueryBuilder.ts.html +400 -0
  20. package/coverage/src/epm-query-builder/base/BaseMeasureBuilder.ts.html +295 -0
  21. package/coverage/src/epm-query-builder/base/BaseOrderBuilder.ts.html +670 -0
  22. package/coverage/src/epm-query-builder/base/BasePaginationBuilder.ts.html +364 -0
  23. package/coverage/src/epm-query-builder/base/BaseQueryBuilder.ts.html +238 -0
  24. package/coverage/src/epm-query-builder/base/BaseRollupBuilder.ts.html +532 -0
  25. package/coverage/src/epm-query-builder/base/BaseSqlBuilder.ts.html +601 -0
  26. package/coverage/src/epm-query-builder/base/BaseSuperFilterBuilder.ts.html +1966 -0
  27. package/coverage/src/epm-query-builder/base/BaseUtilities.ts.html +1798 -0
  28. package/coverage/src/epm-query-builder/base/ColumnRefUtils.ts.html +211 -0
  29. package/coverage/src/epm-query-builder/base/RelationshipResolver.ts.html +706 -0
  30. package/coverage/src/epm-query-builder/base/SharedFilterBuilder.ts.html +1717 -0
  31. package/coverage/src/epm-query-builder/base/index.html +326 -0
  32. package/coverage/src/epm-query-builder/constants/Aggregations.ts.html +133 -0
  33. package/coverage/src/epm-query-builder/constants/Database.ts.html +103 -0
  34. package/coverage/src/epm-query-builder/constants/Source.ts.html +106 -0
  35. package/coverage/src/epm-query-builder/constants/index.html +146 -0
  36. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbAdvancedAggregations.ts.html +286 -0
  37. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbJoinBuilder.ts.html +280 -0
  38. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbMeasureBuilder.ts.html +1924 -0
  39. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbOrderBuilder.ts.html +769 -0
  40. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbPaginationBuilder.ts.html +643 -0
  41. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbQueryBuilder.ts.html +2644 -0
  42. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbRollupBuilder.ts.html +478 -0
  43. package/coverage/src/epm-query-builder/dialects/duckdb/DuckDbSuperFilterBuilder.ts.html +1195 -0
  44. package/coverage/src/epm-query-builder/dialects/duckdb/index.html +221 -0
  45. package/coverage/src/epm-query-builder/errors/QueryBuilderErrors.ts.html +280 -0
  46. package/coverage/src/epm-query-builder/errors/index.html +116 -0
  47. package/coverage/src/epm-query-builder/index.html +116 -0
  48. package/coverage/src/epm-query-builder/interfaces/IDatabaseQueryBuilder.ts.html +100 -0
  49. package/coverage/src/epm-query-builder/interfaces/index.html +131 -0
  50. package/coverage/src/epm-query-builder/interfaces/index.ts.html +88 -0
  51. package/coverage/src/epm-query-builder/utils/format.ts.html +151 -0
  52. package/coverage/src/epm-query-builder/utils/index.html +146 -0
  53. package/coverage/src/epm-query-builder/utils/sql.ts.html +247 -0
  54. package/coverage/src/epm-query-builder/utils/validation.ts.html +124 -0
  55. package/coverage/src/epm-query-builder/validation/QueryOptionsValidator.ts.html +631 -0
  56. package/coverage/src/epm-query-builder/validation/SqlQueryValidator.ts.html +475 -0
  57. package/coverage/src/epm-query-builder/validation/index.html +131 -0
  58. package/coverage/src/filters/FilterConditionBuilder.ts.html +427 -0
  59. package/coverage/src/filters/filter-types.ts.html +484 -0
  60. package/coverage/src/filters/index.html +131 -0
  61. package/coverage/src/index.html +176 -0
  62. package/coverage/src/index.ts.html +103 -0
  63. package/coverage/src/js-lib/JsToSqlParser.ts.html +736 -0
  64. package/coverage/src/js-lib/ParseContext.ts.html +532 -0
  65. package/coverage/src/js-lib/db/azuresql/AzureSqlCallExpressionVisitor.ts.html +196 -0
  66. package/coverage/src/js-lib/db/azuresql/index.html +116 -0
  67. package/coverage/src/js-lib/db/base/ArrayExpressionVisitor.ts.html +133 -0
  68. package/coverage/src/js-lib/db/base/AssignmentExpressionVisitor.ts.html +187 -0
  69. package/coverage/src/js-lib/db/base/BinaryExpressionVisitor.ts.html +223 -0
  70. package/coverage/src/js-lib/db/base/CallExpressionVisitor.ts.html +5479 -0
  71. package/coverage/src/js-lib/db/base/IdentifierVisitor.ts.html +283 -0
  72. package/coverage/src/js-lib/db/base/LiteralVisitor.ts.html +199 -0
  73. package/coverage/src/js-lib/db/base/MemberExpressionVisitor.ts.html +193 -0
  74. package/coverage/src/js-lib/db/base/ProgramVisitor.ts.html +139 -0
  75. package/coverage/src/js-lib/db/base/UnaryExpressionVisitor.ts.html +181 -0
  76. package/coverage/src/js-lib/db/base/VisitorInterface.ts.html +103 -0
  77. package/coverage/src/js-lib/db/base/index.html +251 -0
  78. package/coverage/src/js-lib/db/bigquery/BigQueryCallExpressionVisitor.ts.html +1747 -0
  79. package/coverage/src/js-lib/db/bigquery/index.html +116 -0
  80. package/coverage/src/js-lib/db/commonTransforms.ts.html +2074 -0
  81. package/coverage/src/js-lib/db/databricks/DatabricksCallExpressionVisitor.ts.html +1303 -0
  82. package/coverage/src/js-lib/db/databricks/index.html +116 -0
  83. package/coverage/src/js-lib/db/fabricsql/FabricSqlCallExpressionVisitor.ts.html +196 -0
  84. package/coverage/src/js-lib/db/fabricsql/index.html +116 -0
  85. package/coverage/src/js-lib/db/fabricwarehouse/FabricWarehouseCallExpressionVisitor.ts.html +292 -0
  86. package/coverage/src/js-lib/db/fabricwarehouse/index.html +116 -0
  87. package/coverage/src/js-lib/db/index.html +116 -0
  88. package/coverage/src/js-lib/db/postgresql/PostgreSqlCallExpressionVisitor.ts.html +985 -0
  89. package/coverage/src/js-lib/db/postgresql/index.html +116 -0
  90. package/coverage/src/js-lib/db/redshift/RedshiftCallExpressionVisitor.ts.html +685 -0
  91. package/coverage/src/js-lib/db/redshift/index.html +116 -0
  92. package/coverage/src/js-lib/db/sample/SampleCallExpressionVisitor.ts.html +196 -0
  93. package/coverage/src/js-lib/db/sample/index.html +116 -0
  94. package/coverage/src/js-lib/db/snowflake/SnowflakeCallExpressionVisitor.ts.html +1447 -0
  95. package/coverage/src/js-lib/db/snowflake/index.html +116 -0
  96. package/coverage/src/js-lib/db/validator/FormulaValidator.ts.html +4162 -0
  97. package/coverage/src/js-lib/db/validator/index.html +116 -0
  98. package/coverage/src/js-lib/index.html +131 -0
  99. package/coverage/src/js-lib/objects/BaseObject.ts.html +169 -0
  100. package/coverage/src/js-lib/objects/DateObject.ts.html +169 -0
  101. package/coverage/src/js-lib/objects/PctObject.ts.html +178 -0
  102. package/coverage/src/js-lib/objects/index.html +146 -0
  103. package/coverage/src/query-builder/PaginationBuilder.ts.html +142 -0
  104. package/coverage/src/query-builder/QueryBuilder.ts.html +3118 -0
  105. package/coverage/src/query-builder/SuperFilterBuilder.ts.html +1969 -0
  106. package/coverage/src/query-builder/index.html +146 -0
  107. package/coverage/src/runtime_var.ts.html +109 -0
  108. package/coverage/src/sql-lib/binary_expr.ts.html +133 -0
  109. package/coverage/src/sql-lib/case.ts.html +133 -0
  110. package/coverage/src/sql-lib/column.ts.html +139 -0
  111. package/coverage/src/sql-lib/else.ts.html +124 -0
  112. package/coverage/src/sql-lib/function.ts.html +112 -0
  113. package/coverage/src/sql-lib/index.html +251 -0
  114. package/coverage/src/sql-lib/join.ts.html +127 -0
  115. package/coverage/src/sql-lib/literal.ts.html +130 -0
  116. package/coverage/src/sql-lib/select.ts.html +547 -0
  117. package/coverage/src/sql-lib/unary_expr.ts.html +112 -0
  118. package/coverage/src/sql-lib/when.ts.html +130 -0
  119. package/coverage/src/sql_query_gen.ts.html +535 -0
  120. package/coverage/src/superFilter/DateFilterFactory.ts.html +625 -0
  121. package/coverage/src/superFilter/dateFunction.ts.html +193 -0
  122. package/coverage/src/superFilter/index.html +131 -0
  123. package/coverage/src/utils.ts.html +571 -0
  124. package/dist/index.cjs +8440 -0
  125. package/dist/index.d.cts +927 -0
  126. package/dist/index.d.cts.map +1 -0
  127. package/dist/index.d.ts +927 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +8387 -0
  130. package/dist/index.js.map +1 -0
  131. package/eslint.config.js +4 -0
  132. package/jest.config.ts +44 -0
  133. package/package.json +45 -0
  134. package/src/constants.ts +247 -0
  135. package/src/epm-query-builder/EpmQueryBuilder.ts +27 -0
  136. package/src/epm-query-builder/base/BaseAdvancedAggregations.ts +161 -0
  137. package/src/epm-query-builder/base/BaseAnalyticalFunctions.ts +203 -0
  138. package/src/epm-query-builder/base/BaseCTEGenerator.ts +458 -0
  139. package/src/epm-query-builder/base/BaseCountQueryBuilder.ts +105 -0
  140. package/src/epm-query-builder/base/BaseMeasureBuilder.ts +87 -0
  141. package/src/epm-query-builder/base/BaseOrderBuilder.ts +195 -0
  142. package/src/epm-query-builder/base/BasePaginationBuilder.ts +93 -0
  143. package/src/epm-query-builder/base/BaseQueryBuilder.ts +51 -0
  144. package/src/epm-query-builder/base/BaseRollupBuilder.ts +149 -0
  145. package/src/epm-query-builder/base/BaseSqlBuilder.ts +172 -0
  146. package/src/epm-query-builder/base/BaseSuperFilterBuilder.ts +627 -0
  147. package/src/epm-query-builder/base/BaseUtilities.ts +571 -0
  148. package/src/epm-query-builder/base/ColumnRefUtils.ts +42 -0
  149. package/src/epm-query-builder/base/RelationshipResolver.ts +207 -0
  150. package/src/epm-query-builder/base/SharedFilterBuilder.ts +544 -0
  151. package/src/epm-query-builder/constants/Aggregations.ts +16 -0
  152. package/src/epm-query-builder/constants/Database.ts +6 -0
  153. package/src/epm-query-builder/constants/Source.ts +7 -0
  154. package/src/epm-query-builder/dialects/duckdb/DuckDbAdvancedAggregations.ts +67 -0
  155. package/src/epm-query-builder/dialects/duckdb/DuckDbJoinBuilder.ts +65 -0
  156. package/src/epm-query-builder/dialects/duckdb/DuckDbMeasureBuilder.ts +626 -0
  157. package/src/epm-query-builder/dialects/duckdb/DuckDbOrderBuilder.ts +228 -0
  158. package/src/epm-query-builder/dialects/duckdb/DuckDbPaginationBuilder.ts +186 -0
  159. package/src/epm-query-builder/dialects/duckdb/DuckDbQueryBuilder.ts +853 -0
  160. package/src/epm-query-builder/dialects/duckdb/DuckDbRollupBuilder.ts +131 -0
  161. package/src/epm-query-builder/dialects/duckdb/DuckDbSuperFilterBuilder.ts +370 -0
  162. package/src/epm-query-builder/errors/QueryBuilderErrors.ts +65 -0
  163. package/src/epm-query-builder/interfaces/IDatabaseQueryBuilder.ts +5 -0
  164. package/src/epm-query-builder/interfaces/index.ts +1 -0
  165. package/src/epm-query-builder/types/query-builder-types.d.ts +289 -0
  166. package/src/epm-query-builder/utils/format.ts +22 -0
  167. package/src/epm-query-builder/utils/sql.ts +54 -0
  168. package/src/epm-query-builder/utils/validation.ts +13 -0
  169. package/src/epm-query-builder/validation/QueryOptionsValidator.ts +182 -0
  170. package/src/epm-query-builder/validation/SqlQueryValidator.ts +130 -0
  171. package/src/filters/FilterConditionBuilder.ts +114 -0
  172. package/src/filters/filter-types.ts +133 -0
  173. package/src/index.ts +10 -0
  174. package/src/js-lib/JsToSqlParser.ts +217 -0
  175. package/src/js-lib/ParseContext.ts +149 -0
  176. package/src/js-lib/db/base/ArrayExpressionVisitor.ts +16 -0
  177. package/src/js-lib/db/base/AssignmentExpressionVisitor.ts +34 -0
  178. package/src/js-lib/db/base/BinaryExpressionVisitor.ts +46 -0
  179. package/src/js-lib/db/base/CallExpressionVisitor.ts +1798 -0
  180. package/src/js-lib/db/base/IdentifierVisitor.ts +66 -0
  181. package/src/js-lib/db/base/LiteralVisitor.ts +38 -0
  182. package/src/js-lib/db/base/MemberExpressionVisitor.ts +36 -0
  183. package/src/js-lib/db/base/ProgramVisitor.ts +18 -0
  184. package/src/js-lib/db/base/UnaryExpressionVisitor.ts +32 -0
  185. package/src/js-lib/db/base/VisitorInterface.ts +6 -0
  186. package/src/js-lib/db/validator/FormulaValidator.ts +1235 -0
  187. package/src/js-lib/objects/BaseObject.ts +28 -0
  188. package/src/js-lib/objects/DateObject.ts +28 -0
  189. package/src/js-lib/objects/PctObject.ts +31 -0
  190. package/src/query-builder/PaginationBuilder.ts +19 -0
  191. package/src/query-builder/QueryBuilder.ts +1035 -0
  192. package/src/query-builder/SuperFilterBuilder.ts +628 -0
  193. package/src/runtime_var.ts +8 -0
  194. package/src/sql-lib/binary_expr.ts +16 -0
  195. package/src/sql-lib/case.ts +16 -0
  196. package/src/sql-lib/column.ts +18 -0
  197. package/src/sql-lib/else.ts +13 -0
  198. package/src/sql-lib/function.ts +9 -0
  199. package/src/sql-lib/join.ts +14 -0
  200. package/src/sql-lib/literal.ts +15 -0
  201. package/src/sql-lib/select.ts +154 -0
  202. package/src/sql-lib/unary_expr.ts +9 -0
  203. package/src/sql-lib/when.ts +15 -0
  204. package/src/sql-types.d.ts +565 -0
  205. package/src/sql_query_gen.ts +150 -0
  206. package/src/superFilter/DateFilterFactory.ts +180 -0
  207. package/src/superFilter/dateFunction.ts +36 -0
  208. package/src/utils.ts +354 -0
  209. package/test-output/report/junit.xml +329 -0
  210. package/tests/JsToSqlParser.test.ts +163 -0
  211. package/tests/QueryBuilder.test.ts +1320 -0
  212. package/tests/js-lib/CallExpressionVisitor.test.ts +820 -0
  213. package/tests/mocks/MockQueryResolver.ts +14 -0
  214. package/tests/sanity.test.ts +146 -0
  215. package/tests/sql-lib/binary_expr.test.ts +75 -0
  216. package/tests/sql-lib/case.test.ts +117 -0
  217. package/tests/sql-lib/column.test.ts +87 -0
  218. package/tests/sql-lib/else.test.ts +56 -0
  219. package/tests/sql-lib/function.test.ts +96 -0
  220. package/tests/sql-lib/literal.test.ts +75 -0
  221. package/tests/sql-lib/select.test.ts +245 -0
  222. package/tests/sql-lib/unary_expr.test.ts +32 -0
  223. package/tests/utils.test.ts +13 -0
  224. package/tsconfig.json +24 -0
  225. package/tsdown.config.ts +23 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["COLUMN_TYPE_TO_STRING: Record<ECustomColumnType, NullableValueType>","FUNCTION_RETURN_TYPE: Record<string, EDataType>","parts: string[]","rangeFilterOperator: Record<RangeOperator, string>","negativeCharacterOperators: RangeOperator[]","startsWithCharacterOperators: RangeOperator[]","containsCharacterOperators: RangeOperator[]","parts: string[]","last: IGroupFilter | null","allExpressions: string[]","subQueries: string[]","whereParts: string[]","nativeColumnRules: (Rule | RuleGroup)[]","formulaColumnRules: (Rule | RuleGroup)[]","cteParts: string[]","pendingColumns: IMDMColumnConfigWithParsedMeta[]","finalQuery","formulaColumnsByDependencyLevel: IMDMColumnConfigWithParsedMeta[][]","joins: From[]","flattenedValues: ExpressionValue[]","resultTypes: string[]","DEFAULT_FUNCTION_TRANSFORMS: Record<string, (...args: any[]) => void>","elseValue: ElseType | undefined","patterns: Record<string, string>","comparisons: Binary[]","valueColumnName","whenList: {\n cond: Binary;\n result: ExpressionValue;\n type: 'when';\n }[]","andConditions: Binary[]","innerComparisons: Binary[]","AGGREGATION_TYPE_MAP: Record<string, string>","Sql.buildSqlSelect","Validation.validateRequiredFields","Sql.combineConditions","Format.formatValue","ColumnRefUtils.getTableNameFromId","ColumnRefUtils.extractColumnIdFromHierarchy","ColumnRefUtils.extractTableNameFromColumnId","Sql.buildDistinctSelect","Format.sanitizeIdentifier","Validation.isEmptyOrWhitespace","Validation.isValidIdentifier","Sql.buildLimitClause","mapAgg","parts: string[]","tupleConditions: string[]","hierarchyFunction: string","hierarchyFunction","ColumnRefUtils.getTableNameFromId","ColumnRefUtils.getColumnNameFromId","details?: Record<string, unknown>","nestedGroup: SuperFilterConfig","measureFilters: MeasureFilterConfig[]","tupleConditions: string[]","hierarchyFunction: string","hierarchyFunction","filters: {\n columnName: string;\n values: string[];\n applicationType: string;\n }[]","filterCTEs: string[]","mapAgg","condition: string","hierarchyFunction: string","resolvedNames: string[]","adjusted: FilterConfig","rangeConditions: string[]","parts: string[]","columns: string[]","measureExpr: string","columnRef: string","aggregationExpr: string","measureFilters: FilterConfig[]","clauses: string[]","conditions: string[]","rangeParts: string[]","groupingSets: string[]","dimPrefix: string[]","colPrefix: string[]","indicators: string[]","combinations: T[][]","selects: string[]","indicators: string[]","parentConditions: string[]","siblingConditions: string[]","clauses: string[]","expansions: string[]","clauses: string[]","config: RowColumnConfig","options: EpmQueryBuilderOptions","SUSPICIOUS_PATTERNS: RegExp[]","issues: string[]","edges: Edge[]","q: string[]","path: Edge[]","best: { table: string; covered: number }","joinType: JoinType","joins: JoinStep[]","query: string","selectParts: string[]","ctes: string[]","selectItems: string[]","dimensions: string[]","rkRef: string","subqueries: string[]","selectClause: string","measureRef: string","result: RankingConfig[]","measureExpr: string","refs: string[]"],"sources":["../src/constants.ts","../src/runtime_var.ts","../src/utils.ts","../src/js-lib/ParseContext.ts","../src/query-builder/PaginationBuilder.ts","../src/sql-lib/select.ts","../src/sql-lib/column.ts","../src/sql_query_gen.ts","../src/superFilter/dateFunction.ts","../src/superFilter/DateFilterFactory.ts","../src/query-builder/SuperFilterBuilder.ts","../src/query-builder/QueryBuilder.ts","../src/sql-lib/binary_expr.ts","../src/sql-lib/function.ts","../src/js-lib/objects/BaseObject.ts","../src/js-lib/objects/PctObject.ts","../src/sql-lib/when.ts","../src/sql-lib/else.ts","../src/sql-lib/case.ts","../src/sql-lib/unary_expr.ts","../src/sql-lib/join.ts","../src/js-lib/db/validator/FormulaValidator.ts","../src/js-lib/db/base/CallExpressionVisitor.ts","../src/sql-lib/literal.ts","../src/js-lib/db/base/IdentifierVisitor.ts","../src/js-lib/db/base/LiteralVisitor.ts","../src/js-lib/db/base/BinaryExpressionVisitor.ts","../src/js-lib/db/base/ArrayExpressionVisitor.ts","../src/js-lib/db/base/UnaryExpressionVisitor.ts","../src/js-lib/db/base/ProgramVisitor.ts","../src/js-lib/objects/DateObject.ts","../src/js-lib/db/base/MemberExpressionVisitor.ts","../src/js-lib/db/base/AssignmentExpressionVisitor.ts","../src/js-lib/JsToSqlParser.ts","../src/epm-query-builder/base/ColumnRefUtils.ts","../src/epm-query-builder/constants/Aggregations.ts","../src/epm-query-builder/constants/Source.ts","../src/epm-query-builder/utils/validation.ts","../src/epm-query-builder/utils/format.ts","../src/epm-query-builder/utils/sql.ts","../src/epm-query-builder/base/BaseUtilities.ts","../src/epm-query-builder/base/BaseSqlBuilder.ts","../src/epm-query-builder/base/BaseQueryBuilder.ts","../src/epm-query-builder/base/SharedFilterBuilder.ts","../src/epm-query-builder/errors/QueryBuilderErrors.ts","../src/epm-query-builder/base/BaseSuperFilterBuilder.ts","../src/epm-query-builder/base/BaseCTEGenerator.ts","../src/epm-query-builder/dialects/duckdb/DuckDbSuperFilterBuilder.ts","../src/epm-query-builder/base/BaseMeasureBuilder.ts","../src/epm-query-builder/base/BaseAnalyticalFunctions.ts","../src/epm-query-builder/base/BaseAdvancedAggregations.ts","../src/epm-query-builder/dialects/duckdb/DuckDbAdvancedAggregations.ts","../src/epm-query-builder/dialects/duckdb/DuckDbMeasureBuilder.ts","../src/epm-query-builder/base/BaseRollupBuilder.ts","../src/epm-query-builder/dialects/duckdb/DuckDbRollupBuilder.ts","../src/epm-query-builder/base/BasePaginationBuilder.ts","../src/epm-query-builder/dialects/duckdb/DuckDbPaginationBuilder.ts","../src/epm-query-builder/base/BaseOrderBuilder.ts","../src/epm-query-builder/dialects/duckdb/DuckDbOrderBuilder.ts","../src/epm-query-builder/base/BaseCountQueryBuilder.ts","../src/epm-query-builder/validation/QueryOptionsValidator.ts","../src/epm-query-builder/validation/SqlQueryValidator.ts","../src/epm-query-builder/base/RelationshipResolver.ts","../src/epm-query-builder/dialects/duckdb/DuckDbJoinBuilder.ts","../src/epm-query-builder/dialects/duckdb/DuckDbQueryBuilder.ts","../src/epm-query-builder/constants/Database.ts","../src/epm-query-builder/EpmQueryBuilder.ts"],"sourcesContent":["// Column Types\nexport enum ECustomColumnType {\n TEXT = 1,\n SINGLE_SELECT = 2,\n MULTI_SELECT = 3,\n DATE = 4,\n COMMENTS = 5,\n NUMBER = 6,\n PERSON = 7,\n TIME = 8,\n LAST_UPDATED_BY = 9,\n LAST_UPDATED_AT = 10,\n CHECKBOX = 11,\n DATETIME = 12,\n DECIMAL = 13,\n IMAGE = 14,\n URL = 15,\n EMAIL = 16,\n FORMULA = 17,\n BUTTON_COLUMN = 18,\n CURRENCY = 19,\n PHONE_NUMBER = 20,\n RATING = 21,\n ATTACHMENT = 22,\n PERCENT_SLIDER = 23,\n PERCENT = 24,\n}\n\nexport enum EDataType {\n STRING = 'string',\n NUMBER = 'number',\n DATE = 'date',\n BOOLEAN = 'boolean',\n NULL = 'null',\n}\n\nexport type NullableValueType = EDataType | null;\n\n// Column Type - Value Type Mapping\nexport const COLUMN_TYPE_TO_STRING: Record<ECustomColumnType, NullableValueType> = {\n [ECustomColumnType.TEXT]: EDataType.STRING,\n [ECustomColumnType.SINGLE_SELECT]: EDataType.STRING,\n [ECustomColumnType.MULTI_SELECT]: EDataType.STRING,\n [ECustomColumnType.COMMENTS]: EDataType.STRING,\n [ECustomColumnType.URL]: EDataType.STRING,\n [ECustomColumnType.EMAIL]: EDataType.STRING,\n [ECustomColumnType.PERSON]: EDataType.STRING,\n [ECustomColumnType.IMAGE]: EDataType.STRING,\n [ECustomColumnType.ATTACHMENT]: EDataType.STRING,\n\n [ECustomColumnType.NUMBER]: EDataType.NUMBER,\n [ECustomColumnType.DECIMAL]: EDataType.NUMBER,\n [ECustomColumnType.CURRENCY]: EDataType.NUMBER,\n [ECustomColumnType.RATING]: EDataType.NUMBER,\n [ECustomColumnType.PERCENT]: EDataType.NUMBER,\n [ECustomColumnType.PERCENT_SLIDER]: EDataType.NUMBER,\n\n [ECustomColumnType.DATE]: EDataType.DATE,\n [ECustomColumnType.TIME]: EDataType.DATE,\n [ECustomColumnType.DATETIME]: EDataType.DATE,\n [ECustomColumnType.LAST_UPDATED_AT]: EDataType.DATE,\n\n [ECustomColumnType.CHECKBOX]: EDataType.BOOLEAN,\n\n // Null types\n [ECustomColumnType.LAST_UPDATED_BY]: null,\n [ECustomColumnType.FORMULA]: null,\n [ECustomColumnType.BUTTON_COLUMN]: null,\n [ECustomColumnType.PHONE_NUMBER]: null,\n};\n\n// Operators\nexport const MATH_OPERATORS = new Set(['+', '-', '*', '/', '%']);\nexport const COMPARISON_OPERATORS = new Set(['=', '==', '<', '<=', '>', '>=', '!=', '<>']);\nexport const OPERATOR_MAP = new Map([['==', '=']]);\n\n// Date/Time functions\nconst DATE_FUNCTIONS = [\n 'TODAY',\n 'CURRENT_DATE',\n 'GETDATE',\n 'CURRENT_TIMESTAMP',\n 'NOW',\n 'SYSDATE',\n 'DATEADD',\n 'DATEDIFF',\n 'EOMONTH',\n 'DATE',\n 'FROMEXCELDATE',\n] as const;\n\n// Numeric functions\nconst NUMERIC_FUNCTIONS = [\n 'YEAR',\n 'MONTH',\n 'DAY',\n 'HOUR',\n 'MINUTE',\n 'SECOND',\n 'DATEDIFF_DAY',\n 'DATEDIFF_MONTH',\n 'DATEDIFF_YEAR',\n 'ABS',\n 'CEIL',\n 'CEILING',\n 'FLOOR',\n 'ROUND',\n 'RAND',\n 'RANDBETWEEN',\n 'POW',\n 'POWER',\n 'SQRT',\n 'LOG',\n 'LN',\n 'EXP',\n 'MOD',\n 'ODD',\n 'EVEN',\n 'NUMBERVALUE',\n 'VALUE',\n 'LEN',\n 'LENGTH',\n 'FIND',\n 'SEARCH',\n 'INDEXOF',\n] as const;\n\n// String functions\nconst STRING_FUNCTIONS = [\n 'LOWER',\n 'UPPER',\n 'TRIM',\n 'LTRIM',\n 'RTRIM',\n 'SUBSTRING',\n 'SUBSTR',\n 'LEFT',\n 'RIGHT',\n 'REPLACE',\n 'CONCAT',\n 'CONCATENATE',\n 'TEXT',\n 'FORMAT',\n 'MID',\n 'REPT',\n 'UUID',\n 'TOSTRING',\n 'STRING',\n] as const;\n\n// Logical functions\nconst LOGICAL_FUNCTIONS = [\n 'IF',\n 'IFS',\n 'SWITCH',\n 'IFNA',\n 'ISBLANK',\n 'ISEMPTY',\n 'ISNUMBER',\n 'ISNUMERIC',\n 'HAS',\n 'HASSOME',\n 'HASALL',\n 'IN',\n 'INCLUDES',\n 'CONTAINS',\n 'STARTSWITH',\n 'ENDSWITH',\n 'MATCHES',\n 'REGEXMATCH',\n] as const;\n\n// Aggregate functions\nconst AGGREGATE_FUNCTIONS = [\n 'SUM',\n 'AVG',\n 'AVERAGE',\n 'AVERAGEXNEG',\n 'AVERAGEXZERO',\n 'AVERAGEXZERONEG',\n 'COUNT',\n 'COUNTDISTINCT',\n 'COUNTIF',\n 'SUMIF',\n 'AVERAGEIF',\n 'MIN',\n 'MAX',\n 'MEDIAN',\n 'MODE',\n 'PERCENTILE',\n 'QUARTILE',\n 'STDEV',\n 'STDEVP',\n 'VAR',\n 'VARP',\n] as const;\n\n// Other function types\nconst PERCENT_FUNCTIONS = ['PCT', 'PERCENT'] as const;\n\n// Function - return type map\nexport const FUNCTION_RETURN_TYPE: Record<string, EDataType> = Object.fromEntries([\n ...DATE_FUNCTIONS.map((fn) => [fn, EDataType.DATE]),\n ...NUMERIC_FUNCTIONS.map((fn) => [fn, EDataType.NUMBER]),\n ...STRING_FUNCTIONS.map((fn) => [fn, EDataType.STRING]),\n ...LOGICAL_FUNCTIONS.map((fn) => [fn, EDataType.BOOLEAN]),\n ...AGGREGATE_FUNCTIONS.map((fn) => [fn, EDataType.NUMBER]),\n ...PERCENT_FUNCTIONS.map((fn) => [fn, EDataType.NUMBER]),\n]);\n\n// SQL Expression Enums\nexport enum ESqlDateExpression {\n CURRENT_DATE = 'CURRENT_DATE',\n GETDATE = 'GETDATE()',\n CURRENT_TIMESTAMP = 'CURRENT_TIMESTAMP',\n NOW = 'NOW()',\n SYSDATE = 'SYSDATE',\n}\n\nexport enum ESqlMathExpression {\n RAND = 'RAND()',\n NEWID = 'NEWID()',\n}\n\nexport enum ESqlWindowExpression {\n ROW_NUMBER = 'ROW_NUMBER()',\n PERCENTILE_CONT = 'PERCENTILE_CONT',\n COUNT = 'COUNT',\n}\n\nexport type SqlExpression = ESqlDateExpression | ESqlMathExpression | ESqlWindowExpression;\n\n// Function Type Unions\nexport type DateFunction = (typeof DATE_FUNCTIONS)[number];\nexport type NumericFunction = (typeof NUMERIC_FUNCTIONS)[number];\nexport type StringFunction = (typeof STRING_FUNCTIONS)[number];\nexport type LogicalFunction = (typeof LOGICAL_FUNCTIONS)[number];\nexport type AggregateFunction = (typeof AGGREGATE_FUNCTIONS)[number];\nexport type PercentFunction = (typeof PERCENT_FUNCTIONS)[number];\n\nexport type FunctionType =\n | DateFunction\n | NumericFunction\n | StringFunction\n | LogicalFunction\n | AggregateFunction\n | PercentFunction;\n","export const RUNTIME_TABLE_NAME = '$RUNTIME_TABLE_NAME';\nexport const RUNTIME_FILTER_EXPR = '$RUNTIME_FILTER_EXPR';\nexport const RUNTIME_SORT_EXPR = '$RUNTIME_SORT_EXPR';\nexport const RUNTIME_PAGINATION_EXPR = '$RUNTIME_PAGINATION_EXPR';\nexport const RUNTIME_LOGGEDIN_EMAIL = '$RUNTIME_LOGGEDIN_EMAIL';\nexport const RUNTIME_LOGGEDIN_NAME = '$RUNTIME_LOGGEDIN_NAME';\nexport const RUNTIME_CURRENT_DATE = '$RUNTIME_CURRENT_DATE';\nexport const RUNTIME_CURRENT_DATETIME = '$RUNTIME_CURRENT_DATETIME';\n","import { JoinExpressions } from './filters/filter-types';\nimport { IMDMColumnConfigWithParsedMeta, ParseContext } from './js-lib/ParseContext';\nimport { RuntimeVariables } from './query-builder/QueryBuilder';\nimport XXH from 'xxhashjs';\nimport { Binary, Case, ExpressionValue, SqlFunction } from './sql-types';\nimport {\n COLUMN_TYPE_TO_STRING,\n COMPARISON_OPERATORS,\n ECustomColumnType,\n EDataType,\n ESqlDateExpression,\n ESqlMathExpression,\n ESqlWindowExpression,\n FUNCTION_RETURN_TYPE,\n MATH_OPERATORS,\n NullableValueType,\n OPERATOR_MAP,\n} from './constants';\nimport { RUNTIME_CURRENT_DATE } from './runtime_var';\n\nfunction wrapPart(part: string, wrapper: string): string {\n if (wrapper === '`') return `\\`${part}\\``;\n if (wrapper === '[') return `[${part}]`;\n return `\"${part}\"`;\n}\n\nfunction formatNameByWrapper(name: string, wrapper: string): string {\n return name\n .split('.')\n .map((part) => wrapPart(part, wrapper))\n .join('.');\n}\n\nexport function formatDBEntityName(name: string): string {\n return formatNameByWrapper(name, '[');\n}\n\nexport function getEntityNameFormatter(): (name: string, type?: string) => string {\n const baseFormatter = (name: string) => {\n return formatNameByWrapper(name, '[');\n };\n\n return (name: string, type?: string) => {\n if (type === 'bit') {\n return `CAST(${baseFormatter(name)} AS int) as ${baseFormatter(name)}`;\n }\n return baseFormatter(name);\n };\n}\n\nexport function resolveRuntimeVariables(expr: string, runtimeVariables: RuntimeVariables): string {\n // regular expression to match words starting with $ and containing only word characters\n return expr.replace(\n /\\$\\w+/g,\n (match) => runtimeVariables[match as keyof RuntimeVariables] ?? match,\n );\n}\n\nfunction hashEncrypt(text: string): string {\n const seed = 0xabcd;\n const hash64 = XXH.h64(text, seed);\n return hash64.toString(16).slice(0, 8).padStart(8, '0');\n}\n\nexport function getDeprecatedFormulaId(columnName: string): string {\n return columnName.replace(/\\W+/g, '__');\n}\n\nexport function getFormulaId(columnName: string): string {\n const sanitizedName = columnName.replace(/\\W+/g, '__');\n const hashKey = hashEncrypt(columnName).slice(0, 8);\n return `${sanitizedName}_${hashKey}`;\n}\n\nexport function getDeprecatedFormulaIdColumnMap(\n columnConfigMap: Record<string, IMDMColumnConfigWithParsedMeta>,\n): Record<string, string> {\n const formulaIdColumnMap = Object.values(columnConfigMap as Record<string, any>).reduce(\n (acc, column) => {\n const columnName = column?.columnName;\n const sanitizedColumnName = getDeprecatedFormulaId(columnName);\n if (sanitizedColumnName && columnName) {\n acc[sanitizedColumnName] = columnName;\n }\n return acc;\n },\n {} as Record<string, string>,\n );\n\n return formulaIdColumnMap;\n}\n\nexport function getFormulaIdColumnMap(\n columnConfigMap: Record<string, IMDMColumnConfigWithParsedMeta>,\n): Record<string, string> {\n const formulaIdColumnMap = Object.values(columnConfigMap as Record<string, any>).reduce(\n (acc, column) => {\n const columnName = column?.columnName;\n const sanitizedColumnName = getFormulaId(columnName);\n if (sanitizedColumnName && columnName) {\n acc[sanitizedColumnName] = columnName;\n }\n return acc;\n },\n {} as Record<string, string>,\n );\n\n return formulaIdColumnMap;\n}\n\nexport function getFormattedTableName(databaseDetails: Record<string, any>): string {\n const { database, schema, dataTableName } = databaseDetails;\n\n const tableName = `${database}.${schema}.${dataTableName}`;\n return formatDBEntityName(tableName);\n}\n\nexport function getCurrentDate(): string {\n return new Date().toISOString().split('T')[0];\n}\n\nexport function getCurrentDateTime(): string {\n return new Date().toISOString();\n}\n/**\n * Gets the join expressions from the join config\n * @returns An array of join expressions in SQL format\n */\nexport function getJoinExpressions(\n joinClauses: JoinExpressions,\n databaseDetails: Record<string, string>,\n): string[] {\n const { joinRelation, alias } = joinClauses || {};\n\n if (!Array.isArray(joinRelation) || joinRelation.length === 0) {\n return [];\n }\n const entityNameFormatter = getEntityNameFormatter();\n const { database } = databaseDetails;\n const formattedDatabaseName = database ? `${entityNameFormatter(database)}.` : '';\n const mainTablePrefix = alias ? `${entityNameFormatter(alias)}.` : '';\n\n return joinRelation.map((join) => {\n const formattedSchema = join?.schema ? entityNameFormatter(join.schema) : undefined;\n const formattedTable = entityNameFormatter(join.table);\n const qualifiedJoinTable = formattedSchema\n ? `${formattedDatabaseName}${formattedSchema}.${formattedTable}`\n : formattedTable;\n const joinAlias = entityNameFormatter(join.alias ?? join.table);\n\n // Build left & right columns\n const leftCol = `${mainTablePrefix}${entityNameFormatter(join.id)}`;\n const rightCol = `${joinAlias}.${entityNameFormatter(join.joinId)}`;\n\n // Build join target: always alias the table\n const joinTarget = `${qualifiedJoinTable} ${joinAlias}`;\n\n return `${join.joinType.toUpperCase()} JOIN ${joinTarget} ON ${leftCol} = ${rightCol}`;\n });\n}\n\n/**\n * Strips the 'WHERE' clause from the SQL query.\n * - If where clause is not present, returns the original query.\n * - If where clause is present, returns the part of the query after the 'WHERE' clause.\n */\nexport function stripWhereClause(sqlQuery: string): string {\n const queryInUpperCase = sqlQuery.toUpperCase();\n const whereLabel = 'WHERE';\n // since query generated by Knex starts with 'SELECT' and includes 'WHERE' in the query,\n // we need to slice that part out to just get the filter condition.\n const startIndex = queryInUpperCase.indexOf(whereLabel);\n if (startIndex === -1) {\n return sqlQuery;\n }\n return sqlQuery.slice(startIndex + whereLabel.length).trim();\n}\n\n/**\n * Extracts the target type of a CAST expression from a given Binary expression.\n * The target type is the right-hand side of the AS operator, e.g. 'INT' in 'CAST(x AS INT)'.\n * If the given expression does not represent a CAST expression, returns null.\n * @param {Binary} arg - The Binary expression to extract the target type from.\n * @returns {string | null} - The target type of the CAST expression, or null if it is not a CAST expression.\n */\nexport function extractCastTargetType(arg: Binary): string | null {\n if (arg?.type === 'binary_expr' && arg.operator === 'AS' && arg.right?.type === 'default') {\n return arg.right.value;\n }\n return null;\n}\n\n/**\n * Maps a SQL cast type to a Fabric data type\n * @param {string} type - The SQL cast type to map.\n * @returns {NullableValueType} - The corresponding Fabric data type.\n */\nexport function mapSqlTypeToDataType(type: string): NullableValueType {\n // Convert SQL type to Fabric data type\n const dataType = String(type)\n .replace(/\\(.*\\)/, '')\n .trim()\n .toUpperCase();\n switch (dataType) {\n // Numeric types supported in Fabric\n case 'INT':\n case 'INTEGER':\n case 'BIGINT':\n case 'FLOAT':\n case 'DOUBLE':\n case 'DECIMAL':\n case 'NUMERIC':\n return EDataType.NUMBER;\n\n // Date and time types supported in Fabric\n case 'DATE':\n case 'TIMESTAMP':\n case 'DATETIME':\n return EDataType.DATE;\n\n // Boolean types supported in Fabric\n case 'BOOLEAN':\n case 'BOOL':\n case 'BIT':\n return EDataType.BOOLEAN;\n\n // String types supported in Fabric\n case 'STRING':\n case 'TEXT':\n case 'VARCHAR':\n case 'CHAR':\n case 'NVARCHAR':\n return EDataType.STRING;\n\n default:\n return null;\n }\n}\n\nexport function isValidDate(value: string): boolean {\n if (typeof value !== 'string') return false;\n if (RUNTIME_CURRENT_DATE === value) return true;\n const isoDateRegex = /^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$/;\n if (!isoDateRegex.test(value)) return false;\n\n const date = new Date(value);\n if (isNaN(date.getTime())) return false;\n\n const [year, month, day] = value.split('-').map(Number);\n return (\n date.getUTCFullYear() === year && date.getUTCMonth() + 1 === month && date.getUTCDate() === day\n );\n}\n\nexport function getArgType(arg: ExpressionValue, context: ParseContext): NullableValueType {\n if (arg.type === 'column_ref') {\n const columnName = (arg as Record<string, string>).column.replace(/[`[\\]\"]/g, '');\n const column = context.columnConfigMap[columnName];\n if (!column) return null;\n // Handle formula columns by returning their resolved data type\n if ((column.columnType as number) === ECustomColumnType.FORMULA) {\n const dataType = column.columnMeta?.formulaColumnDetails?.dataType;\n return dataType ?? null;\n }\n return COLUMN_TYPE_TO_STRING[column.columnType] ?? null;\n }\n\n if (arg.type === EDataType.STRING) {\n return isValidDate(arg.value) ? EDataType.DATE : EDataType.STRING;\n }\n if (arg.type === EDataType.NUMBER) return EDataType.NUMBER;\n if (arg.type === EDataType.BOOLEAN) return EDataType.BOOLEAN;\n if (arg.type === EDataType.NULL) return null;\n\n if (arg.type === 'case') {\n const resultTypes = (arg as Case).args.map((branch) =>\n branch.type === 'when' || branch.type === 'else'\n ? getArgType(branch.result as ExpressionValue, context)\n : null,\n );\n\n const unique = [...new Set(resultTypes)];\n return unique.length === 1 ? unique[0] : null;\n }\n\n if (arg.type === 'binary_expr') {\n const operator = OPERATOR_MAP.get((arg as Binary).operator) ?? (arg as Binary).operator;\n\n const leftType = getArgType((arg as Binary).left, context);\n const rightType = getArgType((arg as Binary).right, context);\n\n // Math operators\n if (MATH_OPERATORS.has(operator)) {\n if (leftType !== EDataType.NUMBER || rightType !== EDataType.NUMBER) {\n context.isValid = false;\n context.error = `Operator \"${operator}\" requires both operands to be numbers`;\n }\n return EDataType.NUMBER;\n }\n\n // Comparison operators\n if (COMPARISON_OPERATORS.has(operator)) {\n if (leftType !== rightType && leftType !== null && rightType !== null) {\n context.isValid = false;\n context.error = `Please ensure both sides of the comparison are of the same type`;\n }\n return EDataType.BOOLEAN;\n }\n\n return null;\n }\n\n if (arg.type === 'expr_list') {\n const types = (arg.value as ExpressionValue[]).map((v) => getArgType(v, context));\n return types.find((t) => t !== null) || null;\n }\n\n if (arg.type === 'function') {\n const fnName = (arg as SqlFunction).name.name[0].value.toUpperCase();\n const args =\n (arg as SqlFunction).args?.type === 'expr_list'\n ? (arg as SqlFunction).args.value\n : [(arg as SqlFunction).args];\n\n // Handle specific SQL functions\n if (fnName === 'COALESCE') {\n const types = args.map((a) => getArgType(a, context));\n return types.find((t) => t !== null) || null;\n } else if (fnName === 'CAST') {\n const targetType = extractCastTargetType(args[0] as Binary);\n return targetType ? mapSqlTypeToDataType(targetType) : null;\n }\n\n // Resolve return type for precomputed functions\n const returnType = FUNCTION_RETURN_TYPE[fnName];\n if (returnType) return returnType;\n\n return null;\n }\n\n // Handle SQL expressions\n if (arg.type === 'sql_expr') {\n const sqlValue = (arg as any).value;\n\n if (Object.values(ESqlDateExpression).includes(sqlValue)) return EDataType.DATE;\n if (Object.values(ESqlMathExpression).includes(sqlValue)) return EDataType.NUMBER;\n if (Object.values(ESqlWindowExpression).some((expr) => sqlValue.includes(expr)))\n return EDataType.NUMBER;\n\n return null;\n }\n\n return null;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport * as acorn from 'acorn';\nimport {\n getEntityNameFormatter,\n getFormulaIdColumnMap,\n getDeprecatedFormulaIdColumnMap,\n} from '../utils';\n\nexport enum MDM_COLUMN_TYPE {\n TEXT = 1,\n SINGLE_SELECT = 2,\n MULTI_SELECT = 3,\n DATE = 4,\n COMMENTS = 5,\n NUMBER = 6,\n PERSON = 7,\n TIME = 8,\n LAST_UPDATED_BY = 9,\n LAST_UPDATED_AT = 10,\n CHECKBOX = 11,\n DATETIME = 12,\n DECIMAL = 13,\n IMAGE = 14,\n URL = 15,\n EMAIL = 16,\n FORMULA = 17,\n}\n\nexport enum ResolvedExpressionType {\n COLUMN = 'columnExpr',\n CTE = 'cteExpr',\n}\n\nexport type CteExpression = {\n type: ResolvedExpressionType.CTE;\n cteName: string;\n value: string[];\n};\n\nexport type ColumnExpression = {\n type: ResolvedExpressionType.COLUMN;\n value: string[];\n};\n\nexport type SqlQueryProps = {\n resolvedExpression: ColumnExpression | CteExpression;\n};\n\nexport type ColumnMeta = {\n sqlQueryProps?: SqlQueryProps;\n computationOrder?: number;\n deps?: string[];\n [key: string]: any;\n};\n\n// This is mock interface for column config. Actual type comes from InfoRiverMDM repo from type `IMDMColumnConfigWithParsedMeta`\nexport interface IMDMColumnConfigWithParsedMeta {\n columnName: string;\n columnType: MDM_COLUMN_TYPE;\n columnMeta: ColumnMeta;\n}\n\nexport type TColumnConfigMap = Record<string, IMDMColumnConfigWithParsedMeta>;\n\nexport type ParseContextProps = {\n columnConfigMap: TColumnConfigMap;\n currentColumnId: string;\n primaryKeyColumns: string[];\n tableName: string;\n};\n\nexport class ParseContext {\n private lastEvaluatedValue: any;\n private _cteCount: number = 0;\n public formulaIdColumnMap: Record<string, string>;\n public deprecatedFormulaColumnMap: Record<string, string>;\n public ifCondition: boolean = false;\n private readonly columnDeps: Set<string>;\n public readonly state: Map<string, any>;\n public readonly columnConfigMap: TColumnConfigMap;\n public readonly currentColumnId: string;\n public readonly primaryKeyColumns: string[];\n public readonly tableName: string;\n public readonly entityNameFormatter: (name: string) => string;\n public returnType: string | undefined;\n public isValid: boolean = true;\n public error: string | undefined;\n\n constructor(props: ParseContextProps) {\n this.state = new Map();\n this.lastEvaluatedValue = null;\n this.columnConfigMap = props.columnConfigMap;\n this.formulaIdColumnMap = getFormulaIdColumnMap(props.columnConfigMap);\n this.deprecatedFormulaColumnMap = getDeprecatedFormulaIdColumnMap(props.columnConfigMap);\n this.currentColumnId = props.currentColumnId;\n this.primaryKeyColumns = props.primaryKeyColumns;\n this.tableName = props.tableName;\n this.columnDeps = new Set<string>();\n this.entityNameFormatter = getEntityNameFormatter();\n }\n\n /**\n * Reset the parse context\n */\n reset(): ParseContext {\n this.lastEvaluatedValue = null;\n this.state.clear();\n this.columnDeps.clear();\n return this;\n }\n\n get(node: acorn.Node): any {\n return this.state.get(this.getId(node));\n }\n\n set(node: acorn.Node, value: any): void {\n this.lastEvaluatedValue = value;\n this.state.set(this.getId(node), value);\n }\n\n getId(node: acorn.Node): string {\n return `${node.start}_${node.end}`;\n }\n\n getLastEvaluatedValue(): any {\n return this.lastEvaluatedValue;\n }\n\n getColumnCount(): number {\n return Object.keys(this.columnConfigMap).length;\n }\n\n addColumnDep(columnName: string): void {\n this.columnDeps.add(columnName);\n }\n\n getColumnDeps(): Set<string> {\n return this.columnDeps;\n }\n\n get cteCount(): number {\n return this._cteCount;\n }\n\n incrementCTECount(): void {\n this._cteCount++;\n }\n}\n","export interface PaginationBuilder {\n generateQuery(offset: number, limit: number): string;\n}\n\n/**\n * Creates a pagination builder based on the database type\n */\nexport function createPaginationBuilder(): PaginationBuilder {\n return new DefaultPaginationBuilder();\n}\n\n/**\n * Pagination builder for Default\n */\nexport class DefaultPaginationBuilder implements PaginationBuilder {\n generateQuery(offset: number, limit: number): string {\n return `OFFSET ${offset} ROWS FETCH NEXT ${limit} ROWS ONLY`;\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { ParseContext } from '../js-lib/ParseContext';\nimport {\n Binary,\n Column,\n ColumnRef,\n RawSqlExpression,\n From,\n Limit,\n OrderBy,\n Select,\n SqlFunction,\n ValueExpr,\n With,\n ExpressionValue,\n} from '../sql-types';\n\nexport class SelectBuilder {\n private columns: Column[] = [];\n private from: From[] | null = null;\n private where: Binary | SqlFunction | RawSqlExpression | null = null;\n private qualify: RawSqlExpression | null = null;\n private groupby: { columns: ColumnRef[] | null; modifiers: ValueExpr<string>[] } = {\n columns: null,\n modifiers: [],\n };\n private having: any[] | null = null;\n private orderby: OrderBy[] | RawSqlExpression[] | null = null;\n private limit: Limit | RawSqlExpression | null = null;\n private withExpr: With[] | null = null;\n private set_op: string | undefined = undefined;\n private _next: Select | undefined = undefined;\n private distinct: 'DISTINCT' | null = null;\n\n public addColumns(columns: Column[]): SelectBuilder {\n this.columns = columns;\n return this;\n }\n\n public addFrom(from: From[]): SelectBuilder {\n this.from = from;\n return this;\n }\n\n public addWhere(where: Binary | SqlFunction | RawSqlExpression): SelectBuilder {\n this.where = where;\n return this;\n }\n\n public addQualify(qualify: RawSqlExpression): SelectBuilder {\n this.qualify = qualify;\n return this;\n }\n\n public addGroupby(groupby: {\n columns: ColumnRef[];\n modifiers: ValueExpr<string>[];\n }): SelectBuilder {\n this.groupby = groupby;\n return this;\n }\n\n public addHaving(having: any[]): SelectBuilder {\n this.having = having;\n return this;\n }\n\n public addOrderby(orderby: OrderBy[] | RawSqlExpression[]): SelectBuilder {\n this.orderby = orderby;\n return this;\n }\n\n public addLimit(limit: Limit | RawSqlExpression): SelectBuilder {\n this.limit = limit;\n return this;\n }\n\n public addWith(withExpr: With[]): SelectBuilder {\n this.withExpr = withExpr;\n return this;\n }\n\n public addSetOp(set_op: string): SelectBuilder {\n this.set_op = set_op;\n return this;\n }\n\n public addNext(next: Select): SelectBuilder {\n this._next = next;\n return this;\n }\n\n public addDistinct(): SelectBuilder {\n this.distinct = 'DISTINCT';\n return this;\n }\n\n public build(): Select {\n return {\n type: 'select',\n with: this.withExpr,\n columns: this.columns,\n from: this.from,\n where: this.where,\n qualify: this.qualify,\n groupby: this.groupby,\n having: this.having,\n orderby: this.orderby,\n limit: this.limit,\n options: null,\n distinct: this.distinct,\n set_op: this.set_op,\n _next: this._next,\n };\n }\n}\n\nexport class WithBuilder {\n private name: string | undefined;\n private stmt: Select | undefined;\n\n constructor(context: ParseContext) {\n this.name = undefined;\n this.stmt = undefined;\n context.incrementCTECount();\n }\n\n public addName(name: string): WithBuilder {\n this.name = name;\n return this;\n }\n\n public addStmt(stmt: Select): WithBuilder {\n this.stmt = stmt;\n return this;\n }\n\n public build(): With {\n if (!this.name || !this.stmt) {\n throw new Error('name and statement are required');\n }\n\n return {\n name: { value: this.name },\n stmt: {\n _parentheses: true,\n tableList: [],\n columnList: [],\n ast: this.stmt,\n },\n };\n }\n}\n","import { Column, ColumnRef, ExpressionValue } from '../sql-types';\n\nexport function toColumnRef(columName: string, table: string | null = null): ColumnRef {\n return {\n type: 'column_ref',\n table: table,\n column: columName,\n collate: undefined,\n };\n}\n\nexport function toColumn(expr: ExpressionValue, as: string | null = null): Column {\n return {\n type: 'column',\n expr: expr,\n as: as,\n };\n}\n","import {\n ExpressionValue,\n ColumnRefItem,\n SqlFunction,\n Case,\n Binary,\n UnaryExpression,\n Select,\n With,\n TableExpr,\n From,\n Join,\n Column,\n ExprList,\n RawSqlExpression,\n OrderBy,\n} from './sql-types';\nimport { WhenType } from './sql-lib/when';\nimport { ElseType } from './sql-lib/else';\n\n/**\n * Transforms an AST to a SQL query string\n */\nexport function generateSqlQuery(ast: ExpressionValue | Select | TableExpr | From): string {\n switch (ast.type) {\n case 'column_ref':\n const columnRef = ast as ColumnRefItem;\n return `${columnRef.table ? `${columnRef.table}.` : ''}${columnRef.column}`;\n case 'column':\n const column = ast as Column;\n return `${generateSqlQuery(column.expr)}${column.as ? ` AS ${column.as}` : ''}`;\n case 'function':\n const functionAst = ast as SqlFunction;\n return `${functionAst.name.name[0].value}(${functionAst.args?.value.map((arg) => generateSqlQuery(arg)).join(', ')})`;\n case 'unary_expr':\n const unaryExpr = ast as UnaryExpression;\n return `${unaryExpr.operator} ${generateSqlQuery(unaryExpr.expr)}`;\n case 'binary_expr':\n const binaryExpr = ast as Binary;\n if (binaryExpr.parentheses) {\n return `(${generateSqlQuery(binaryExpr.left)} ${binaryExpr.operator} ${generateSqlQuery(binaryExpr.right)})`;\n }\n return `${generateSqlQuery(binaryExpr.left)} ${binaryExpr.operator} ${generateSqlQuery(binaryExpr.right)}`;\n case 'expr_list':\n const exprList = ast as ExprList;\n return `(${exprList.value.map((arg) => generateSqlQuery(arg)).join(', ')})`;\n case 'default':\n case 'sql_expr':\n return ast.value;\n case 'number':\n return ast.value.toString();\n case 'string':\n return `'${ast.value}'`;\n case 'bit':\n return `'${ast.value}'`;\n case 'double_quote_string':\n return `\"${ast.value}\"`;\n case 'boolean':\n return ast.value.toString().toUpperCase();\n case 'null':\n return 'NULL';\n case 'select':\n return processSelect(ast as Select);\n case 'from':\n const fromAst = ast as Join;\n const tableName = `${fromAst.db ? `${fromAst.db}.` : ''}${fromAst.table}`;\n if (fromAst.join) {\n return `${fromAst.join} ${tableName} ON ${generateSqlQuery(fromAst.on!)}`;\n }\n return tableName;\n case 'table_expr':\n const tableExpr = ast as TableExpr;\n return generateSqlQuery(tableExpr.expr.ast);\n case 'case':\n const caseAst = ast as Case;\n const whenLength = caseAst.args.length - 1;\n const elseArg = caseAst.args[whenLength] as ElseType;\n const whenArgs = caseAst.args.slice(0, whenLength) as WhenType[];\n return `CASE ${whenArgs.map((arg) => `WHEN ${generateSqlQuery(arg.cond)} THEN ${generateSqlQuery(arg.result)}`).join(' ')} ELSE ${generateSqlQuery(elseArg.result)} END`;\n default:\n throw new Error(`Unsupported type: ${ast.type}`);\n }\n}\n\nfunction processWith(ast: With[]): string {\n return ast\n .map((withStmt) => `${withStmt.name.value} AS (${generateSqlQuery(withStmt.stmt.ast)})`)\n .join(', ');\n}\n\n/**\n * Processes a Select AST and returns the corresponding SQL query string\n */\nexport function processSelect(ast: Select): string {\n const parts: string[] = [];\n if (ast.with) {\n parts.push(`${ast.from ? 'WITH ' : ''}${processWith(ast.with)}`);\n }\n\n if (ast.from) {\n parts.push('SELECT');\n if (ast.distinct) {\n parts.push(ast.distinct);\n }\n parts.push(ast.columns.map((col) => generateSqlQuery(col)).join(', '));\n const from = Array.isArray(ast.from)\n ? ast.from.map((arg) => generateSqlQuery(arg)).join(' ')\n : generateSqlQuery(ast.from);\n parts.push(`FROM ${from}`);\n }\n\n if (ast.from && ast.where) {\n parts.push(`WHERE ${generateSqlQuery(ast.where)}`);\n }\n\n if (ast.qualify) {\n parts.push(`QUALIFY ${generateSqlQuery(ast.qualify)}`);\n }\n\n if (ast.from && ast.groupby?.columns) {\n parts.push(`GROUP BY ${ast.groupby.columns.map((col) => generateSqlQuery(col)).join(', ')}`);\n }\n\n if (ast.from && ast.orderby) {\n parts.push(\n `ORDER BY ${ast.orderby\n .map((order) => {\n if ((order as RawSqlExpression).type === 'sql_expr') {\n return (order as RawSqlExpression).value;\n }\n return `${generateSqlQuery((order as OrderBy).expr)} ${order.type}`;\n })\n .join(', ')}`,\n );\n }\n\n if (ast.from && ast.limit) {\n if ((ast.limit as RawSqlExpression).type === 'sql_expr') {\n parts.push((ast.limit as RawSqlExpression).value);\n } else {\n throw new Error('Unsupported limit type. Limit must be a RawSqlExpression');\n }\n }\n\n if (ast._next) {\n parts.push(`${ast.set_op} ${generateSqlQuery(ast._next)}`);\n }\n\n return parts.join(' ');\n}\n","// dateFunctions.ts\n\nexport interface DateFunctions {\n today: string;\n dateAdd(expr: string, amount: number, unit: string): string;\n dateTrunc(unit: string, expr: string): string;\n startOfWeek?(expr: string): string;\n}\n\nabstract class BaseDateFunctions implements DateFunctions {\n abstract today: string;\n abstract dateAdd(expr: string, amount: number, unit: string): string;\n abstract dateTrunc(unit: string, expr: string): string;\n startOfWeek?(expr: string): string;\n}\n\nclass FabricSQLDateFunctions extends BaseDateFunctions {\n today = 'CURRENT_DATE';\n dateAdd = (expr: any, amount: any, unit: string) =>\n `DATEADD(${unit.toUpperCase()}, ${amount}, ${expr})`;\n dateTrunc(unit: string, expr: string) {\n const truncMap: Record<string, string> = {\n week: `DATEADD(DAY, -DATEPART(WEEKDAY, ${expr}) + 1, ${expr})`,\n month: `DATEFROMPARTS(YEAR(${expr}), MONTH(${expr}), 1)`,\n quarter: `DATEADD(QUARTER, DATEDIFF(QUARTER, 0, ${expr}), 0)`,\n year: `DATEFROMPARTS(YEAR(${expr}), 1, 1)`,\n };\n return truncMap[unit] ?? expr;\n }\n startOfWeek = (expr: any) => `DATEADD(DAY, -DATEPART(WEEKDAY, ${expr}) + 1, ${expr})`;\n}\n\n// Factory function\nexport const getDateFunctions = (): DateFunctions => {\n return new FabricSQLDateFunctions();\n};\n","// DateFilterFactory.ts\nimport { IGroupFilter } from '../filters/filter-types';\nimport { EDateRangeRelativeFilterCondition } from '../query-builder/SuperFilterBuilder';\nimport { getDateFunctions } from './dateFunction';\n\ntype PeriodConfig = {\n startExpr: () => string;\n shiftFn: (expr: string, amount: number) => string;\n isCalendar: boolean;\n};\n\nexport enum Period {\n DAYS = 'DAYS',\n WEEKS = 'WEEKS',\n CALENDER_WEEKS = 'CALENDER_WEEKS',\n MONTHS = 'MONTHS',\n CALENDER_MONTHS = 'CALENDER_MONTHS',\n CALENDER_QUARTERS = 'CALENDER_QUARTERS',\n CALENDER_YEARS = 'CALENDER_YEARS',\n FISCAL_QUARTER = 'FISCAL_QUARTER',\n FISCAL_YEAR = 'FISCAL_YEAR',\n YEARS = 'YEARS',\n}\n\n/**\n * Centralized period configs\n * @param today :today expression\n * @param fiscalShift :fiscal shift\n * @returns :period configs <object <string, PeriodConfig>>\n */\nconst getPeriodConfigs = (today: string, fiscalShift = 0): Record<Period, PeriodConfig> => {\n const fns = getDateFunctions();\n return {\n [Period.DAYS]: {\n startExpr: () => today,\n shiftFn: (e, a) => fns.dateAdd(e, a, 'day'),\n isCalendar: false,\n },\n [Period.WEEKS]: {\n startExpr: () => today,\n shiftFn: (e, a) => fns.dateAdd(e, a * 7, 'day'),\n isCalendar: false,\n },\n [Period.CALENDER_WEEKS]: {\n startExpr: () => fns.startOfWeek!(today),\n shiftFn: (e, a) => fns.dateAdd(e, a * 7, 'day'),\n isCalendar: true,\n },\n [Period.MONTHS]: {\n startExpr: () => today,\n shiftFn: (e, a) => fns.dateAdd(e, a, 'month'),\n isCalendar: false,\n },\n [Period.CALENDER_MONTHS]: {\n startExpr: () => fns.dateTrunc('month', today),\n shiftFn: (e, a) => fns.dateAdd(e, a, 'month'),\n isCalendar: true,\n },\n [Period.CALENDER_QUARTERS]: {\n startExpr: () => fns.dateTrunc('quarter', today),\n shiftFn: (e, a) => fns.dateAdd(e, a * 3, 'month'),\n isCalendar: true,\n },\n [Period.CALENDER_YEARS]: {\n startExpr: () => fns.dateTrunc('year', today),\n shiftFn: (e, a) => fns.dateAdd(e, a, 'year'),\n isCalendar: true,\n },\n [Period.FISCAL_QUARTER]: {\n startExpr: () =>\n fns.dateAdd(\n fns.dateTrunc('quarter', fns.dateAdd(today, -fiscalShift, 'month')),\n fiscalShift,\n 'month',\n ),\n shiftFn: (e, a) => fns.dateAdd(e, a * 3, 'month'),\n isCalendar: true,\n },\n [Period.FISCAL_YEAR]: {\n startExpr: () =>\n fns.dateAdd(\n fns.dateTrunc('year', fns.dateAdd(today, -fiscalShift, 'month')),\n fiscalShift,\n 'month',\n ),\n shiftFn: (e, a) => fns.dateAdd(e, a, 'year'),\n isCalendar: true,\n },\n [Period.YEARS]: {\n startExpr: () => today,\n shiftFn: (e, a) => fns.dateAdd(e, a, 'year'),\n isCalendar: false,\n },\n };\n};\n\n// Base class for date filter factor\nexport class DateFilterFactory {\n static build(column: string, filter: IGroupFilter): string {\n const fns = getDateFunctions();\n const today = fns.today;\n\n const dt = filter.dateTimeFilter;\n if (!dt || !dt.period || !dt.relativeDateFilter) throw new Error('Invalid date filter');\n\n const fiscalShift = dt.fiscalYearStartMonth ?? 0;\n const configs = getPeriodConfigs(today, fiscalShift);\n\n const periodKey = this.resolvePeriodKey(dt.period, dt.relativeDateFilter);\n const cfg = configs[periodKey];\n if (!cfg) throw new Error(`Unsupported period: ${periodKey}`);\n\n const duration = dt.duration ?? 1;\n\n const { startExpr, endExpr } = this.resolveDateRangeExpressions({\n relativeDateFilter: dt.relativeDateFilter,\n cfg,\n fns,\n today,\n duration,\n });\n\n return `(${column} >= ${startExpr} AND ${column} < ${endExpr})`;\n }\n\n private static resolvePeriodKey(\n period: string,\n relativeDateFilter: EDateRangeRelativeFilterCondition,\n ): Period {\n if (relativeDateFilter === EDateRangeRelativeFilterCondition.IS_IN_THIS) {\n switch (period) {\n case Period.WEEKS:\n return Period.CALENDER_WEEKS;\n case Period.MONTHS:\n return Period.CALENDER_MONTHS;\n case 'QUARTERS':\n return Period.CALENDER_QUARTERS;\n case Period.YEARS:\n return Period.CALENDER_YEARS;\n }\n }\n return period as Period;\n }\n\n private static resolveDateRangeExpressions(params: {\n relativeDateFilter: EDateRangeRelativeFilterCondition;\n cfg: PeriodConfig;\n fns: ReturnType<typeof getDateFunctions>;\n today: string;\n duration: number;\n }): { startExpr: string; endExpr: string } {\n const { relativeDateFilter, cfg, fns, today, duration } = params;\n const startOfPeriod = cfg.startExpr();\n\n switch (relativeDateFilter) {\n case EDateRangeRelativeFilterCondition.IS_IN_THIS:\n return {\n startExpr: startOfPeriod,\n endExpr: cfg.shiftFn(startOfPeriod, 1),\n };\n\n case EDateRangeRelativeFilterCondition.IS_IN_THE_LAST:\n return {\n startExpr: cfg.shiftFn(cfg.isCalendar ? startOfPeriod : today, -duration),\n endExpr: cfg.isCalendar ? startOfPeriod : today,\n };\n\n case EDateRangeRelativeFilterCondition.IS_IN_THE_NEXT:\n const baseNext = cfg.isCalendar ? startOfPeriod : today;\n const startExpr = cfg.isCalendar ? cfg.shiftFn(baseNext, 1) : fns.dateAdd(today, 1, 'day');\n return {\n startExpr,\n endExpr: cfg.shiftFn(startExpr, duration),\n };\n\n default:\n throw new Error(`Unsupported relative date filter: ${relativeDateFilter}`);\n }\n }\n}\n","import {\n JoinExpressions,\n RangeOperator,\n ISuperFilterConfig,\n IGroupFilter,\n IManualFilterConfig,\n IManualFilterOption,\n} from '../filters/filter-types';\nimport { DateFilterFactory } from '../superFilter/DateFilterFactory';\nimport { getEntityNameFormatter, getFormattedTableName } from '../utils';\nimport { MAX_STRING_TYPE } from './QueryBuilder';\n\nexport enum EDateRangeRelativeFilterCondition {\n IS_IN_THE_LAST = 'IS_IN_THE_LAST',\n IS_IN_THIS = 'IS_IN_THIS',\n IS_IN_THE_NEXT = 'IS_IN_THE_NEXT',\n}\n\nexport enum EDateRangeRelativePeriodFilterCondition {\n DAYS = 'DAYS',\n WEEKS = 'WEEKS',\n CALENDER_WEEKS = 'CALENDER_WEEKS',\n MONTHS = 'MONTHS',\n CALENDER_MONTHS = 'CALENDER_MONTHS',\n YEARS = 'YEARS',\n CALENDER_YEARS = 'CALENDER_YEARS',\n HOURS = 'HOURS',\n MINUTES = 'MINUTES',\n CALENDER_QUARTERS = 'CALENDER_QUARTERS',\n FISCAL_QUARTER = 'FISCAL_QUARTER',\n FISCAL_YEAR = 'FISCAL_YEAR',\n QUARTERS = 'QUARTERS',\n}\n\nconst rangeFilterOperator: Record<RangeOperator, string> = {\n // common operators\n IS: '=',\n IS_NOT: '!=',\n IS_BLANK: 'IS',\n IS_NOT_BLANK: 'IS NOT',\n //date specific operators\n IS_AFTER: '>',\n IS_BEFORE: '<',\n IS_ON_OR_AFTER: '>=',\n IS_ON_OR_BEFORE: '<=',\n //numeric specific operators\n IS_LESS_THAN: '<',\n IS_LESS_THAN_OR_EQUAL_TO: '<=',\n IS_GREATER_THAN: '>',\n IS_GREATER_THAN_OR_EQUAL_TO: '>=',\n //character specific operators\n CONTAINS: 'LIKE',\n DOES_NOT_CONTAIN: 'NOT LIKE',\n STARTS_WITH: 'LIKE',\n DOES_NOT_START_WITH: 'NOT LIKE',\n};\n\nconst characterRangeFilterOperator = [\n 'CONTAINS',\n 'DOES_NOT_CONTAIN',\n 'STARTS_WITH',\n 'DOES_NOT_START_WITH',\n];\n\nexport const negativeCharacterOperators: RangeOperator[] = [\n 'DOES_NOT_CONTAIN',\n 'DOES_NOT_START_WITH',\n 'IS_NOT',\n];\n\nexport const startsWithCharacterOperators: RangeOperator[] = ['STARTS_WITH', 'DOES_NOT_START_WITH'];\n\nexport const containsCharacterOperators: RangeOperator[] = ['CONTAINS', 'DOES_NOT_CONTAIN'];\n\nconst SUPER_FILTER_NUMERIC_SUPPORTED_DATA_TYPES = [\n 'Int64',\n 'Decimal',\n 'Double',\n 'Integer',\n 'Number',\n];\n\nexport enum EFilterDataType {\n BOOLEAN = 'boolean',\n DATE = 'date',\n NUMBER = 'number',\n STRING = 'string',\n}\n\n// Base class for super filter builder\nexport class SuperFilterBuilder {\n private superFilter: ISuperFilterConfig;\n private databaseDetails: any;\n private skipCountForRankingFilter: boolean;\n private joinClauses: JoinExpressions;\n private manualFilterOptions: IManualFilterConfig[];\n\n // new: the selected (last) ranking filter across the whole payload\n private lastRankingFilter: IGroupFilter | null = null;\n\n constructor(\n superFilter: ISuperFilterConfig,\n databaseDetails: any,\n skipCountForRankingFilter: boolean = false,\n joinClauses: JoinExpressions = { alias: '', joinRelation: [] },\n manualFilterOptions: IManualFilterConfig[] = [],\n ) {\n this.superFilter = superFilter;\n this.databaseDetails = databaseDetails;\n this.skipCountForRankingFilter = skipCountForRankingFilter;\n this.joinClauses = joinClauses;\n this.manualFilterOptions = manualFilterOptions;\n\n // find the last ranking filter in the whole payload and store a reference\n this.lastRankingFilter = this.findLastRankingFilter(this.superFilter);\n }\n\n /**\n * Entry point: build SQL condition string\n */\n public build(): string {\n const whereCondition = this.processGroup(this.superFilter, true, this.lastRankingFilter);\n\n //appending ranking filter at the end of the where condition.\n if (this.lastRankingFilter && !this.skipCountForRankingFilter) {\n // wrap existing where in parentheses to pass as a single expression to ranking\n const existingWhere = whereCondition ? `(${whereCondition})` : '';\n const rankingCondition = this.processRankingFilter(this.lastRankingFilter);\n\n if (!whereCondition) {\n // no other filters, return ranking condition\n return rankingCondition;\n }\n\n // ensure ranking condition is appended at the end\n return `${existingWhere} AND ${rankingCondition}`;\n }\n\n return whereCondition;\n }\n\n /**\n * Recursively process group and children\n * - skips all ranking filters during this pass\n * - preserves order of all other filters\n */\n private processGroup(\n group: any,\n isRoot = false,\n lastRankingToSkip: IGroupFilter | null = null,\n ): string {\n if (!group?.children) throw new Error('No childrens found');\n\n const parts: string[] = [];\n\n for (const child of group.children) {\n if ('groupId' in child && 'children' in child) {\n const nested = this.processGroup(child, false, lastRankingToSkip);\n if (nested) parts.push(nested);\n } else if ('filters' in child) {\n const filter = child.filters as IGroupFilter;\n\n if (filter.sourceType?.[0] !== 'powerTables') throw new Error('Unsupported source type');\n\n if (filter.filterType === 'RANKING') continue;\n\n const condition = this.processFilter(filter);\n if (condition) parts.push(condition);\n const searchCondition = this.processSearchFilter(filter);\n if (searchCondition) parts.push(searchCondition);\n }\n }\n\n if (parts.length === 0) return '';\n\n const joined = parts.join(` ${group.condition ?? 'AND'} `);\n\n return isRoot ? joined : `(${joined})`;\n }\n\n /**\n * Find the last ranking filter in the whole superFilter (depth-first, left-to-right traversal)\n */\n private findLastRankingFilter(group: any): IGroupFilter | null {\n if (!group?.children) return null;\n\n let last: IGroupFilter | null = null;\n\n for (const child of group.children) {\n if ('groupId' in child && 'children' in child) {\n const found = this.findLastRankingFilter(child);\n if (found) last = found;\n } else if ('filters' in child) {\n if (child.filters.filterType === 'RANKING') {\n last = child.filters as IGroupFilter;\n }\n }\n }\n\n return last;\n }\n\n /**\n * Decide which filter type to handle\n */\n private processFilter(filter: IGroupFilter): string {\n switch (filter.filterType) {\n case 'VALUES':\n return this.processValuesFilter(filter);\n case 'RANGE':\n return this.processRangeFilter(filter);\n case 'DATE': {\n const column = this.getColumnName(filter);\n return DateFilterFactory.build(column, filter);\n }\n case 'RANKING':\n // ranking filters are intentionally ignored here; they are processed in build()\n return '';\n default:\n if (!filter.searchConfig) {\n throw new Error(`Unsupported filter type: ${filter.filterType}`);\n }\n return '';\n }\n }\n\n /**\n * Handle VALUES filter => column IN/NOT IN (...)\n */\n private processValuesFilter(filter: IGroupFilter): string {\n if (!filter.valuesFilter || filter.valuesFilter.length === 0)\n throw new Error('Values filter not found');\n const column = this.getColumnName(filter);\n const values = filter.valuesFilter.flatMap((v) => v.id);\n\n const include = filter.valuesFilterApplicationType === 'include';\n const nonBlankValues = values.filter((v) => v !== '(Blank)' && v !== null);\n const hasBlank = values.length !== nonBlankValues.length;\n\n const formattedValues = nonBlankValues\n .map((v) => this.formatValue(v, this.getFilterDataType(filter)))\n .join(', ');\n\n const parts = [];\n if (nonBlankValues.length) {\n parts.push(`${column} ${include ? 'IN' : 'NOT IN'} (${formattedValues})`);\n }\n if (hasBlank) {\n let baseFilter = `${column} IS ${include ? '' : 'NOT '}NULL`;\n\n if (filter.dataType?.[0] === EFilterDataType.STRING) {\n baseFilter = `${baseFilter} OR ${column} = ''`;\n }\n parts.push(baseFilter);\n }\n\n return `(${parts.join(include ? ' OR ' : ' AND')})`;\n }\n\n /**\n * Handle RANGE filter => column op value AND/OR column op value\n */\n\n private processRangeFilter(filter: IGroupFilter): string {\n if (!filter.rangeFilter || filter.rangeFilter.length === 0)\n throw new Error('Range filter not found');\n\n const column = this.getColumnName(filter);\n const { rangeFilter } = filter;\n\n const allExpressions: string[] = [];\n\n const columnName = filter.columnNames?.[0] ?? filter.columnIds?.[0];\n const manualConfig = this.manualFilterOptions?.find((opt) => opt.column === columnName);\n\n for (const range of rangeFilter) {\n const parts: string[] = [];\n const hasFrom = range.from !== undefined && range.fromCondition !== undefined;\n const hasTo = range.to !== undefined && range.toCondition !== undefined;\n\n const dataType = this.getFilterDataType(filter);\n\n // Handle \"from\"\n if (hasFrom) {\n const op = rangeFilterOperator[range.fromCondition as RangeOperator];\n const isCharacterFilter = characterRangeFilterOperator.includes(\n range.fromCondition as RangeOperator,\n );\n\n if (isCharacterFilter) {\n if (manualConfig) {\n const manualMatch = this.getManualFilterMatch(\n range.from,\n filter,\n range.fromCondition as RangeOperator,\n manualConfig,\n );\n parts.push(manualMatch);\n } else {\n parts.push(\n this.formatRelativeCharacterFilter(\n column,\n range.fromCondition as RangeOperator,\n\n range.from,\n ),\n );\n }\n } else {\n const formattedValue = this.formatValue(range.from, dataType);\n let baseFilter = `${column} ${op} ${formattedValue}`;\n const { isBlankOperator, isNotBlankOperator } = this.getOperatorFlags(\n range.fromCondition as RangeOperator,\n );\n if (isBlankOperator && dataType === EFilterDataType.STRING) {\n baseFilter = `${baseFilter} OR ${column} = ''`;\n }\n if (isNotBlankOperator && dataType === EFilterDataType.STRING) {\n baseFilter = `${baseFilter} AND ${column} <> ''`;\n }\n parts.push(baseFilter);\n }\n }\n\n // Handle \"to\"\n if (hasTo) {\n const op = rangeFilterOperator[range.toCondition as RangeOperator];\n const isCharacterFilter = characterRangeFilterOperator.includes(\n range.toCondition as RangeOperator,\n );\n\n if (isCharacterFilter) {\n if (manualConfig) {\n const manualMatch = this.getManualFilterMatch(\n range.to,\n filter,\n range.toCondition as RangeOperator,\n manualConfig,\n );\n parts.push(manualMatch);\n } else {\n parts.push(\n this.formatRelativeCharacterFilter(\n column,\n range.toCondition as RangeOperator,\n range.to,\n ),\n );\n }\n } else {\n const formattedValue = this.formatValue(range.to, dataType);\n let baseFilter = `${column} ${op} ${formattedValue}`;\n\n const { isBlankOperator, isNotBlankOperator } = this.getOperatorFlags(\n range.fromCondition as RangeOperator,\n );\n if (isBlankOperator && dataType === EFilterDataType.STRING) {\n baseFilter = `${baseFilter} OR ${column} = ''`;\n }\n if (isNotBlankOperator && dataType === EFilterDataType.STRING) {\n baseFilter = `${baseFilter} AND ${column} <> ''`;\n }\n parts.push(baseFilter);\n }\n }\n\n if (parts.length > 0) {\n // If both exist and this range specifies a logicalOperator join with that\n if (hasFrom && hasTo && range.logicalOperator) {\n allExpressions.push(`(${parts.join(` ${range.logicalOperator.toUpperCase()} `)})`);\n } else if (parts.length === 1) {\n allExpressions.push(parts[0]);\n }\n }\n }\n\n if (allExpressions.length === 0) return '';\n\n // Top-level join fallback to filter.logicalOperator OR default AND\n return `(${allExpressions.join(` ${filter.logicalOperator?.toUpperCase() ?? 'AND'} `)})`;\n }\n\n /**\n * Handle RANKING filter (top/bottom/both)\n */\n\n private processRankingFilter(filter: IGroupFilter): string {\n if (!filter.rankingFilter || filter.rankingFilter.length === 0) {\n throw new Error('Ranking filter not found');\n }\n\n const { rankingFilter } = filter;\n const subQueries: string[] = [];\n const dataType = filter.dataType?.[0];\n const formatEntity = getEntityNameFormatter();\n\n // Step 1: Build table name without alias\n const tableName = getFormattedTableName(this.databaseDetails);\n\n // Step 2: Derive safe column names\n const targetColumn = this.getColumnName(filter);\n\n for (const rank of rankingFilter) {\n const { type, value, isPercentage, rankByColumnId } = rank;\n\n const rankByColumn = formatEntity(rankByColumnId, dataType);\n const limitCondition = isPercentage\n ? `CAST(ROUND(COUNT(*) * ${value} / 100.0) AS INT)`\n : `${value}`;\n\n const whereParts: string[] = [`${rankByColumn} IS NOT NULL`];\n if (targetColumn !== rankByColumn) {\n whereParts.push(`${targetColumn} IS NOT NULL`);\n }\n const finalWhere = whereParts.length > 0 ? `WHERE ${whereParts.join(' AND ')}` : '';\n\n // Build TOP subquery if needed\n if (type === 'TOP' || type === 'BOTH') {\n subQueries.push(`\n ${targetColumn} IN (\n SELECT ranked.${targetColumn}\n FROM (\n SELECT ${targetColumn},\n DENSE_RANK() OVER (ORDER BY ${rankByColumn} DESC) AS rn\n FROM ${tableName}\n ${finalWhere}\n ) ranked\n WHERE rn <= ${limitCondition}\n )\n `);\n }\n\n // Build BOTTOM subquery if needed\n if (type === 'BOTTOM' || type === 'BOTH') {\n subQueries.push(`\n ${targetColumn} IN (\n SELECT ranked.${targetColumn}\n FROM (\n SELECT ${targetColumn},\n DENSE_RANK() OVER (ORDER BY ${rankByColumn} ASC) AS rn\n FROM ${tableName}\n ${finalWhere}\n ) ranked\n WHERE rn <= ${limitCondition}\n )\n `);\n }\n }\n\n // Join TOP/BOTTOM subqueries with OR, wrap them to maintain AND order\n return `(${subQueries.join(' OR ')})`;\n }\n\n /**\n * Resolve column name (table.column or column only)\n */\n private getColumnName(filter: IGroupFilter): string {\n const { alias, joinRelation = [] } = this.joinClauses || {};\n let mainTableAlias = alias;\n let col = filter.columnNames?.[0] ?? filter.columnIds?.[0];\n // If any join.id matches the column, use join.id instead join.label and alias\n const matchingJoin = joinRelation.find((join) => join.id === col);\n if (matchingJoin) {\n col = matchingJoin.label;\n mainTableAlias = matchingJoin.alias as string;\n }\n const formatter = getEntityNameFormatter();\n const tableAlias = mainTableAlias ? `${formatter(mainTableAlias)}.` : '';\n if (!col) return '';\n return tableAlias + formatter(col, filter.dataType?.[0]);\n }\n\n /**\n * Get filter data type\n */\n private getFilterDataType(filter: IGroupFilter): string {\n const dataType = filter.dataType?.[0];\n if (!dataType) return '';\n return dataType;\n }\n\n /**\n * Format value depending on datatype/db\n */\n private formatValue(val: unknown, dt: string): string | null {\n if (val === null || val === undefined) return null;\n if (dt === 'date' || dt === 'datetime') {\n return `'${val}'`;\n }\n switch (typeof val) {\n case 'string':\n return `'${val}'`;\n case 'boolean':\n return val ? '1' : '0';\n default:\n return String(val);\n }\n }\n\n /**\n * Format relative character filter\n */\n private formatRelativeCharacterFilter(column: string, op: RangeOperator, value: any): string {\n switch (op) {\n case 'CONTAINS':\n return `${column} LIKE '%${value}%'`;\n case 'DOES_NOT_CONTAIN':\n return `${column} NOT LIKE '%${value}%'`;\n case 'STARTS_WITH':\n return `${column} LIKE '${value}%'`;\n case 'DOES_NOT_START_WITH':\n return `${column} NOT LIKE '${value}%'`;\n default:\n throw new Error(`Unsupported character operator: ${op}`);\n }\n }\n\n /**\n * Process search filter\n */\n public processSearchFilter(filter: IGroupFilter, isSearch = true): string {\n if (!filter.searchConfig) return '';\n\n const { joinRelation = [] } = this.joinClauses || {};\n const columnName = filter.columnNames?.[0] ?? filter.columnIds?.[0];\n const joinTableDetails = joinRelation.find((join) => join.id === columnName);\n const tableRef = joinTableDetails?.alias ?? joinTableDetails?.table;\n const formatter = getEntityNameFormatter();\n let column = this.getColumnName(filter);\n if (joinTableDetails) {\n column = `${formatter(tableRef!, filter.dataType?.[0])}.${formatter(joinTableDetails.label, filter.dataType?.[0])}`;\n }\n\n const castType = MAX_STRING_TYPE;\n const { searchString, matchCase } = filter.searchConfig;\n\n const columnExpr =\n matchCase && isSearch\n ? `CAST(${column} AS ${castType})`\n : `LOWER(CAST(${column} AS ${castType}))`;\n if (!isSearch) {\n // --- No search input mode ---\n // This handles NULL or empty strings gracefully COALESCE support all databases\n return `COALESCE(${columnExpr}, '')`;\n }\n // --- Normal search mode ---\n const valueExpr = matchCase ? `'%${searchString}%'` : `'%${searchString.toLowerCase()}%'`;\n return `${columnExpr} LIKE ${valueExpr}`;\n }\n\n private getManualFilterMatch(\n value = '',\n filter: IGroupFilter,\n operator: RangeOperator,\n manualConfig?: { column: string; options: IManualFilterOption[] },\n ): string {\n if (\n !manualConfig ||\n !Array.isArray(manualConfig.options) ||\n manualConfig.options.length === 0\n ) {\n return '';\n }\n\n const columnType = filter.dataType?.[0] || '';\n const formattedColumn = this.getColumnName(filter);\n\n const {\n isBlankOperator,\n isNotBlankOperator,\n isNegativeOperator,\n isStartsWithOperator,\n isContainsOperator,\n } = this.getOperatorFlags(operator);\n\n if (isBlankOperator) {\n return columnType !== EFilterDataType.STRING\n ? `${formattedColumn} IS NULL`\n : `${formattedColumn} IS NULL OR ${formattedColumn} = ''`;\n }\n if (isNotBlankOperator) {\n return columnType !== EFilterDataType.STRING\n ? `${formattedColumn} IS NOT NULL`\n : `${formattedColumn} IS NOT NULL AND ${formattedColumn} <> ''`;\n }\n if (!value) return isNegativeOperator ? '1=1' : '1=0';\n const matchedValues = manualConfig.options\n .filter((opt) => {\n const displayText = (opt.displayName || '').toString();\n\n if (isContainsOperator) {\n return displayText.includes(value);\n }\n\n if (isStartsWithOperator) {\n return displayText.startsWith(value);\n }\n\n return displayText.includes(value);\n })\n .map((opt) => this.formatValue(opt.id ?? opt.value, this.getFilterDataType(filter)));\n\n if (matchedValues.length > 0) {\n const sqlOperator = isNegativeOperator ? 'NOT IN' : 'IN';\n return `${formattedColumn} ${sqlOperator} (${matchedValues.join(', ')})`;\n }\n\n return isNegativeOperator ? '1=1' : '1=0';\n }\n\n private getOperatorFlags(operator: RangeOperator) {\n const isCharacterOperator = characterRangeFilterOperator.includes(operator);\n const isBlankOperator = operator === 'IS_BLANK';\n const isNotBlankOperator = operator === 'IS_NOT_BLANK';\n const isNegativeOperator = negativeCharacterOperators.includes(operator);\n const isStartsWithOperator = startsWithCharacterOperators.includes(operator);\n const isContainsOperator = containsCharacterOperators.includes(operator);\n\n return {\n isCharacterOperator,\n isBlankOperator,\n isNotBlankOperator,\n isNegativeOperator,\n isStartsWithOperator,\n isContainsOperator,\n };\n }\n}\n","import {\n IMDMColumnConfigWithParsedMeta,\n MDM_COLUMN_TYPE,\n ResolvedExpressionType,\n CteExpression,\n} from '../js-lib/ParseContext';\nimport {\n FilterConfig,\n JoinExpressions,\n Rule,\n RuleGroup,\n ISuperFilterConfig,\n IGroupFilter,\n IManualFilterConfig,\n} from '../filters/filter-types';\nimport { RUNTIME_TABLE_NAME } from '../runtime_var';\nimport { PaginationBuilder, createPaginationBuilder } from './PaginationBuilder';\nimport { From, RawSqlExpression, Select } from '../sql-types';\nimport { SelectBuilder } from '../sql-lib/select';\nimport { toColumn } from '../sql-lib/column';\nimport { processSelect } from '../sql_query_gen';\nimport {\n getCurrentDate,\n getCurrentDateTime,\n getEntityNameFormatter,\n getFormattedTableName,\n getJoinExpressions,\n resolveRuntimeVariables,\n stripWhereClause,\n} from '../utils';\nimport { SuperFilterBuilder } from './SuperFilterBuilder';\n\nexport type SortConfig = { column: string; order: 'ASC' | 'DESC' }[];\n\nexport type PaginationConfig = { skip: number; take: number };\n\nexport type FilterResolverParams = {\n filterConfig: FilterConfig;\n schema?: IColumnSchemaItem[];\n};\n\nexport interface QueryResolver {\n filterResolver(params: FilterResolverParams): string;\n}\n\nexport type RuntimeVariables = {\n $RUNTIME_LOGGEDIN_NAME: string;\n $RUNTIME_LOGGEDIN_EMAIL: string;\n $RUNTIME_CURRENT_DATE?: string;\n $RUNTIME_CURRENT_DATETIME?: string;\n};\n\nexport type QueryBuilderOptions = {\n selectedColumns: string[];\n databaseDetails: Record<string, any>;\n primaryKeyColumns: string[];\n filterConfig?: FilterConfig;\n pagination?: PaginationConfig;\n sortConfig?: SortConfig;\n searchExpression?: string;\n distinct?: boolean;\n columnConfigMap: Record<string, IMDMColumnConfigWithParsedMeta>;\n queryResolver: QueryResolver; // instance of BaseDB in database-service-link\n runtimeVariables: RuntimeVariables;\n schema?: IColumnSchemaItem[];\n includeFinalCTESelectQuery?: boolean;\n finalResponseAsObject?: boolean;\n superFilters?: ISuperFilterConfig;\n skipCountForRankingFilter?: boolean;\n joinClauses?: JoinExpressions;\n manualFilterOptions?: IManualFilterConfig[];\n enableLastSelectCTEWrap?: boolean;\n};\n\ntype BuildState = {\n pendingFilterConfig: FilterConfig;\n pendingSortConfig: SortConfig;\n isSortPending: boolean;\n isPaginationPending: boolean;\n isSearchPending: boolean;\n hasFormulaColumns: boolean;\n isSuperFilterPending: boolean;\n};\n\ntype BuildOptions = Partial<Omit<QueryBuilderOptions, 'tableName' | 'queryResolver' | 'schema'>>;\n\ntype MainCteExpression = {\n type: ResolvedExpressionType.CTE;\n cteName: string;\n value: Select;\n};\n\nexport type FinalQueryResult = {\n finalQuery: string;\n finalCteName?: string; // For group by feat need to pass cte name\n};\n\ntype CalculationOrderResult = {\n nativeColumns: Set<string>;\n formulaColumnsByDependencyLevel: IMDMColumnConfigWithParsedMeta[][];\n};\n\nexport enum DEFAULT_VALUE_TYPE {\n MANUAL = 'MANUAL',\n DERIVED = 'DERIVED',\n NONE = 'NONE',\n}\n\ntype IColumnSchemaItem = {\n name: string;\n type: string;\n defaultValue?: string | number;\n isNullable?: boolean;\n isIdentity?: boolean;\n};\n\nexport const MAX_STRING_TYPE = 'nvarchar(max)';\n\n/**\n * Steps:\n * 1. Separate out filters for native columns and formula columns\n * 2. Apply filters for native columns in the main CTE. If Native columns have sorting config then -\n * - If SortConfig exists for Formula columns with cte, do not apply sorting\n * - If SortConfig exists for Formula columns without cte, apply sorting\n * - If SortConfig does not exist for Formula columns, apply sorting\n * 3. Apply filters for formula columns in the CTE followed by the column specific CTEs due to alias not supported in where clause\n * 4. Apply SortConfig and pagination in the CTE with last filter\n * 5. Perform final projection and apply SortConfig and Pagination, if still exists\n */\nexport class QueryBuilder {\n private readonly paginationBuilder: PaginationBuilder;\n private readonly options: QueryBuilderOptions;\n\n constructor(options: QueryBuilderOptions) {\n this.options = options;\n this.paginationBuilder = createPaginationBuilder();\n }\n\n build(options: BuildOptions = {}): FinalQueryResult {\n const combinedOptions = { ...this.options, ...options };\n const impl = new QueryBuilderImpl(combinedOptions, this.paginationBuilder);\n return impl.build();\n }\n\n buildCountQuery(options: BuildOptions = {}): FinalQueryResult {\n const combinedOptions = {\n ...this.options,\n ...options,\n sortConfig: undefined, // not required for count query\n pagination: undefined, // not required for count query\n };\n const impl = new QueryBuilderImpl(combinedOptions, this.paginationBuilder);\n return impl.build(true);\n }\n}\n\n/**\n * Implementation class for QueryBuilder\n *\n * @private exposed for testing\n */\nexport class QueryBuilderImpl {\n private readonly paginationBuilder: PaginationBuilder;\n private readonly options: QueryBuilderOptions;\n private buildState: BuildState;\n private readonly entityNameFormatter: (name: string, type?: string) => string;\n\n constructor(options: QueryBuilderOptions, paginationBuilder: PaginationBuilder) {\n this.options = {\n ...options,\n searchExpression: options.searchExpression\n ? stripWhereClause(options.searchExpression)\n : undefined,\n sortConfig: this.getRelevantSortConfig(options.sortConfig, new Set(options.selectedColumns)),\n };\n this.paginationBuilder = paginationBuilder;\n this.buildState = {\n pendingFilterConfig: {\n ...(options.filterConfig ?? { combinator: 'and', not: false }),\n rules: [],\n },\n hasFormulaColumns: false,\n pendingSortConfig: [],\n isSortPending: true,\n isPaginationPending: true,\n isSearchPending: options.searchExpression !== undefined,\n isSuperFilterPending: options.superFilters !== undefined,\n };\n this.entityNameFormatter = getEntityNameFormatter();\n // Set runtime variables with current date/time values\n Object.assign(this.options.runtimeVariables, {\n $RUNTIME_CURRENT_DATE: getCurrentDate(),\n $RUNTIME_CURRENT_DATETIME: getCurrentDateTime(),\n });\n }\n\n build(isCountQuery = false): FinalQueryResult {\n const { joinClauses, superFilters } = this.options;\n const { joinRelation = [] } = joinClauses || {};\n const requiredColumns = this.filterRequiredColumns();\n this.addColumnsFromFilterConfig(requiredColumns);\n const { nativeColumns, formulaColumnsByDependencyLevel } =\n this.getCalculationOrder(requiredColumns);\n this.buildState.hasFormulaColumns = formulaColumnsByDependencyLevel.length > 0;\n this.buildState.isSuperFilterPending = superFilters !== undefined;\n\n // build main CTE and intermediate CTE for formula columns join relation\n const mainCteFormulas = joinRelation.length > 0 ? [] : formulaColumnsByDependencyLevel;\n const columnExprs = this.retrieveColumnExprsInFront(mainCteFormulas);\n const mainCTE = this.buildMainCTE(nativeColumns, columnExprs);\n const intermediateCTE = this.buildIntermediateCTE(\n mainCTE.cteName,\n formulaColumnsByDependencyLevel,\n );\n return this.buildFinalProjection(mainCTE, intermediateCTE, isCountQuery);\n }\n\n /**\n * Returns the sort config with only the columns that are part of the requested columns\n */\n private getRelevantSortConfig(\n sortConfig: SortConfig | undefined,\n requestedColumns: Set<string>,\n ): SortConfig | undefined {\n return sortConfig?.filter((s) => requestedColumns.has(s.column));\n }\n\n /**\n * Adds columns used in the filter config to the set of all columns\n */\n private addColumnsFromFilterConfig(requiredColumns: Set<string>): void {\n const { filterConfig } = this.options;\n\n if (!filterConfig) return;\n\n const traverse = (rule: Rule | RuleGroup) => {\n if ('column' in rule) {\n requiredColumns.add(rule.column);\n } else if ('rules' in rule) {\n rule.rules.forEach(traverse);\n }\n };\n filterConfig.rules.forEach(traverse);\n }\n\n private retrieveColumnExprsInFront(\n calcOrderMembers: IMDMColumnConfigWithParsedMeta[][],\n ): IMDMColumnConfigWithParsedMeta[] {\n if (calcOrderMembers.length === 0) return [];\n\n let lastColumnExprIndex = -1;\n const firstCalcOrderMembers = calcOrderMembers[0];\n for (let i = 0; i < firstCalcOrderMembers.length; i++) {\n if (\n firstCalcOrderMembers[i].columnMeta.sqlQueryProps?.resolvedExpression.type ===\n ResolvedExpressionType.COLUMN\n ) {\n lastColumnExprIndex = i;\n } else {\n break;\n }\n }\n\n if (lastColumnExprIndex === -1) {\n return [];\n }\n\n const columnExprsInFront = firstCalcOrderMembers.splice(0, lastColumnExprIndex + 1);\n if (firstCalcOrderMembers.length === 0) {\n calcOrderMembers.shift();\n }\n return columnExprsInFront;\n }\n\n private buildMainCTE(\n nativeColumns: Set<string>,\n columnExprs: IMDMColumnConfigWithParsedMeta[],\n ): MainCteExpression {\n const columnsInMainCTE = new Set([...nativeColumns, ...columnExprs.map((c) => c.columnName)]);\n const selectBuilder = new SelectBuilder();\n const { joinClauses } = this.options;\n const { alias } = joinClauses || {};\n const tableAlias = alias ? `${this.entityNameFormatter(alias)}.` : '';\n\n const columns = Array.from(nativeColumns).map((c) => {\n const schemaMatch = this.options.schema?.find((s) => s.name === c);\n return toColumn({\n type: 'sql_expr',\n value: `${tableAlias}` + this.entityNameFormatter(c, schemaMatch?.type ?? ''),\n meta: { rawColumnName: c },\n });\n });\n\n if (columnExprs.length) {\n columnExprs.forEach((c) => {\n const schemaMatch = this.options.schema?.find((s) => s.name === c.columnName);\n let resolvedExpressionValue =\n c.columnMeta.sqlQueryProps?.resolvedExpression?.value?.join(', ');\n if (resolvedExpressionValue) {\n resolvedExpressionValue = resolveRuntimeVariables(\n resolvedExpressionValue,\n this.options.runtimeVariables,\n );\n }\n columns.push(\n toColumn(\n {\n type: 'sql_expr',\n value: resolvedExpressionValue ?? '',\n meta: { rawColumnName: c.columnName },\n },\n this.entityNameFormatter(c.columnName, schemaMatch?.type ?? ''),\n ),\n );\n });\n }\n\n const formattedTableName = getFormattedTableName(this.options.databaseDetails);\n selectBuilder.addColumns(columns);\n selectBuilder.addFrom([\n {\n type: 'from',\n table: `${formattedTableName}${alias ? ` AS ${this.entityNameFormatter(alias)}` : ''}`,\n } as From,\n ]);\n\n // Build filter condition\n const where = [];\n const filterCondition = this.getFilterExpression(columnsInMainCTE);\n if (filterCondition) {\n where.push(filterCondition);\n }\n\n if (\n this.buildState.isSearchPending &&\n this.buildState.isSuperFilterPending === false &&\n this.buildState.hasFormulaColumns === false\n ) {\n this.buildState.isSearchPending = false;\n where.push(this.options.searchExpression);\n }\n if (where.length) {\n selectBuilder.addWhere({\n type: 'sql_expr',\n value: where.join(' AND '),\n } as RawSqlExpression);\n }\n\n // Build sort expression\n const sortExpression = this.getSortExpression(columnsInMainCTE);\n if (sortExpression) {\n selectBuilder.addOrderby([{ type: 'sql_expr', value: sortExpression } as RawSqlExpression]);\n }\n\n // Build pagination expression\n const paginationExpression = this.getPaginationExpression();\n if (paginationExpression) {\n selectBuilder.addLimit({\n type: 'sql_expr',\n value: paginationExpression,\n } as RawSqlExpression);\n }\n\n return {\n type: ResolvedExpressionType.CTE,\n cteName: 'cte_main',\n value: selectBuilder.build(),\n };\n }\n\n /**\n * Returns the filter expression for the selected columns. If column type is formula,\n * stores the rules in pending filter config and process it in the next call to getFilterExpression\n * else processes immediately.\n *\n * Note - Pass empty set to process any pending filter config\n */\n private getFilterExpression(columns: Set<string>): string | undefined {\n const { filterConfig, columnConfigMap, queryResolver, databaseDetails } = this.options;\n if (!filterConfig) {\n return;\n }\n\n // extract pending filter config\n const filterConfigToProcess = this.buildState.pendingFilterConfig;\n\n // Reset pending filter config\n this.buildState.pendingFilterConfig = {\n rules: [],\n combinator: filterConfig.combinator,\n not: filterConfig.not,\n };\n\n if (columns.size) {\n const nativeColumnRules: (Rule | RuleGroup)[] = [];\n const formulaColumnRules: (Rule | RuleGroup)[] = [];\n // Get rules for selected columns from original filter config\n filterConfig.rules.forEach((rule) => {\n const columnName = (rule as Rule).column ?? (rule as RuleGroup).rules[0].column;\n if (columns.has(columnName)) {\n if (columnConfigMap[columnName].columnType === MDM_COLUMN_TYPE.FORMULA) {\n formulaColumnRules.push(rule);\n\n const schema = this.options.schema ?? [];\n const exists = schema.some((col) => col.name === columnName);\n if (!exists) {\n schema.push({\n name: columnName,\n type: MAX_STRING_TYPE,\n });\n }\n } else {\n nativeColumnRules.push(rule);\n }\n }\n });\n\n // if column type is formula, store the rules in pending filter config else process immediately\n if (formulaColumnRules.length) {\n this.buildState.pendingFilterConfig.rules = formulaColumnRules;\n }\n if (nativeColumnRules.length) {\n filterConfigToProcess.rules = filterConfigToProcess.rules.concat(nativeColumnRules);\n }\n }\n\n if (filterConfigToProcess.rules.length) {\n const resolvedFilterQuery = queryResolver.filterResolver({\n filterConfig: filterConfigToProcess,\n schema: this.options.schema,\n });\n return stripWhereClause(resolvedFilterQuery);\n }\n }\n\n /**\n * Returns the sort expression if each column in the sort config is part of selected columns\n */\n private getSortExpression(columns: Set<string>): string | undefined {\n const { sortConfig, joinClauses } = this.options;\n const { alias } = joinClauses || {};\n if (!sortConfig || sortConfig.length === 0) {\n this.buildState.isSortPending = false;\n return;\n }\n\n if (this.buildState.isSortPending === false) {\n return;\n }\n\n const selectedSortColumns = sortConfig.filter((s) => columns.has(s.column));\n this.buildState.pendingSortConfig = (this.buildState.pendingSortConfig ?? []).concat(\n selectedSortColumns,\n );\n\n const hasPendingFilters = this.buildState.pendingFilterConfig.rules.length > 0;\n if (\n this.buildState.pendingSortConfig.length === sortConfig.length &&\n !hasPendingFilters &&\n !this.buildState.isSearchPending &&\n !this.buildState.isSuperFilterPending\n ) {\n this.buildState.isSortPending = false;\n return `${sortConfig.map((s) => `${alias && !this.buildState.isSuperFilterPending ? `${this.entityNameFormatter(alias)}.` : ''}${this.entityNameFormatter(s.column)} ${s.order}`).join(', ')}`;\n }\n }\n\n /**\n * Returns the pagination expression if the pagination config is set and sort is not pending.\n * It must be called after getSortExpression.\n */\n private getPaginationExpression(): string | undefined {\n const { pagination } = this.options;\n if (!pagination) {\n this.buildState.isPaginationPending = false;\n return;\n }\n\n // If pagination is already processed, return\n if (this.buildState.isPaginationPending === false) {\n return;\n }\n\n // If sort is not processed, throw error\n if (this.buildState.pendingSortConfig === undefined) {\n throw new Error('getSortExpression() must be called before getPaginationExpression()');\n }\n\n // If sort is not complete, return\n if (this.buildState.isSortPending || this.buildState.isSearchPending) {\n this.buildState.isPaginationPending = true;\n return;\n }\n\n // If pagination can be completed, return\n this.buildState.isPaginationPending = false;\n return this.paginationBuilder.generateQuery(pagination.skip, pagination.take);\n }\n\n /**\n * Builds the intermediate CTEs for the formula columns\n * 1. Replace table name with previous cte name\n * 2. Apply filter condition\n * 3. Apply sort expression, if applicable\n * 4. Apply pagination, if applicable\n * 5. Return CTEs/Column expressions\n */\n private buildIntermediateCTE(\n previousCTEName: string,\n formulaColumnsInCalcOrder: IMDMColumnConfigWithParsedMeta[][],\n ): CteExpression {\n let parentCTEName = previousCTEName;\n const tableNameRegex = new RegExp(`\\\\${RUNTIME_TABLE_NAME}`, 'g');\n\n const cteParts: string[] = [];\n formulaColumnsInCalcOrder.forEach((stageMembers) => {\n const pendingColumns: IMDMColumnConfigWithParsedMeta[] = [];\n\n stageMembers.forEach((column) => {\n const {\n columnName,\n columnMeta: { sqlQueryProps },\n } = column;\n const isCteExpression =\n sqlQueryProps?.resolvedExpression?.type === ResolvedExpressionType.CTE;\n const intermediateParts = [];\n\n if (isCteExpression) {\n // add staging cte to process any pending filters, sort, pagination\n const stagingCte = this.addStagingCTE(parentCTEName, pendingColumns);\n if (stagingCte) {\n pendingColumns.length = 0;\n parentCTEName = stagingCte!.cteName;\n intermediateParts.push(stagingCte.expr);\n }\n\n // process current column cte\n const sqlParts = this.buildSqlQueryParts([columnName]);\n const expr = sqlQueryProps.resolvedExpression as CteExpression;\n let resolvedCte = expr.value.join(', ').replace(tableNameRegex, parentCTEName);\n if (resolvedCte) {\n resolvedCte = resolveRuntimeVariables(resolvedCte, this.options.runtimeVariables);\n }\n parentCTEName = expr.cteName;\n intermediateParts.push(resolvedCte);\n if (sqlParts.length) {\n const cteName = `cte_post_${parentCTEName}`;\n const postCte = `${cteName} AS (SELECT * FROM ${parentCTEName}${sqlParts.length ? ' ' + sqlParts.join(' ') : ''})`;\n intermediateParts.push(postCte);\n parentCTEName = cteName;\n }\n cteParts.push(intermediateParts.join(', '));\n } else {\n pendingColumns.push(column);\n }\n });\n\n // add staging cte if there are pending columns at the end of stage.\n if (pendingColumns.length) {\n const stagingCte = this.addStagingCTE(parentCTEName, pendingColumns);\n pendingColumns.length = 0;\n if (stagingCte) {\n cteParts.push(stagingCte.expr);\n parentCTEName = stagingCte.cteName;\n }\n }\n });\n\n return { type: ResolvedExpressionType.CTE, cteName: parentCTEName, value: cteParts };\n }\n\n private addStagingCTE(\n parentCTEName: string,\n columnConfigs: IMDMColumnConfigWithParsedMeta[],\n ): { cteName: string; expr: string } | undefined {\n const pendingColumnsSet = new Set(columnConfigs.map((config) => config.columnName));\n const sqlParts = this.buildSqlQueryParts(Array.from(pendingColumnsSet));\n\n if (sqlParts.length !== 0 || columnConfigs.length !== 0) {\n const cteName = `cte_staging_${parentCTEName}`;\n const columnsToProject = [\n '*',\n ...columnConfigs.map((config) => {\n let resolvedExpressionValue =\n config.columnMeta.sqlQueryProps?.resolvedExpression?.value?.join(', ');\n if (resolvedExpressionValue) {\n resolvedExpressionValue = resolveRuntimeVariables(\n resolvedExpressionValue,\n this.options.runtimeVariables,\n );\n }\n return `${resolvedExpressionValue} AS ${this.entityNameFormatter(config.columnName)}`;\n }),\n ].join(', ');\n const stagingCte = `${cteName} AS (SELECT ${columnsToProject} FROM ${parentCTEName}${sqlParts.length ? ' ' + sqlParts.join(' ') : ''})`;\n return { cteName, expr: stagingCte };\n }\n }\n\n private buildFinalProjection(\n mainCTE: MainCteExpression,\n intermediateCTE: CteExpression,\n isCountQuery: boolean = false,\n ): FinalQueryResult {\n const {\n distinct,\n selectedColumns,\n includeFinalCTESelectQuery = true,\n finalResponseAsObject = false,\n joinClauses,\n enableLastSelectCTEWrap = false,\n } = this.options;\n const { joinRelation, alias } = joinClauses || {};\n const mainTableAlias = alias ? `${this.entityNameFormatter(alias)}` : '';\n\n // final query is select from main cte and intermediate cte if exists and isFilterPending is false\n const finalSqlParts = this.buildState.isSuperFilterPending ? false : true;\n const sqlParts = this.buildSqlQueryParts([], finalSqlParts);\n\n if (\n sqlParts.length === 0 &&\n intermediateCTE.value.length === 0 &&\n !this.buildState.isSuperFilterPending\n ) {\n if (joinRelation?.length) {\n mainCTE.value.from = this.applyJoinExpressionToMainCTE(mainCTE.value);\n }\n if (distinct) {\n this.applyDistinctExpressionToMainCTE(mainCTE);\n }\n const query = isCountQuery\n ? this.applyCountExpressionToMainCTE(mainCTE)\n : processSelect(mainCTE.value);\n return {\n finalQuery: query,\n };\n } else {\n let currentCteName = mainCTE.cteName;\n const cteParts = [`cte_main AS (${processSelect(mainCTE.value)})`];\n if (intermediateCTE.value.length > 0) {\n currentCteName = intermediateCTE.cteName;\n cteParts.push(intermediateCTE.value.join(', '));\n }\n let tableName = currentCteName;\n if (joinRelation?.length) {\n const joinExpr = getJoinExpressions(\n joinClauses as JoinExpressions,\n this.options?.databaseDetails,\n ).join(' ');\n sqlParts.splice(0, 0, joinExpr);\n }\n let column = '*';\n if (distinct) {\n tableName = `${tableName}${mainTableAlias ? ` AS ${mainTableAlias}` : ''}`;\n\n column = `DISTINCT ${selectedColumns\n .map((c) => {\n const schemaMatch = this.options.schema?.find((s) => s.name === c);\n return (\n `${mainTableAlias ? `${mainTableAlias}.` : ''}` +\n this.entityNameFormatter(c, schemaMatch?.type ?? '')\n );\n })\n .join(', ')}`;\n }\n if (isCountQuery) {\n if (distinct) {\n const distinctCountCte = this.getDistinctCountCte(currentCteName, sqlParts);\n sqlParts.length = 0;\n tableName = distinctCountCte.cteName;\n cteParts.push(distinctCountCte.value.join(', '));\n column = `COUNT(*) AS row_count`;\n } else {\n if (joinRelation?.length) {\n const primaryKeyColumns = this.options.primaryKeyColumns?.[0];\n if (mainTableAlias && primaryKeyColumns) {\n column = `DISTINCT ${mainTableAlias}.${this.entityNameFormatter(primaryKeyColumns)}`;\n }\n }\n column = `COUNT(${column}) AS row_count`;\n }\n }\n if (!distinct) {\n tableName = `${tableName}${mainTableAlias ? ` AS ${mainTableAlias}` : ''}`;\n }\n let selectedColumn =\n column === '*' && mainTableAlias ? `DISTINCT ${mainTableAlias}.*` : column;\n\n if (isCountQuery && this.buildState.isSuperFilterPending) {\n selectedColumn = mainTableAlias && !distinct ? `DISTINCT ${mainTableAlias}.*` : '*';\n }\n\n const selectedProjection = `SELECT ${selectedColumn} FROM ${tableName}${sqlParts.length ? ' ' + sqlParts.join(' ') : ''}`;\n\n let finalProjection = '';\n if (this.buildState.isSuperFilterPending || enableLastSelectCTEWrap) {\n const { cteDefinition, finalQuery, finalCteName } = this.buildFinalQueryComponents(\n currentCteName,\n selectedProjection,\n isCountQuery,\n distinct,\n );\n currentCteName = finalCteName;\n cteParts.push(cteDefinition);\n finalProjection = finalQuery;\n } else {\n finalProjection = selectedProjection;\n }\n const cteJoins = enableLastSelectCTEWrap\n ? cteParts.join(', ')\n : `WITH ${cteParts.join(', ')}`;\n let finalQuery = cteJoins;\n if (includeFinalCTESelectQuery) {\n finalQuery += ` ${finalProjection}`;\n }\n\n if (finalResponseAsObject) {\n return {\n finalQuery: finalQuery,\n finalCteName: currentCteName,\n };\n }\n\n return {\n finalQuery,\n };\n }\n }\n\n private applyDistinctExpressionToMainCTE(mainCTE: MainCteExpression) {\n const { selectedColumns } = this.options;\n if (mainCTE.value.columns.length > selectedColumns.length) {\n mainCTE.value.columns = mainCTE.value.columns.filter((c) => {\n return selectedColumns.includes(c.expr.meta?.rawColumnName);\n });\n }\n mainCTE.value.distinct = 'DISTINCT';\n }\n\n private applyCountExpressionToMainCTE(mainCTE: MainCteExpression): string {\n if (mainCTE.value.distinct) {\n const mainCteResult = `WITH cte_main AS (${processSelect(mainCTE.value)})`;\n return `${mainCteResult} SELECT COUNT(*) AS row_count FROM cte_main`;\n }\n\n const columnValue =\n mainCTE.value.columns.length > 1 ? '*' : `${mainCTE.value.columns[0].expr.value}`;\n mainCTE.value.columns[0].expr.value = `COUNT(${columnValue})`;\n mainCTE.value.columns[0].as = `row_count`;\n mainCTE.value.columns.length = 1;\n return processSelect(mainCTE.value);\n }\n\n private getDistinctCountCte(parentCTEName: string, sqlParts: string[]): CteExpression {\n const { selectedColumns, joinClauses } = this.options;\n const { alias } = joinClauses || {};\n const cteName = `cte_distinct_${parentCTEName}`;\n const fromName = `${parentCTEName}${alias ? ` AS ${this.entityNameFormatter(alias)}` : ''}`;\n return {\n type: ResolvedExpressionType.CTE,\n cteName,\n value: [\n `${cteName} AS (SELECT DISTINCT ${selectedColumns.map((c) => `${alias ? `${this.entityNameFormatter(alias)}.` : ''}` + this.entityNameFormatter(c)).join(', ')} FROM ${fromName}${sqlParts.length ? ' ' + sqlParts.join(' ') : ''})`,\n ],\n };\n }\n\n private buildSqlQueryParts(columns: string[], isFinalProjection = false): string[] {\n const sqlParts = [];\n\n const where = [];\n const filterCondition = this.getFilterExpression(new Set(columns));\n if (filterCondition) {\n where.push(filterCondition);\n }\n if (columns.length === 0 && this.buildState.isSuperFilterPending) {\n const superFilterCondition = this.getSuperFilterExpression(isFinalProjection);\n if (superFilterCondition) {\n where.push(superFilterCondition);\n }\n }\n if (columns.length === 0 && this.buildState.isSearchPending) {\n this.buildState.isSearchPending = false;\n where.push(this.options.searchExpression);\n }\n if (where.length) {\n sqlParts.push(`WHERE ${where.join(' AND ')}`);\n }\n\n const sortExpression = this.getSortExpression(new Set(columns));\n if (sortExpression) {\n sqlParts.push(`ORDER BY ${sortExpression}`);\n }\n\n const paginationExpression = this.getPaginationExpression();\n if (paginationExpression) {\n sqlParts.push(paginationExpression);\n }\n\n return sqlParts;\n }\n\n /**\n * Returns the calculation order for the given columns\n * @private exposed for testing\n */\n public getCalculationOrder(columns: Set<string>): CalculationOrderResult {\n const state = {\n dependencyLevel: -1,\n dependencyLevelMap: new Map<string, number>(),\n nativeColumns: new Set<string>(),\n visited: new Set<string>(),\n };\n\n // trigger dependency tracing for each column\n columns.forEach((columnName) => {\n state.dependencyLevel = -1; // reset dependency level for each column\n this.dfs(columnName, state);\n });\n\n // build output\n const formulaColumnsByDependencyLevel: IMDMColumnConfigWithParsedMeta[][] = [];\n for (const [columnName, level] of state.dependencyLevelMap) {\n const columnConfig = this.options.columnConfigMap[columnName];\n if (level >= formulaColumnsByDependencyLevel.length) {\n formulaColumnsByDependencyLevel.push([]);\n }\n formulaColumnsByDependencyLevel[level].push(columnConfig);\n }\n\n return {\n nativeColumns: state.nativeColumns,\n formulaColumnsByDependencyLevel,\n };\n }\n\n private dfs(\n columnName: string,\n state: {\n dependencyLevel: number;\n dependencyLevelMap: Map<string, number>;\n nativeColumns: Set<string>;\n visited: Set<string>;\n },\n ) {\n // If dependency level is already resolved, return\n const level = state.dependencyLevelMap.get(columnName);\n if (level !== undefined) {\n if (level > state.dependencyLevel) {\n state.dependencyLevel = level;\n }\n return;\n }\n\n if (state.visited.has(columnName)) {\n throw new Error(`Cycle detected in formula dependencies: ${columnName}`);\n }\n\n const columnConfig = this.options.columnConfigMap[columnName];\n const { columnType, columnMeta } = columnConfig;\n const { sqlQueryProps, isCustomColumn, deps, defaultValueType } = columnMeta;\n\n const isNativeColumn =\n columnType !== MDM_COLUMN_TYPE.FORMULA && defaultValueType !== DEFAULT_VALUE_TYPE.DERIVED;\n const isFormulaDbColumn =\n columnType === MDM_COLUMN_TYPE.FORMULA && !sqlQueryProps && !isCustomColumn && !deps;\n const isDerivedDbColumn =\n defaultValueType === DEFAULT_VALUE_TYPE.DERIVED && !sqlQueryProps && !deps;\n\n if (isNativeColumn || isFormulaDbColumn || isDerivedDbColumn) {\n state.nativeColumns.add(columnName);\n return;\n }\n\n // Skip processing to maintain backward compatibility with older formula visual columns\n if (columnType === MDM_COLUMN_TYPE.FORMULA && isCustomColumn && !sqlQueryProps) {\n return;\n }\n\n state.visited.add(columnName);\n deps?.forEach((colName) => {\n this.dfs(colName, state);\n });\n\n state.visited.delete(columnName);\n state.dependencyLevelMap.set(columnName, ++state.dependencyLevel);\n }\n\n /**\n * Applies the join positions from the query builder to the given Select AST.\n * The join positions are added to the FROM list of the AST.\n *\n * @param {Select} ast - The Select AST to apply the join positions to.\n * @returns {string[]} - An empty array, for consistency with other methods.\n */\n private applyJoinExpressionToMainCTE(ast: Select): From[] {\n const { joinClauses, databaseDetails } = this.options;\n const joinExpressions = getJoinExpressions(joinClauses as JoinExpressions, databaseDetails);\n const joins: From[] = joinExpressions.map((j) => {\n const raw: RawSqlExpression = { type: 'sql_expr', value: j };\n return raw as unknown as From;\n });\n if (joins.length) {\n ast.distinct = 'DISTINCT';\n }\n const joinFroms = ast.from as From[];\n // set the FROM list as base table + joins\n return joinFroms?.concat(joins);\n }\n\n /**\n * Gets the super filter expression.\n * If super filters are present and the pending filter config is not empty,\n * it will process the super filter condition and return the result.\n * If the super filter expression is empty, it will return an empty string.\n * @returns {string} - The super filter expression.\n */\n private getSuperFilterExpression(isFinalProjection?: boolean): string {\n if (!this.options.superFilters || !this.options.superFilters.children.length) return '';\n const { superFilters, manualFilterOptions } = this.options;\n\n const { children } = superFilters;\n const { rankingFilters, nonRankingFilters } = children.reduce(\n (acc, child) => {\n if ('groupId' in child && 'children' in child) {\n acc.nonRankingFilters.push(child);\n } else if ('filters' in child) {\n const filterType = (child as { filters: IGroupFilter }).filters.filterType;\n if (filterType === 'RANKING') {\n acc.rankingFilters.push(child);\n } else {\n acc.nonRankingFilters.push(child);\n }\n }\n return acc;\n },\n {\n rankingFilters: [] as typeof children,\n nonRankingFilters: [] as typeof children,\n },\n );\n\n let activeFilters = { ...superFilters, children: nonRankingFilters };\n let joinClauses = this.options.joinClauses;\n\n // Process ranking filters if pending and available\n if (rankingFilters.length && isFinalProjection && this.buildState.isSuperFilterPending) {\n activeFilters = { ...superFilters, children: rankingFilters };\n joinClauses = { alias: '', joinRelation: [] };\n }\n if (rankingFilters.length === 0) {\n this.buildState.isSuperFilterPending = false;\n }\n if (activeFilters.children.length) {\n const sqlQueryBuilder = new SuperFilterBuilder(\n activeFilters,\n this.options.databaseDetails,\n this.options.skipCountForRankingFilter,\n joinClauses,\n manualFilterOptions,\n );\n return sqlQueryBuilder.build();\n }\n\n return '';\n }\n\n private buildFinalQueryComponents(\n currentCteName: string,\n selectProjection: string,\n isCountQuery: boolean,\n distinct: boolean,\n ): { cteDefinition: string; finalQuery: string; finalCteName: string } {\n const { selectedColumns, enableLastSelectCTEWrap } = this.options;\n let selectQuery = '*';\n if (distinct && !isCountQuery) {\n selectQuery = `DISTINCT ${selectedColumns\n .map((c) => {\n const schemaMatch = this.options.schema?.find((s) => s.name === c);\n return this.entityNameFormatter(c, schemaMatch?.type ?? '');\n })\n .join(', ')}`;\n }\n\n let finalCteName = `${currentCteName}_main_cte`;\n let cteDefinition = `${finalCteName} AS (${selectProjection})`;\n\n const columns = isCountQuery ? `COUNT(${selectQuery}) AS row_count` : `${selectQuery}`;\n const sqlParts = this.buildSqlQueryParts([], true);\n\n const finalQuery = `SELECT ${columns} FROM ${finalCteName}${sqlParts.length ? ' ' + sqlParts.join(' ') : ''}`;\n\n if (enableLastSelectCTEWrap && this.buildState.isSuperFilterPending) {\n finalCteName = `${finalCteName}_main_cte`;\n cteDefinition = ` ${cteDefinition},${finalCteName} AS (${finalQuery})`;\n }\n\n this.buildState.isSuperFilterPending = false;\n\n return { cteDefinition, finalQuery, finalCteName };\n }\n\n private filterRequiredColumns(): Set<string> {\n const {\n selectedColumns,\n superFilters,\n primaryKeyColumns,\n sortConfig = [],\n joinClauses,\n } = this.options;\n const requiredColumn = new Set<string>(selectedColumns);\n if (superFilters?.children?.length) {\n // Collect all columnIds from superFilters\n (superFilters?.children as { filters: IGroupFilter }[])?.forEach((child) => {\n const filterColumn = child.filters?.columnIds?.[0];\n if (filterColumn) requiredColumn.add(filterColumn);\n child?.filters?.rankingFilter?.forEach?.((rank) => {\n if (rank?.rankByColumnName) requiredColumn.add(rank.rankByColumnName);\n });\n });\n primaryKeyColumns.forEach((col) => {\n requiredColumn.add(col);\n });\n sortConfig.forEach((col) => {\n requiredColumn.add(col?.column);\n });\n }\n // Add all columnIds from joinRelation\n for (const { id } of joinClauses?.joinRelation ?? []) {\n if (id != null) requiredColumn.add(id);\n }\n\n return requiredColumn;\n }\n}\n","import { Binary, ExpressionValue } from '../sql-types';\n\nexport function toBinaryExpression(\n operator: string,\n left: ExpressionValue,\n right: ExpressionValue,\n parentheses = false,\n): Binary {\n return {\n type: 'binary_expr',\n operator,\n left,\n right,\n parentheses,\n };\n}\n","import { ExpressionValue, SqlFunction, ValueExpr } from '../sql-types';\n\nexport function toFunction(name: ValueExpr<string>, args: ExpressionValue[]): SqlFunction {\n return {\n type: 'function',\n name: { name: [name] },\n args: { type: 'expr_list', value: args },\n };\n}\n","import { ParseContext } from '../ParseContext';\nimport { ExpressionValue, SqlFunction } from '../../sql-types';\n\nexport type ObjectFn<T> = (context: ParseContext, ...args: T[]) => BaseObject;\nexport type PropertyFn = (context: ParseContext) => ExpressionValue | SqlFunction;\n\nexport abstract class BaseObject {\n protected _fnMap: Map<string, ObjectFn<ExpressionValue>>;\n protected _propertyMap: Map<string, PropertyFn>;\n\n constructor() {\n this._fnMap = new Map<string, ObjectFn<ExpressionValue>>();\n this._propertyMap = new Map<string, PropertyFn>();\n }\n\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n resolve(...args: ExpressionValue[]): ExpressionValue | SqlFunction {\n throw new Error('Not implemented');\n }\n\n get fnMap(): Map<string, ObjectFn<ExpressionValue>> {\n return this._fnMap;\n }\n\n get propertyMap(): Map<string, PropertyFn> {\n return this._propertyMap;\n }\n}\n","import { toBinaryExpression } from '../../sql-lib/binary_expr';\nimport { toFunction } from '../../sql-lib/function';\nimport { ExpressionValue, SqlFunction, ValueExpr } from '../../sql-types';\nimport { BaseObject } from './BaseObject';\n\nexport class PctObject extends BaseObject {\n private arg: ExpressionValue;\n\n constructor(arg: ExpressionValue) {\n super();\n const name = { type: 'default', value: 'CAST' } as ValueExpr<string>;\n const castType = 'FLOAT';\n const argValue = toFunction(name, [\n toBinaryExpression('AS', arg, { type: 'default', value: castType }),\n ]);\n this.arg = toBinaryExpression('/', argValue, { type: 'number', value: 100 }, true);\n }\n\n resolve(...args: ExpressionValue[]): ExpressionValue | SqlFunction {\n const [lhs, op] = args;\n const pctValue = this.getPctValue((op as ValueExpr<string>).value);\n return toBinaryExpression('*', lhs, pctValue);\n }\n\n private getPctValue(op: string): ExpressionValue {\n if (op === '+' || op === '-') {\n return toBinaryExpression(op, { type: 'number', value: 1 }, this.arg, true);\n }\n return { type: 'null', value: null };\n }\n}\n","import { Binary, ExpressionValue } from '../sql-types';\n\nexport type WhenType = {\n type: 'when';\n cond: Binary;\n result: ExpressionValue;\n};\n\nexport function toWhen(cond: Binary, result: ExpressionValue): WhenType {\n return {\n type: 'when',\n cond,\n result,\n };\n}\n","import { ExpressionValue } from '../sql-types';\n\nexport type ElseType = {\n type: 'else';\n result: ExpressionValue;\n};\n\nexport function toElse(result: ExpressionValue): ElseType {\n return {\n type: 'else',\n result,\n };\n}\n","import { Binary, Case, ExpressionValue } from '../sql-types';\n\nexport function toCase(args: {\n whenList: {\n cond: Binary;\n result: ExpressionValue;\n type: 'when';\n }[];\n elseResult: { type: 'else'; result: ExpressionValue };\n}): Case {\n return {\n type: 'case',\n expr: null,\n args: [...args.whenList, args.elseResult],\n };\n}\n","import { ExpressionValue, UnaryExpression } from '../sql-types';\n\nexport function toUnaryExpression(operator: string, expr: ExpressionValue): UnaryExpression {\n return {\n type: 'unary_expr',\n operator,\n expr,\n };\n}\n","import { Binary, Join } from '../sql-types';\n\nexport type JoinType = 'INNER JOIN' | 'LEFT JOIN' | 'RIGHT JOIN';\n\nexport function toJoin(joinType: JoinType, table: string, on: Binary): Join {\n return {\n type: 'from',\n db: null,\n table,\n as: null,\n join: joinType,\n on,\n };\n}\n","/**\n * validators.ts\n *\n * This file contains reusable validation functions for transform argument checking.\n * Each validator accepts the parsing context and arguments to validate types, argument count, etc.\n *\n * These functions help keep transform functions clean by centralizing validation logic,\n * providing consistent error handling and context updates.\n *\n * Usage:\n * import { concatenateTransformValidator, dateArgumentValidator } from './validators';\n *\n * // In your transform function:\n * concatenateTransformValidator(context, args);\n * dateArgumentValidator(context, dateArg, 'MONTH');\n */\n\nimport { ParseContext } from '../../ParseContext';\nimport { ExpressionValue } from '../../../sql-types';\nimport { getArgType } from '@/utils';\n\nexport function ifTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 3) {\n context.isValid = false;\n context.error = 'IF() requires 3 arguments';\n return;\n }\n const trueValueType = getArgType(args[1], context);\n const falseValueType = getArgType(args[2], context);\n if (trueValueType !== falseValueType) {\n context.isValid = false;\n context.error = `Both true value and false value should of same type`;\n return;\n }\n if (falseValueType) context.returnType = falseValueType;\n}\n\nexport function todayTransformValidator(context: ParseContext): void {\n context.returnType = 'date';\n}\n\nexport function nowTransformValidator(context: ParseContext): void {\n context.returnType = 'datetime';\n}\n\nexport function concatenateTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 2) {\n context.isValid = false;\n context.error = 'CONCATENATE() requires at least 2 arguments';\n return;\n }\n context.returnType = 'string';\n}\n\nexport function lowerTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'LOWER() requires 1 argument';\n return;\n }\n if (getArgType(arg, context) !== 'string') {\n context.isValid = false;\n context.error = 'Argument to LOWER must be of type string';\n return;\n }\n context.returnType = 'string';\n}\n\nexport function dateArgumentValidator(context: ParseContext, arg: ExpressionValue, fnName: string) {\n if (!arg) {\n context.isValid = false;\n context.error = `${fnName}() requires 1 argument`;\n return;\n }\n if (getArgType(arg, context) !== 'date') {\n context.isValid = false;\n context.error = `Argument to ${fnName} must be of type date in format 'YYYY-MM-DD'`;\n return;\n }\n context.returnType = 'number';\n}\n\nexport function trimTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'TRIM() requires 1 argument';\n return;\n }\n if (getArgType(arg, context) !== 'string') {\n context.isValid = false;\n context.error = 'Argument to TRIM must be of type string';\n return;\n }\n context.returnType = 'string';\n}\n\nexport function upperTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'UPPER() requires 1 argument';\n return;\n }\n if (getArgType(arg, context) !== 'string') {\n context.isValid = false;\n context.error = 'Argument to UPPER must be of type string';\n return;\n }\n context.returnType = 'string';\n}\n\nexport function lenTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'LEN() requires exactly 1 argument';\n return;\n }\n if (getArgType(arg, context) !== 'string') {\n context.isValid = false;\n context.error = 'Argument to LEN must be of type string';\n return;\n }\n context.returnType = 'number';\n}\n\nexport function leftTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 2) {\n context.isValid = false;\n context.error = 'LEFT() requires exactly 2 arguments';\n return;\n }\n if (getArgType(args[0], context) !== 'string') {\n context.isValid = false;\n context.error = 'First argument to LEFT must be of type string';\n return;\n }\n if (getArgType(args[1], context) !== 'number') {\n context.isValid = false;\n context.error = 'Second argument to LEFT must be of type number';\n return;\n }\n context.returnType = 'string';\n}\n\nexport function rightTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 2) {\n context.isValid = false;\n context.error = 'RIGHT() requires exactly 2 arguments';\n return;\n }\n if (getArgType(args[0], context) !== 'string') {\n context.isValid = false;\n context.error = 'First argument to RIGHT must be of type string';\n return;\n }\n if (getArgType(args[1], context) !== 'number') {\n context.isValid = false;\n context.error = 'Second argument to RIGHT must be of type number';\n return;\n }\n context.returnType = 'string';\n}\n\nexport function replaceTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n const types = ['string', 'number', 'number', 'string'];\n if (args.length !== types.length) {\n context.isValid = false;\n context.error = 'REPLACE() requires 4 arguments';\n return;\n }\n args.forEach((arg, i) => {\n if (getArgType(arg, context) !== types[i]) {\n context.isValid = false;\n context.error = `Argument ${i + 1} to REPLACE must be of type ${types[i]}`;\n return;\n }\n });\n context.returnType = 'string';\n}\n\nexport function reptTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n const types = ['string', 'number'];\n if (args.length !== types.length) {\n context.isValid = false;\n context.error = 'REPT() requires 2 arguments';\n return;\n }\n args.forEach((arg, i) => {\n if (getArgType(arg, context) !== types[i]) {\n context.isValid = false;\n context.error = `Argument ${i + 1} to REPT must be of type ${types[i]}`;\n return;\n }\n });\n context.returnType = 'string';\n}\n\nexport function matchTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n const types = ['string', 'string'];\n if (args.length !== types.length) {\n context.isValid = false;\n context.error = 'MATCH() requires 2 arguments';\n return;\n }\n args.forEach((arg, i) => {\n if (getArgType(arg, context) !== types[i]) {\n context.isValid = false;\n context.error = `Argument ${i + 1} to MATCH must be of type ${types[i]}`;\n return;\n }\n });\n context.returnType = 'boolean';\n}\n\nexport function dateAddTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 2) {\n context.isValid = false;\n context.error = 'DATEADD() requires 2 arguments';\n return;\n }\n if (getArgType(args[0], context) !== 'date') {\n context.isValid = false;\n context.error = \"First argument to DATEADD must be of type date in format 'YYYY-MM-DD'\";\n return;\n }\n if (getArgType(args[1], context) !== 'number') {\n context.isValid = false;\n context.error = 'Second argument to DATEADD must be of type number';\n return;\n }\n context.returnType = 'date';\n}\n\nexport function dateDiffTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 2) {\n context.isValid = false;\n context.error = 'DATEDIFF() requires 2 arguments';\n return;\n }\n const types = ['date', 'date'];\n args.forEach((arg, i) => {\n if (getArgType(arg, context) !== types[i]) {\n context.isValid = false;\n context.error = `Argument ${i + 1} to DATEDIFF must be of type ${types[i]} in format 'YYYY-MM-DD'`;\n return;\n }\n });\n context.returnType = 'number';\n}\n\nexport function dayTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'DAY() requires 1 argument';\n return;\n }\n if (getArgType(arg, context) !== 'date') {\n context.isValid = false;\n context.error = \"Argument to DAY must be of type date in format 'YYYY-MM-DD'\";\n return;\n }\n context.returnType = 'number';\n}\n\nexport function monthTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'MONTH() requires 1 argument';\n return;\n }\n if (getArgType(arg, context) !== 'date') {\n context.isValid = false;\n context.error = \"Argument to MONTH must be of type date in format 'YYYY-MM-DD'\";\n return;\n }\n context.returnType = 'number';\n}\n\nexport function yearTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'YEAR() requires 1 argument';\n return;\n }\n if (getArgType(arg, context) !== 'date') {\n context.isValid = false;\n context.error = \"Argument to YEAR must be of type date in format 'YYYY-MM-DD'\";\n return;\n }\n context.returnType = 'number';\n}\n\nexport function eomonthTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 1 || args.length > 2) {\n context.isValid = false;\n context.error = 'EOMONTH() requires 1 or 2 arguments';\n return;\n }\n\n if (getArgType(args[0], context) !== 'date') {\n context.isValid = false;\n context.error = \"First argument to EOMONTH must be of type date in format 'YYYY-MM-DD'\";\n return;\n }\n\n if (args.length === 2 && getArgType(args[1], context) !== 'number') {\n context.isValid = false;\n context.error = 'Second argument to EOMONTH must be of type number';\n return;\n }\n\n context.returnType = 'date';\n}\n\nexport function divideTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 2) {\n context.isValid = false;\n context.error = 'DIVIDE() requires 2 arguments';\n return;\n }\n\n const types = ['number', 'number'];\n args.forEach((arg, i) => {\n if (getArgType(arg, context) !== types[i]) {\n context.isValid = false;\n context.error = `Argument ${i + 1} to DIVIDE must be of type ${types[i]}`;\n return;\n }\n });\n\n context.returnType = 'number';\n}\n\nexport function andTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 2) {\n context.isValid = false;\n context.error = 'AND() requires at least 2 arguments';\n return;\n }\n\n args.forEach((arg, i) => {\n if (getArgType(arg, context) !== 'boolean') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to AND must be of type boolean`;\n return;\n }\n });\n\n context.returnType = 'boolean';\n}\n\nexport function orTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 2) {\n context.isValid = false;\n context.error = 'OR() requires at least 2 arguments';\n return;\n }\n\n args.forEach((arg, i) => {\n if (getArgType(arg, context) !== 'boolean') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to OR must be of type boolean`;\n return;\n }\n });\n\n context.returnType = 'boolean';\n}\n\nexport function ceilTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'CEIL() requires 1 argument';\n return;\n }\n\n if (getArgType(arg, context) !== 'number') {\n context.isValid = false;\n context.error = 'Argument to CEIL must be of type number';\n return;\n }\n\n context.returnType = 'number';\n}\n\nexport function floorTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'FLOOR() requires 1 argument';\n return;\n }\n\n if (getArgType(arg, context) !== 'number') {\n context.isValid = false;\n context.error = 'Argument to FLOOR must be of type number';\n return;\n }\n\n context.returnType = 'number';\n}\n\nexport function absTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'ABS() requires 1 argument';\n return;\n }\n\n if (getArgType(arg, context) !== 'number') {\n context.isValid = false;\n context.error = 'Argument to ABS must be of type number';\n return;\n }\n\n context.returnType = 'number';\n}\n\nexport function roundTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 1 || args.length > 2) {\n context.isValid = false;\n context.error = 'ROUND() requires 1 or 2 arguments';\n return;\n }\n\n const valueType = getArgType(args[0], context);\n if (valueType !== 'number') {\n context.isValid = false;\n context.error = 'First argument to ROUND must be of type number';\n return;\n }\n\n if (args[1]) {\n const decimalType = getArgType(args[1], context);\n if (decimalType !== 'number') {\n context.isValid = false;\n context.error = 'Second argument to ROUND must be of type number';\n return;\n }\n }\n\n context.returnType = 'number';\n}\n\nexport function expTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'EXP() requires exactly 1 argument';\n return;\n }\n const type = getArgType(arg, context);\n if (type !== 'number') {\n context.isValid = false;\n context.error = 'Argument to EXP must be of type number';\n return;\n }\n context.returnType = 'number';\n}\n\nexport function powTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 2) {\n context.isValid = false;\n context.error = 'POW() requires exactly 2 arguments';\n return;\n }\n const types = ['number', 'number'];\n args.forEach((arg, i) => {\n if (getArgType(arg, context) !== types[i]) {\n context.isValid = false;\n context.error = `Argument ${i + 1} to POW must be of type ${types[i]}`;\n return;\n }\n });\n context.returnType = 'number';\n}\n\nexport function logTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 1 || args.length > 2) {\n context.isValid = false;\n context.error = 'LOG() requires 1 or 2 arguments';\n return;\n }\n args.forEach((arg, i) => {\n if (getArgType(arg, context) !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to LOG must be of type number`;\n return;\n }\n });\n context.returnType = 'number';\n}\n\nexport function sqrtTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'SQRT() requires exactly 1 arguments';\n return;\n }\n if (getArgType(arg, context) !== 'number') {\n context.isValid = false;\n context.error = 'Argument to SQRT must be of type number';\n return;\n }\n context.returnType = 'number';\n}\n\nexport function modTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 2) {\n context.isValid = false;\n context.error = 'MOD() requires exactly 2 arguments';\n return;\n }\n const types = ['number', 'number'];\n args.forEach((arg, i) => {\n if (getArgType(arg, context) !== types[i]) {\n context.isValid = false;\n context.error = `Argument ${i + 1} to MOD must be of type ${types[i]}`;\n return;\n }\n });\n context.returnType = 'number';\n}\n\nexport function notTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'NOT() requires exactly 1 argument';\n return;\n }\n if (getArgType(arg, context) !== 'boolean') {\n context.isValid = false;\n context.error = 'Argument to NOT must be of type boolean';\n return;\n }\n context.returnType = 'boolean';\n}\n\nexport function randTransformValidator(context: ParseContext) {\n context.returnType = 'number';\n}\n\nexport function randBetweenTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 2) {\n context.isValid = false;\n context.error = 'RAND_BETWEEN() requires exactly 2 arguments';\n return;\n }\n const types = ['number', 'number'];\n args.forEach((arg, i) => {\n if (getArgType(arg, context) !== types[i]) {\n context.isValid = false;\n context.error = `Argument ${i + 1} to RAND_BETWEEN must be of type ${types[i]}`;\n return;\n }\n });\n context.returnType = 'number';\n}\n\nexport function averageTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 1) {\n context.isValid = false;\n context.error = 'AVERAGE() requires at least 1 argument';\n return;\n }\n for (let i = 0; i < args.length; i++) {\n if (getArgType(args[i], context) !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to AVERAGE must be of type number`;\n return;\n }\n }\n context.returnType = 'number';\n}\n\nexport function averageIfTransformValidator(\n context: ParseContext,\n valueList: ExpressionValue[],\n condition: ExpressionValue,\n) {\n if (valueList.length < 1) {\n context.isValid = false;\n context.error = 'AVERAGE_IF() requires at least one value to average';\n return;\n }\n\n for (let i = 0; i < valueList.length; i++) {\n if (getArgType(valueList[i], context) !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} in value list must be of type number`;\n return;\n }\n }\n\n if (condition.type !== 'string') {\n context.isValid = false;\n context.error =\n 'The first argument in AVERAGE_IF must be a string representing a condition expression';\n return;\n }\n\n context.returnType = 'number';\n}\n\nexport function averageXNegTransformValidator(context: ParseContext, valueList: ExpressionValue[]) {\n if (valueList.length < 1) {\n context.isValid = false;\n context.error = 'AVERAGE_X_NEG() requires at least one numeric argument';\n return;\n }\n for (let i = 0; i < valueList.length; i++) {\n if (getArgType(valueList[i], context) !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to AVERAGE_X_NEG must be of type number`;\n return;\n }\n }\n context.returnType = 'number';\n}\n\nexport function averageXZeroTransformValidator(\n context: ParseContext,\n valueList: ExpressionValue[],\n) {\n if (valueList.length < 1) {\n context.isValid = false;\n context.error = 'AVERAGE_X_ZERO() requires at least one numeric argument';\n return;\n }\n for (let i = 0; i < valueList.length; i++) {\n if (getArgType(valueList[i], context) !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to AVERAGE_X_ZERO must be of type number`;\n return;\n }\n }\n context.returnType = 'number';\n}\n\nexport function averageXZeroNegTransformValidator(\n context: ParseContext,\n valueList: ExpressionValue[],\n) {\n if (valueList.length < 1) {\n context.isValid = false;\n context.error = 'AVERAGE_X_ZERO_NEG() requires at least one numeric argument';\n return;\n }\n for (let i = 0; i < valueList.length; i++) {\n if (getArgType(valueList[i], context) !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to AVERAGE_X_ZERO_NEG must be of type number`;\n return;\n }\n }\n context.returnType = 'number';\n}\n\nexport function numberValueTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 1 || args.length > 3) {\n context.isValid = false;\n context.error = 'NUMBERVALUE() requires 1, 2, or 3 arguments';\n return;\n }\n if (getArgType(args[0], context) !== 'string' && getArgType(args[0], context) !== 'number') {\n context.isValid = false;\n context.error = 'First argument to NUMBERVALUE must be string or number';\n return;\n }\n if (args[1] && getArgType(args[1], context) !== 'string') {\n context.isValid = false;\n context.error = 'Second argument to NUMBERVALUE must be string';\n return;\n }\n if (args[2] && getArgType(args[2], context) !== 'string') {\n context.isValid = false;\n context.error = 'Third argument to NUMBERVALUE must be string';\n return;\n }\n context.returnType = 'number';\n}\n\nexport function oddTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'ODD() requires 1 argument';\n return;\n }\n if (getArgType(arg, context) !== 'number') {\n context.isValid = false;\n context.error = 'Argument to ODD must be of type number';\n return;\n }\n context.returnType = 'number';\n}\n\nexport function evenTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'EVEN() requires 1 argument';\n return;\n }\n if (getArgType(arg, context) !== 'number') {\n context.isValid = false;\n context.error = 'Argument to EVEN must be of type number';\n return;\n }\n context.returnType = 'number';\n}\n\nexport function inTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 2) {\n context.isValid = false;\n context.error = 'IN() requires exactly 2 arguments: column and an array of values';\n return;\n }\n const [column, values] = args;\n const columnType = getArgType(column, context);\n if (columnType === null || !['string', 'number'].includes(columnType)) {\n context.isValid = false;\n context.error =\n 'First argument to IN must be a string or number or column reference of type string or number';\n return;\n }\n if (values.type !== 'expr_list' || !Array.isArray(values.value)) {\n context.isValid = false;\n context.error = 'Second argument to IN must be an array of values';\n return;\n }\n context.returnType = 'boolean';\n}\n\nexport function sumTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 1) {\n context.isValid = false;\n context.error = 'SUM() requires 1 or more arguments';\n return;\n }\n for (let i = 0; i < args.length; i++) {\n const argType = getArgType(args[i], context);\n if (argType !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to SUM must be of type number`;\n return;\n }\n }\n context.returnType = 'number';\n}\n\nexport function indexOfTransformValidator(\n context: ParseContext,\n valueList: ExpressionValue[],\n valueToFind: ExpressionValue,\n) {\n if (!valueList || !valueToFind) {\n context.isValid = false;\n context.error = 'INDEXOF() requires 2 arguments';\n return;\n }\n if (!Array.isArray(valueList) || valueList.length === 0) {\n context.isValid = false;\n context.error = 'First argument to INDEXOF must be a non-empty array';\n return;\n }\n for (let i = 0; i < valueList.length; i++) {\n const t = getArgType(valueList[i], context);\n if (t !== 'string' && t !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} in valueList must be string or number`;\n return;\n }\n }\n const searchType = getArgType(valueToFind, context);\n if (searchType !== 'string' && searchType !== 'number') {\n context.isValid = false;\n context.error = 'Second argument to INDEXOF must be string or number';\n return;\n }\n context.returnType = 'number';\n}\n\nexport function isEmptyTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'ISEMPTY() requires exactly 1 argument';\n return;\n }\n const type = getArgType(arg, context);\n if (!['string', 'null'].includes(type || '')) {\n context.isValid = false;\n context.error = 'Argument to ISEMPTY must be of type string or null';\n return;\n }\n context.returnType = 'boolean';\n}\n\nexport function isNumberTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'ISNUMBER() requires exactly 1 argument';\n return;\n }\n const type = getArgType(arg, context);\n if (type !== 'string' && type !== 'number') {\n context.isValid = false;\n context.error = 'Argument to ISNUMBER must be of type string or number';\n return;\n }\n context.returnType = 'boolean';\n}\n\nexport function maxAggregateTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 1) {\n context.isValid = false;\n context.error = 'GREATEST() requires 1 or more arguments';\n return;\n }\n for (let i = 0; i < args.length; i++) {\n const type = getArgType(args[i], context);\n if (type !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to GREATEST must be of type number`;\n return;\n }\n }\n context.returnType = 'number';\n}\n\nexport function minAggregateTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 1) {\n context.isValid = false;\n context.error = 'LEAST() requires 1 or more arguments';\n return;\n }\n for (let i = 0; i < args.length; i++) {\n const type = getArgType(args[i], context);\n if (type !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to LEAST must be of type number`;\n return;\n }\n }\n context.returnType = 'number';\n}\n\nexport function midTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 3) {\n context.isValid = false;\n context.error = 'MID() requires exactly 3 arguments';\n return;\n }\n const [strArg, startArg, lengthArg] = args;\n if (getArgType(strArg, context) !== 'string') {\n context.isValid = false;\n context.error = 'First argument to MID must be of type string';\n return;\n }\n if (getArgType(startArg, context) !== 'number') {\n context.isValid = false;\n context.error = 'Second argument to MID must be of type number';\n return;\n }\n if (getArgType(lengthArg, context) !== 'number') {\n context.isValid = false;\n context.error = 'Third argument to MID must be of type number';\n return;\n }\n context.returnType = 'string';\n}\n\nexport function medianTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 1) {\n context.isValid = false;\n context.error = 'MEDIAN() requires 1 or more arguments';\n return;\n }\n for (let i = 0; i < args.length; i++) {\n const type = getArgType(args[i], context);\n if (type !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to MEDIAN must be of type number`;\n return;\n }\n }\n context.returnType = 'number';\n}\n\nexport function modeTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 1) {\n context.isValid = false;\n context.error = 'MODE() requires 1 or more arguments';\n return;\n }\n for (let i = 0; i < args.length; i++) {\n const type = getArgType(args[i], context);\n if (type !== 'number') {\n context.isValid = false;\n context.error = `Argument ${i + 1} to MODE must be of type number`;\n return;\n }\n }\n context.returnType = 'number';\n}\n\nexport function valueTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'VALUE() requires exactly 1 argument';\n return;\n }\n\n const type = getArgType(arg, context);\n if (!['string', 'number'].includes(type || '')) {\n context.isValid = false;\n context.error = 'VALUE() accepts only string or number as input';\n return;\n }\n\n context.returnType = 'number';\n}\n\nexport function pctTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'PCT() requires exactly 1 argument';\n return;\n }\n\n const type = getArgType(arg, context);\n if (type !== 'number') {\n context.isValid = false;\n context.error = 'PCT() argument must be of type number';\n return;\n }\n\n context.returnType = 'number';\n}\n\nexport function xorTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 2) {\n context.isValid = false;\n context.error = 'XOR() requires exactly 2 arguments';\n return;\n }\n\n const [arg1Type, arg2Type] = args.map((arg) => getArgType(arg, context));\n if (arg1Type !== 'boolean' || arg2Type !== 'boolean') {\n context.isValid = false;\n context.error = 'XOR() arguments must both be of type boolean';\n return;\n }\n\n context.returnType = 'boolean';\n}\n\nexport function textTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 2 || args.length > 3) {\n context.isValid = false;\n context.error = 'TEXT() requires 2 or 3 arguments';\n return;\n }\n\n const [valueType, formatType, localeType] = args.map((arg) => getArgType(arg, context));\n if (!['number', 'date'].includes(valueType || '')) {\n context.isValid = false;\n context.error = 'First argument to TEXT() must be of type number or date';\n return;\n }\n if (formatType !== 'string') {\n context.isValid = false;\n context.error = 'Second argument to TEXT() must be a string format pattern';\n return;\n }\n if (args[2] && localeType !== 'string') {\n context.isValid = false;\n context.error = 'Third argument to TEXT() (locale) must be a string';\n return;\n }\n\n context.returnType = 'string';\n}\n\nexport function uuidTransformValidator(context: ParseContext) {\n context.returnType = 'string';\n}\n\nexport function ifNullTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length !== 2) {\n context.isValid = false;\n context.error = 'IFNA() requires exactly 2 arguments';\n return;\n }\n\n const [valueType, fallbackType] = args.map((arg) => getArgType(arg, context));\n if (valueType !== fallbackType && valueType !== null && fallbackType !== null) {\n context.isValid = false;\n context.error = 'Both arguments to IFNA() must be of the same type';\n return;\n }\n\n context.returnType = valueType || fallbackType || 'string';\n}\n\nexport function fromExcelDateTransformValidator(context: ParseContext, arg: ExpressionValue) {\n if (!arg) {\n context.isValid = false;\n context.error = 'FROMEXCELDATE() requires exactly 1 argument';\n return;\n }\n const argType = getArgType(arg, context);\n if (argType !== 'number') {\n context.isValid = false;\n context.error = 'FROMEXCELDATE() argument must be a number';\n return;\n }\n context.returnType = 'date';\n}\n\nexport function hasTransformValidator(\n context: ParseContext,\n args: ExpressionValue[],\n searchValue: ExpressionValue,\n) {\n if (args.length === 0) {\n context.isValid = false;\n context.error = 'HAS() requires at least one column to check against';\n return;\n }\n\n const searchType = getArgType(searchValue, context);\n for (let i = 0; i < args.length; i++) {\n const argType = getArgType(args[i], context);\n if (argType !== searchType) {\n context.isValid = false;\n context.error = `Argument ${i + 1} to HAS must be of the same type as searchValue (${searchType})`;\n return;\n }\n }\n context.returnType = 'number';\n}\n\nexport function hasSomeTransformValidator(\n context: ParseContext,\n args: ExpressionValue[],\n valueArray: ExpressionValue[],\n) {\n if (args.length === 0) {\n context.isValid = false;\n context.error = 'HAS_SOME() requires at least one column to check against';\n return;\n }\n if (valueArray.length === 0) {\n context.isValid = false;\n context.error = 'HAS_SOME() requires at least one search value';\n return;\n }\n const flattenedValues: ExpressionValue[] = [];\n valueArray.forEach((valGroup) => {\n if (Array.isArray(valGroup)) {\n valGroup.forEach((val) => flattenedValues.push(val));\n } else {\n flattenedValues.push(valGroup);\n }\n });\n for (let i = 0; i < args.length; i++) {\n const colType = getArgType(args[i], context);\n for (let j = 0; j < flattenedValues.length; j++) {\n const valType = getArgType(flattenedValues[j], context);\n if (colType !== valType) {\n context.isValid = false;\n context.error = `Argument ${i + 1} and value ${j + 1} to HAS_SOME must be of the same type (${colType} vs ${valType})`;\n return;\n }\n }\n }\n\n context.returnType = 'number';\n}\n\nexport function filterIfTransformValidator(\n context: ParseContext,\n columnArg: ExpressionValue,\n conditionArg: ExpressionValue,\n) {\n const colType = getArgType(columnArg, context);\n if (colType !== 'string' && colType !== 'number') {\n context.isValid = false;\n context.error = 'First argument to FILTER_IF must be a column reference or a valid column';\n return;\n }\n if (getArgType(conditionArg, context) !== 'string') {\n context.isValid = false;\n context.error = 'Second argument to FILTER_IF must be of type string';\n return;\n }\n context.returnType = colType;\n}\n\nexport function dateTransformValidator(\n context: ParseContext,\n date: ExpressionValue,\n format: ExpressionValue,\n year?: ExpressionValue,\n) {\n const dateType = getArgType(date, context);\n if (dateType !== 'date' && dateType !== 'string') {\n context.isValid = false;\n context.error = 'First argument to DATE must be of type date or string';\n return;\n }\n\n const formatType = getArgType(format, context);\n if (formatType !== 'string') {\n context.isValid = false;\n context.error = 'Second argument (format) to DATE must be of type string';\n return;\n }\n\n if (year !== undefined) {\n const yearType = getArgType(year, context);\n if (yearType !== 'number') {\n context.isValid = false;\n context.error = 'Third argument (year) to DATE must be of type number';\n return;\n }\n }\n\n context.returnType = 'date';\n}\n\nexport function switchTransformValidator(context: ParseContext, args: ExpressionValue[]) {\n if (args.length < 3) {\n context.isValid = false;\n context.error = 'SWITCH() requires at least 3 arguments';\n return;\n }\n\n const switchExprType = getArgType(args[0], context);\n if (switchExprType === null) {\n context.isValid = false;\n context.error = 'Switch expression has invalid type';\n return;\n }\n\n const remainingArgs = args.slice(1);\n\n if (remainingArgs.length % 2 !== 0 && remainingArgs.length < 3) {\n context.isValid = false;\n context.error = 'SWITCH() requires at least one condition-result pair';\n return;\n }\n\n for (let i = 0; i < remainingArgs.length - (remainingArgs.length % 2); i += 2) {\n const condType = getArgType(remainingArgs[i], context);\n if (condType === null || condType !== switchExprType) {\n context.isValid = false;\n context.error = `Condition argument ${i + 2} must be of the same type as switch expression (${switchExprType})`;\n return;\n }\n }\n\n const resultTypes: string[] = [];\n\n for (let i = 1; i < remainingArgs.length - (remainingArgs.length % 2); i += 2) {\n const resultType = getArgType(remainingArgs[i], context);\n if (resultType === null) {\n context.isValid = false;\n context.error = `Result argument ${i + 2} has invalid type`;\n return;\n }\n resultTypes.push(resultType);\n }\n\n if (remainingArgs.length % 2 === 1) {\n const elseType = getArgType(remainingArgs[remainingArgs.length - 1], context);\n if (elseType === null) {\n context.isValid = false;\n context.error = 'Else argument has invalid type';\n return;\n }\n resultTypes.push(elseType);\n }\n\n const uniqueResultTypes = new Set(resultTypes);\n if (uniqueResultTypes.size > 1) {\n context.isValid = false;\n context.error = 'All result arguments to SWITCH() must be of the same type';\n return;\n }\n\n context.returnType = resultTypes[0];\n}\n\nexport function hasAllTransformValidator(\n context: ParseContext,\n args: ExpressionValue[],\n valueArray: ExpressionValue[][],\n) {\n if (args.length === 0) {\n context.isValid = false;\n context.error = 'HAS_ALL() requires at least one column to check against';\n return;\n }\n\n if (valueArray.length === 0) {\n context.isValid = false;\n context.error = 'HAS_ALL() requires at least one search value array';\n return;\n }\n\n for (const col of args) {\n const colType = getArgType(col, context);\n if (colType === null) {\n context.isValid = false;\n context.error = 'One or more columns have invalid type';\n return;\n }\n }\n\n for (const valGroup of valueArray) {\n if (!Array.isArray(valGroup) || valGroup.length === 0) {\n context.isValid = false;\n context.error = 'Each search value group must be a non-empty array';\n return;\n }\n\n for (const val of valGroup) {\n const valType = getArgType(val, context);\n if (valType === null) {\n context.isValid = false;\n context.error = 'One or more search values have invalid type';\n return;\n }\n }\n }\n\n context.returnType = 'number';\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars */\n\nimport * as acorn from 'acorn';\nimport { MDM_COLUMN_TYPE, ParseContext } from '../../ParseContext';\nimport { VisitorInterface } from './VisitorInterface';\nimport { toBinaryExpression } from '../../../sql-lib/binary_expr';\nimport {\n Binary,\n Case,\n ColumnRefItem,\n ExpressionValue,\n From,\n Select,\n Value,\n ValueExpr,\n} from '../../../sql-types';\nimport { PctObject } from '../../objects/PctObject';\nimport { toFunction } from '../../../sql-lib/function';\nimport { toWhen, WhenType } from '../../../sql-lib/when';\nimport { ElseType, toElse } from '../../../sql-lib/else';\nimport { toCase } from '../../../sql-lib/case';\nimport { toUnaryExpression } from '../../../sql-lib/unary_expr';\nimport { generateSqlQuery } from '../../../sql_query_gen';\nimport { SelectBuilder, WithBuilder } from '../../../sql-lib/select';\nimport { toColumn, toColumnRef } from '../../../sql-lib/column';\nimport { createJsToSqlParser } from '../../JsToSqlParser';\nimport { RUNTIME_TABLE_NAME } from '../../../runtime_var';\nimport { toJoin } from '../../../sql-lib/join';\nimport { formatDBEntityName } from '../../../utils';\nimport {\n absTransformValidator,\n andTransformValidator,\n averageTransformValidator,\n averageXNegTransformValidator,\n averageXZeroNegTransformValidator,\n averageXZeroTransformValidator,\n ceilTransformValidator,\n concatenateTransformValidator,\n dateAddTransformValidator,\n dateDiffTransformValidator,\n dateTransformValidator,\n dayTransformValidator,\n divideTransformValidator,\n eomonthTransformValidator,\n evenTransformValidator,\n expTransformValidator,\n filterIfTransformValidator,\n floorTransformValidator,\n fromExcelDateTransformValidator,\n hasAllTransformValidator,\n hasSomeTransformValidator,\n hasTransformValidator,\n ifTransformValidator,\n indexOfTransformValidator,\n inTransformValidator,\n isEmptyTransformValidator,\n isNumberTransformValidator,\n leftTransformValidator,\n lenTransformValidator,\n logTransformValidator,\n lowerTransformValidator,\n matchTransformValidator,\n maxAggregateTransformValidator,\n medianTransformValidator,\n midTransformValidator,\n minAggregateTransformValidator,\n modeTransformValidator,\n modTransformValidator,\n monthTransformValidator,\n notTransformValidator,\n nowTransformValidator,\n numberValueTransformValidator,\n oddTransformValidator,\n orTransformValidator,\n pctTransformValidator,\n powTransformValidator,\n randBetweenTransformValidator,\n randTransformValidator,\n replaceTransformValidator,\n reptTransformValidator,\n rightTransformValidator,\n roundTransformValidator,\n sqrtTransformValidator,\n sumTransformValidator,\n switchTransformValidator,\n textTransformValidator,\n todayTransformValidator,\n trimTransformValidator,\n upperTransformValidator,\n uuidTransformValidator,\n valueTransformValidator,\n xorTransformValidator,\n yearTransformValidator,\n} from '../validator/FormulaValidator';\n\nexport const DEFAULT_FUNCTION_TRANSFORMS: Record<string, (...args: any[]) => void> = {\n // Common functions\n DATE: dateTransform,\n\n // Logical functions\n AND: andTransform,\n IF: ifTransform,\n OR: orTransform,\n NOT: notTransform,\n XOR: xorTransform,\n IFNA: ifNullTransform,\n HAS: hasTransform,\n HAS_SOME: hasSomeTransform,\n FILTERIF: filterIfTransform,\n IN: inTransform,\n HAS_ALL: hasAllTransform,\n SWITCH: switchTransform,\n\n // Date functions\n DATEADD: dateAddTransform,\n DATEDIFF: dateDiffTransform,\n DAY: dayTransform,\n EOMONTH: eomonthTransform,\n MONTH: monthTransform,\n NOW: nowTransform,\n TODAY: todayTransform,\n YEAR: yearTransform,\n FROMEXCELDATE: fromExcelDateTransform,\n\n // String functions\n CONCAT: concatenateTransform,\n CONCATENATE: concatenateTransform,\n ISBLANK: isEmptyTransform,\n ISEMPTY: isEmptyTransform,\n LEFT: leftTransform,\n LEN: lenTransform,\n LOWER: lowerTransform,\n MATCH: matchTransform,\n MID: midTransform,\n NUMBERVALUE: numberValueTransform,\n REPLACE: replaceTransform,\n REPT: reptTransform,\n RIGHT: rightTransform,\n TRIM: trimTransform,\n TEXT: textTransform,\n UPPER: upperTransform,\n VALUE: valueTransform,\n UUID: uuidTransform,\n FIND: findTransform,\n\n // Math functions\n ABS: absTransform,\n AVERAGE: averageTransform,\n AVERAGEIF: averageIfTransform,\n AVERAGEEXNEG: averageXNegTransform,\n AVERAGEEXZERO: averageXZeroTransform,\n AVERAGEEXZERONEG: averageXZeroNegTransform,\n CEIL: ceilTransform,\n CEILING: ceilTransform,\n DIVIDE: divideTransform,\n INDEXOF: indexOfTransform,\n ISNUMBER: isNumberTransform,\n EXP: expTransform,\n FLOOR: floorTransform,\n LOG: logTransform,\n MAX: maxAggregateTransform,\n MEDIAN: medianTransform,\n MIN: minAggregateTransform,\n MOD: modTransform,\n ODD: oddTransform,\n EVEN: evenTransform,\n POW: powTransform,\n PCT: pctTransform,\n RAND: randTransform,\n RANDBETWEEN: randBetweenTransform,\n ROUND: roundTransform,\n SUM: sumTransform,\n SQRT: sqrtTransform,\n MODE: modeTransform,\n};\n\n/**\n * This class can be customized by extending this class and provide custom function transforms as part of `init()` implementation\n */\nexport class CallExpressionVisitor implements VisitorInterface<acorn.CallExpression> {\n protected functionTransformMap: Map<string, (...args: any[]) => void> | undefined;\n\n constructor() {\n this.init();\n }\n\n protected init(): void {\n this.functionTransformMap = new Map<string, (...args: any[]) => void>(\n Object.entries(DEFAULT_FUNCTION_TRANSFORMS),\n );\n }\n\n /**\n * visitor needs to be implemented as arrow function to avoid `this` binding issue since it will be\n * passed to `acorn-walk` library\n */\n public visitor = (node: acorn.CallExpression, context: ParseContext) => {\n if (node.callee.type === 'MemberExpression') {\n return this.processMemberExpression(node, context);\n }\n const fn = node.callee as acorn.Identifier;\n const args = node.arguments.map((arg) => context.get(arg));\n const transform = this.functionTransformMap!.get(fn.name.toUpperCase());\n if (!transform) {\n throw new Error(`Unsupported function: ${fn.name}`);\n }\n context.set(node, transform(node, context, ...args));\n };\n\n /**\n * method to process call expression with member expression\n */\n protected processMemberExpression(node: acorn.CallExpression, context: ParseContext) {\n const memberExpression = node.callee as acorn.MemberExpression;\n const objectInstance = context.get(memberExpression);\n const fnName = (memberExpression.property as acorn.Identifier).name.toUpperCase();\n const fn = objectInstance.fnMap.get(fnName);\n if (!fn) {\n throw new Error(`Unsupported function: ${fnName}`);\n }\n const args = node.arguments.map((arg) => context.get(arg));\n context.set(node, fn(context, ...args));\n }\n}\n\n/**\n * Transforms `if` call expression to `case-when-then-else` SQL expression\n */\nexport function ifTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n cond: Binary,\n trueValue: ExpressionValue,\n falseValue: ExpressionValue,\n): ExpressionValue {\n ifTransformValidator(context, [cond, trueValue, falseValue]);\n let whenList = [toWhen(cond, trueValue)];\n let elseValue: ElseType | undefined = undefined;\n if (falseValue.type == 'case') {\n const args = (falseValue as Case).args;\n elseValue = args.pop() as ElseType;\n whenList = whenList.concat(args as WhenType[]);\n } else {\n elseValue = toElse(falseValue);\n }\n\n return toCase({\n whenList,\n elseResult: elseValue,\n });\n}\n\n/**\n * Transforms `today` call expression to `current_date` SQL expression\n */\nfunction todayTransform(_node: acorn.CallExpression, context: ParseContext): ExpressionValue {\n todayTransformValidator(context);\n const sqlFnName = 'CURRENT_DATE';\n return { type: 'sql_expr', value: sqlFnName };\n}\n\n/**\n * Transforms `now` call expression to `current_timestamp` SQL expression\n */\nfunction nowTransform(_node: acorn.CallExpression, context: ParseContext): ExpressionValue {\n nowTransformValidator(context);\n const sqlFnName = 'CURRENT_TIMESTAMP';\n return { type: 'sql_expr', value: sqlFnName };\n}\n\n/**\n * Transforms `concat` call expression to `concat` SQL expression\n */\nfunction concatenateTransform(\n _node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n concatenateTransformValidator(context, args);\n\n const sqlFnName = 'CONCAT';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, args);\n}\n\n/**\n * Transforms `lower` call expression to `lower` SQL expression\n */\nfunction lowerTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n lowerTransformValidator(context, arg);\n const sqlFnName = 'LOWER';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n context.returnType = 'string';\n return toFunction(name, [arg]);\n}\n\n/**\n * Transforms `trim` call expression to `trim` SQL expression\n */\nfunction trimTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n trimTransformValidator(context, arg);\n const sqlFnName = 'TRIM';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [arg]);\n}\n\n/**\n * Transforms `upper` call expression to `upper` SQL expression\n */\nfunction upperTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n upperTransformValidator(context, arg);\n const sqlFnName = 'UPPER';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [arg]);\n}\n\n/**\n * Transforms `len` call expression to `len` SQL expression\n */\nfunction lenTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n lenTransformValidator(context, arg);\n context.returnType = 'number';\n const sqlFnName = 'LEN';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [arg]);\n}\n\n/**\n * Transforms `left` call expression to `left` SQL expression\n */\nfunction leftTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n leftTransformValidator(context, args);\n const text = args[0];\n const len = args[1] ?? { type: 'number', value: 0 };\n const name = { type: 'default', value: 'LEFT' } as ValueExpr<string>;\n return toFunction(name, [text, len]);\n}\n\n/**\n * Transforms `right` call expression to `right` SQL expression\n */\nfunction rightTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n rightTransformValidator(context, args);\n const sqlFnName = 'RIGHT';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n const text = args[0];\n const len = args[1] ?? { type: 'number', value: 0 };\n return toFunction(name, [text, len]);\n}\n\n/**\n * Transforms `replace` call expression to `stuff` SQL expression\n */\nfunction replaceTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n replaceTransformValidator(context, args);\n const sqlFnName = 'STUFF';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, args);\n}\n\n/**\n * Transforms `rept` call expression to `rept` SQL expression\n */\nfunction reptTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n reptTransformValidator(context, args);\n const sqlFnName = 'REPLICATE';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, args);\n}\n\n/**\n * Transforms `match` call expression to `case-when-then-else using like in condition` SQL expression\n */\nfunction matchTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n matchTransformValidator(context, args);\n const [value, pattern] = args;\n return ifTransform(\n node,\n context,\n { type: 'binary_expr', operator: 'LIKE', left: value, right: pattern } as Binary,\n { type: 'string', value: 'true' } as ExpressionValue,\n { type: 'string', value: 'false' } as ExpressionValue,\n );\n}\n\n/**\n * Transforms `dateadd` call expression to `DATEADD` SQL expression\n */\nfunction dateAddTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n date: ExpressionValue,\n numDays: ExpressionValue,\n): ExpressionValue {\n dateAddTransformValidator(context, [date, numDays]);\n const startDate = generateSqlQuery(date);\n const daysToAdd = generateSqlQuery(numDays);\n return { type: 'sql_expr', value: `DATEADD(DAY, ${daysToAdd}, ${startDate})` };\n}\n\n/**\n * Transforms `datediff` call expression to `DATEDIFF` SQL expression\n */\nfunction dateDiffTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n date1: ExpressionValue,\n date2: ExpressionValue,\n): ExpressionValue {\n dateDiffTransformValidator(context, [date1, date2]);\n const startDate = generateSqlQuery(date1);\n const endDate = generateSqlQuery(date2);\n return { type: 'sql_expr', value: `DATEDIFF(DAY, ${startDate}, ${endDate})` };\n}\n\n/**\n * Transforms `day` call expression to `day` SQL expression\n */\nfunction dayTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n date: ExpressionValue,\n): ExpressionValue {\n dayTransformValidator(context, date);\n const sqlFnName = 'DAY';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [date]);\n}\n\n/**\n * Transforms `month` call expression to `month` SQL expression\n */\nfunction monthTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n date: ExpressionValue,\n): ExpressionValue {\n monthTransformValidator(context, date);\n const sqlFnName = 'MONTH';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [date]);\n}\n\n/**\n * Transforms `year` call expression to `year` SQL expression\n */\nfunction yearTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n date: ExpressionValue,\n): ExpressionValue {\n yearTransformValidator(context, date);\n const sqlFnName = 'YEAR';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [date]);\n}\n\n/**\n * Transforms `eomonth` call expression to `eomonth` SQL expression\n */\nfunction eomonthTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n eomonthTransformValidator(context, args);\n const sqlFnName = 'EOMONTH';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n if (args.length < 1 || args.length > 2) {\n throw new Error('EOMONTH() requires 1 or 2 arguments');\n }\n return toFunction(name, args);\n}\n\n/**\n * Transforms `divide` call expression to `divide` SQL expression\n */\nfunction divideTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n dividend: ExpressionValue,\n divisor: ExpressionValue,\n): ExpressionValue {\n divideTransformValidator(context, [dividend, divisor]);\n const cast = (expr: ExpressionValue) =>\n toFunction({ type: 'default', value: 'CAST' }, [\n toBinaryExpression('AS', expr, { type: 'default', value: 'FLOAT' }),\n ]);\n\n const zeroCheck = toBinaryExpression('=', cast(divisor), { type: 'number', value: 0 });\n const whenArg = toWhen(zeroCheck, { type: 'null', value: null });\n const elseArg = toElse(toBinaryExpression('/', cast(dividend), cast(divisor)));\n\n return toCase({ whenList: [whenArg], elseResult: elseArg });\n}\n\n/**\n * Transforms `and` call expression to `and` SQL expression\n */\nfunction andTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...conds: ExpressionValue[]\n): ExpressionValue {\n andTransformValidator(context, conds);\n const sqlOperator = 'AND';\n const [first, ...rest] = conds;\n const condition = rest.reduce((acc, cond) => {\n return toBinaryExpression(sqlOperator, acc, cond);\n }, first);\n\n if (!context.ifCondition) {\n return ifTransform(\n node,\n context,\n condition as Binary,\n { type: 'string', value: 'true' },\n { type: 'string', value: 'false' },\n );\n }\n\n return condition;\n}\n/**\n * Transforms `or` call expression to `or` SQL expression\n */\nfunction orTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...conds: ExpressionValue[]\n): ExpressionValue {\n orTransformValidator(context, conds);\n const sqlOperator = 'OR';\n const [first, ...rest] = conds;\n const condition = rest.reduce((acc, cond) => {\n return toBinaryExpression(sqlOperator, acc, cond);\n }, first);\n\n if (!context.ifCondition) {\n return ifTransform(\n node,\n context,\n condition as Binary,\n { type: 'string', value: 'true' },\n { type: 'string', value: 'false' },\n );\n }\n\n return condition;\n}\n\n/**\n * Transforms `ceil` call expression to `ceil` SQL expression\n */\nfunction ceilTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n ceilTransformValidator(context, arg);\n const sqlFnName = 'CEILING';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [arg]);\n}\n\n/**\n * Transforms `floor` call expression to `floor` SQL expression\n */\nfunction floorTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n floorTransformValidator(context, arg);\n const sqlFnName = 'FLOOR';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [arg]);\n}\n\n/**\n * Transforms `abs` call expression to `abs` SQL expression\n */\nfunction absTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n absTransformValidator(context, arg);\n const sqlFnName = 'ABS';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [arg]);\n}\n\n/**\n * Transforms `round` call expression to `round` SQL expression\n */\nfunction roundTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n roundTransformValidator(context, args);\n\n const sqlFnName = 'ROUND';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n const [value, decimals] = args;\n return toFunction(name, [value, decimals ?? { type: 'number', value: 0 }]);\n}\n\n/**\n * Transforms `exp` call expression to `exp` SQL expression\n */\nfunction expTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n expTransformValidator(context, arg);\n const sqlFnName = 'EXP';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [arg]);\n}\n\n/**\n * Transforms `pow` call expression to `pow` SQL expression\n */\nfunction powTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n powTransformValidator(context, args);\n const sqlFnName = 'POWER';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n if (args.length < 2) {\n throw new Error('POW() requires 2 arguments');\n }\n return toFunction(name, args);\n}\n\n/**\n * Transforms `log` call expression to `log` SQL expression\n */\nfunction logTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n logTransformValidator(context, args);\n const sqlFnName = 'LOG';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n if (args.length < 1 || args.length > 2) {\n throw new Error('LOG() requires 1 or 2 arguments');\n }\n return toFunction(name, args);\n}\n\n/**\n * Transforms `sqrt` call expression to `sqrt` SQL expression\n */\nfunction sqrtTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n sqrtTransformValidator(context, arg);\n const sqlFnName = 'SQRT';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [arg]);\n}\n\n/**\n * Transforms `mod` call expression to `mod` SQL expression\n */\nfunction modTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n modeTransformValidator(context, args);\n const [dividend, divisor] = args;\n return toBinaryExpression('%', dividend, divisor);\n}\n\n/**\n * Transforms `not` call expression to `not` SQL expression\n */\nfunction notTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: Binary,\n): ExpressionValue {\n notTransformValidator(context, arg);\n if (!context.ifCondition) {\n const whenArg = toWhen(\n arg,\n toFunction({ type: 'default', value: 'CAST' }, [\n toBinaryExpression('AS', { type: 'number', value: 0 }, { type: 'default', value: 'BIT' }),\n ]),\n );\n const elseArg = toElse(\n toFunction({ type: 'default', value: 'CAST' }, [\n toBinaryExpression('AS', { type: 'number', value: 1 }, { type: 'default', value: 'BIT' }),\n ]),\n );\n return toCase({ whenList: [whenArg], elseResult: elseArg });\n }\n return arg;\n}\n\n/**\n * Transforms `rand` call expression to `rand` SQL expression\n */\nfunction randTransform(node: acorn.CallExpression, context: ParseContext): ExpressionValue {\n randTransformValidator(context);\n const sqlFnName = 'RAND';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, []);\n}\n\n/**\n * Transforms `randbetween` call expression to `rand_between` SQL expression\n */\nfunction randBetweenTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n randBetweenTransformValidator(context, args);\n const [minValue, maxValue] = args.map(generateSqlQuery);\n return { type: 'sql_expr', value: `(RAND() * (${maxValue} - ${minValue}) + ${minValue})` };\n}\n\n/**\n * Transforms `average` call expression to SQL expression. This performs average of the arguments\n * which is different than SQL's AVG() function.\n */\nfunction averageTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n averageTransformValidator(context, args);\n const argsCount = args.length;\n const argList = args.map((arg) => `COALESCE(${generateSqlQuery(arg)}, 0)`);\n return { type: 'sql_expr', value: `CAST(((${argList.join(' + ')})/${argsCount}) AS FLOAT)` };\n}\n\nfunction averageConditionalTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n valueList: ExpressionValue[],\n conditionBuilder: (valueColumnName: string) => Binary,\n): Select {\n const currentColumnId = context.currentColumnId;\n const valueColumnName = `val_${currentColumnId}`;\n const unionCte = new WithBuilder(context)\n .addName(`cte_union_${currentColumnId}`)\n .addStmt(\n valueList.reverse().reduce(\n (acc, arg) => {\n const builder = new SelectBuilder()\n .addColumns([\n ...context.primaryKeyColumns.map((id) => toColumn(toColumnRef(id))),\n toColumn(arg, valueColumnName),\n ])\n .addFrom([{ type: 'from', table: RUNTIME_TABLE_NAME } as From]);\n\n if (acc) {\n builder.addSetOp('UNION ALL').addNext(acc);\n }\n return builder.build();\n },\n undefined as Select | undefined,\n )!,\n )\n .build();\n\n const filterCte = new WithBuilder(context)\n .addName(`cte_filter_${currentColumnId}`)\n .addStmt(\n new SelectBuilder()\n .addColumns([\n ...context.primaryKeyColumns.map((id) => toColumn(toColumnRef(id))),\n toColumn(toColumnRef(valueColumnName)),\n ])\n .addFrom([{ type: 'from', table: unionCte.name.value } as From])\n .addWhere(conditionBuilder(valueColumnName))\n .build(),\n )\n .build();\n\n const avgCte = new WithBuilder(context)\n .addName(`cte_avg_${currentColumnId}`)\n .addStmt(\n new SelectBuilder()\n .addColumns([\n ...context.primaryKeyColumns.map((id) => toColumn(toColumnRef(id))),\n toColumn(\n toFunction({ type: 'default', value: 'AVG' }, [toColumnRef(valueColumnName)]),\n currentColumnId,\n ),\n ])\n .addFrom([{ type: 'from', table: filterCte.name.value } as From])\n .addGroupby({\n columns: context.primaryKeyColumns.map((id) => toColumnRef(id)),\n modifiers: [],\n })\n .build(),\n )\n .build();\n\n const finalCte = new WithBuilder(context)\n .addName(`cte_${currentColumnId}`)\n .addStmt(\n new SelectBuilder()\n .addColumns([\n toColumn(toColumnRef('*', RUNTIME_TABLE_NAME)),\n toColumn(toColumnRef(currentColumnId)),\n ])\n .addFrom([\n { type: 'from', table: RUNTIME_TABLE_NAME } as From,\n toJoin(\n 'INNER JOIN',\n avgCte.name.value,\n context.primaryKeyColumns\n .map((id) =>\n toBinaryExpression(\n '=',\n toColumnRef(id, RUNTIME_TABLE_NAME),\n toColumnRef(id, avgCte.name.value),\n ),\n )\n .reduce((acc, expr) => toBinaryExpression('AND', acc, expr)),\n ),\n ])\n .build(),\n )\n .build();\n\n // since this transformation depends on primary key columns, manually add primary columns to the dependencies\n context.primaryKeyColumns.forEach((id) => context.addColumnDep(id));\n const select = new SelectBuilder().addWith([unionCte, filterCte, avgCte, finalCte]).build();\n return select;\n}\n\n/**\n * Transforms `averageif` call expression to SQL expression. This performs average of the arguments\n * which is different than SQL's AVG() function.\n */\nfunction averageIfTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n valueList: ExpressionValue[],\n condition: ExpressionValue,\n): Select {\n const conditionBuilder = (valueColumnName: string) => {\n if (condition.type === 'string') {\n const conditionWithLhs = `${valueColumnName} ${condition.value}`;\n const localContext = new ParseContext({\n columnConfigMap: {\n ...context.columnConfigMap,\n [valueColumnName]: {\n columnName: valueColumnName,\n columnType: MDM_COLUMN_TYPE.NUMBER,\n columnMeta: { tableName: context.tableName },\n },\n },\n currentColumnId: context.currentColumnId,\n primaryKeyColumns: context.primaryKeyColumns,\n tableName: context.tableName,\n });\n const parser = createJsToSqlParser(localContext);\n return parser.parse(conditionWithLhs);\n }\n throw new Error('Invalid condition type');\n };\n return averageConditionalTransform(node, context, valueList, conditionBuilder);\n}\n\n/**\n * Transforms `averagexneg` call expression to SQL expression. This performs average of the arguments\n * which is different than SQL's AVG() function.\n */\nfunction averageXNegTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n valueList: ExpressionValue[],\n): Select {\n averageXNegTransformValidator(context, valueList);\n const conditionBuilder = (valueColumnName: string) => {\n return toBinaryExpression('>=', toColumnRef(valueColumnName), { type: 'number', value: 0 });\n };\n return averageConditionalTransform(node, context, valueList, conditionBuilder);\n}\n\n/**\n * Transforms `averagexzero` call expression to SQL expression. This performs average of the arguments\n * which is different than SQL's AVG() function.\n */\nfunction averageXZeroTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n valueList: ExpressionValue[],\n): Select {\n averageXZeroTransformValidator(context, valueList);\n const conditionBuilder = (valueColumnName: string) => {\n return toBinaryExpression('!=', toColumnRef(valueColumnName), { type: 'number', value: 0 });\n };\n return averageConditionalTransform(node, context, valueList, conditionBuilder);\n}\n\n/**\n * Transforms `averagexzeroneg` call expression to SQL expression. This performs average of the arguments\n * which is different than SQL's AVG() function.\n */\nfunction averageXZeroNegTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n valueList: ExpressionValue[],\n): Select {\n averageXZeroNegTransformValidator(context, valueList);\n const conditionBuilder = (valueColumnName: string) => {\n return toBinaryExpression('>', toColumnRef(valueColumnName), { type: 'number', value: 0 });\n };\n return averageConditionalTransform(node, context, valueList, conditionBuilder);\n}\n\n/**\n * Transforms `numbervalue` call expression to SQL expression.\n */\nfunction numberValueTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n numberValueTransformValidator(context, args);\n const [valueToCast, decimalSeparator, thousandSeparator] = args;\n let expr = generateSqlQuery(valueToCast);\n if (thousandSeparator) {\n expr = `REPLACE(${expr}, '${generateSqlQuery(thousandSeparator)}', '')`;\n }\n if (decimalSeparator) {\n expr = `REPLACE(${expr}, '${generateSqlQuery(decimalSeparator)}', '.')`;\n }\n return { type: 'sql_expr', value: `CAST(${expr} AS FLOAT)` };\n}\n\n/**\n * Transforms `odd` call expression to SQL expression.\n *\n * Sql Expression:\n * CASE WHEN arg % 2 = 1 THEN arg\n * ELSE arg + 1\n * END\n */\nfunction oddTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n oddTransformValidator(context, arg);\n const moduloCondition = toBinaryExpression('%', arg, { type: 'number', value: 2 });\n const isOdd = toBinaryExpression('=', moduloCondition, { type: 'number', value: 1 });\n const whenArg = toWhen(isOdd, arg);\n const elseArg = toElse(toBinaryExpression('+', arg, { type: 'number', value: 1 }));\n return toCase({ whenList: [whenArg], elseResult: elseArg });\n}\n\n/**\n * Transforms `even` call expression to SQL expression.\n *\n * Sql Expression:\n * CASE WHEN arg % 2 = 0 THEN arg\n * ELSE arg + 1\n * END\n */\nfunction evenTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n if (args.length !== 1) {\n throw new Error('EVEN() requires 1 argument');\n }\n\n const arg = args[0];\n const sqlFnName = 'FLOOR';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n const floored = toFunction(name, [arg]);\n\n const intCast = toFunction({ type: 'default', value: 'CAST' }, [\n toBinaryExpression('AS', floored, { type: 'default', value: 'INT' }),\n ]);\n\n const moduloCondition = toBinaryExpression('%', intCast, { type: 'number', value: 2 });\n const isEven = toBinaryExpression('=', moduloCondition, { type: 'number', value: 0 });\n\n const whenArg = toWhen(isEven, intCast);\n const elseArg = toElse(toBinaryExpression('+', intCast, { type: 'number', value: 1 }));\n\n return toCase({ whenList: [whenArg], elseResult: elseArg });\n}\n\n/**\n * Transforms `IN(column, [value1, value2, ...])` call expression to SQL CASE expression.\n *\n * SQL:\n * CASE\n * WHEN column IN ('val1', 'val2', ...) THEN TRUE\n * ELSE FALSE\n * END\n */\nfunction inTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n inTransformValidator(context, args);\n const [column, values] = args;\n const inExpr: ExpressionValue = {\n type: 'binary_expr',\n operator: 'IN',\n left: column,\n right: {\n type: 'expr_list',\n value: values,\n },\n };\n\n const whenClause = toWhen(inExpr, { type: 'number', value: 1 });\n const elseClause = toElse({ type: 'number', value: 0 });\n\n return toCase({\n whenList: [whenClause],\n elseResult: elseClause,\n });\n}\n\n/**\n * Transforms `sum` call expression to SQL expression.\n */\nfunction sumTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n sumTransformValidator(context, args);\n const argList = args.map((arg) => `COALESCE(${generateSqlQuery(arg)}, 0)`);\n return { type: 'sql_expr', value: `(${argList.join(' + ')})` };\n}\n\n/**\n * Transforms `indexof` call expression to SQL expression.\n */\nfunction indexOfTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n valueList: ExpressionValue[],\n valueToFind: ExpressionValue,\n): ExpressionValue {\n indexOfTransformValidator(context, valueList, valueToFind);\n const whenList = valueList.map((value, index) =>\n toWhen(toBinaryExpression('=', value, valueToFind), { type: 'number', value: index }),\n );\n return toCase({ whenList, elseResult: toElse({ type: 'number', value: -1 }) });\n}\n\n/**\n * Transforms `isblank` call expression to SQL expression.\n */\nfunction isEmptyTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n isEmptyTransformValidator(context, arg);\n const condition = toBinaryExpression('IS', arg, { type: 'null', value: null });\n\n if (!context.ifCondition) {\n const whenArg = toWhen(\n condition,\n toFunction({ type: 'default', value: 'CAST' }, [\n toBinaryExpression('AS', { type: 'number', value: 1 }, { type: 'default', value: 'BIT' }),\n ]),\n );\n\n const elseArg = toElse(\n toFunction({ type: 'default', value: 'CAST' }, [\n toBinaryExpression('AS', { type: 'number', value: 0 }, { type: 'default', value: 'BIT' }),\n ]),\n );\n\n return toCase({ whenList: [whenArg], elseResult: elseArg });\n }\n\n return condition;\n}\n\n/**\n * Transforms `isnumber` call expression to SQL expression.\n */\nfunction isNumberTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n isNumberTransformValidator(context, arg);\n const sqlFnName = 'ISNUMERIC';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [arg]);\n}\n\n/**\n * Transforms `MAX` call expression to aggregate `MAX` SQL expression\n */\nfunction maxAggregateTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n maxAggregateTransformValidator(context, args);\n const sqlFnName = 'GREATEST';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, args);\n}\n\n/**\n * Transforms `MIN` call expression to aggregate `MIN` SQL expression\n */\nfunction minAggregateTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n minAggregateTransformValidator(context, args);\n const sqlFnName = 'LEAST';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, args);\n}\n\n/**\n * Transforms `mid` call expression to SQL expression.\n */\nfunction midTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n midTransformValidator(context, args);\n const sqlFnName = 'SUBSTRING';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n if (args.length !== 3) {\n throw new Error('MID() requires 3 arguments');\n }\n return toFunction(name, args);\n}\n\n/**\n * Transforms `median` call expression to SQL expression.\n */\nfunction medianTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): Select {\n medianTransformValidator(context, args);\n const currentColumnId = context.currentColumnId;\n const valueColumnName = formatDBEntityName(`val_${currentColumnId}`);\n const unionName = formatDBEntityName(`cte_union_${currentColumnId}`);\n const unionCte = new WithBuilder(context)\n .addName(unionName)\n .addStmt(\n args.reverse().reduce(\n (acc, arg) => {\n const builder = new SelectBuilder()\n .addColumns([\n ...context.primaryKeyColumns.map((id) => toColumn(toColumnRef(id))),\n toColumn(arg, valueColumnName),\n ])\n .addFrom([{ type: 'from', table: RUNTIME_TABLE_NAME } as From]);\n\n if (acc) {\n builder.addSetOp('UNION ALL').addNext(acc);\n }\n return builder.build();\n },\n undefined as Select | undefined,\n )!,\n )\n .build();\n\n const aggName = formatDBEntityName(`cte_agg_${currentColumnId}`);\n const aggCte = new WithBuilder(context)\n .addName(aggName)\n .addStmt(\n new SelectBuilder()\n .addDistinct()\n .addColumns([\n ...context.primaryKeyColumns.map((id) => toColumn(toColumnRef(id))),\n toColumn(\n {\n type: 'sql_expr',\n value: `PERCENTILE_CONT(0.50) WITHIN GROUP(ORDER BY ${valueColumnName}) OVER (PARTITION BY ${context.primaryKeyColumns.map((id) => id).join(', ')})`,\n },\n currentColumnId,\n ),\n ])\n .addFrom([{ type: 'from', table: unionCte.name.value } as From])\n .build(),\n )\n .build();\n\n const finalCteName = formatDBEntityName(`cte_${currentColumnId}`);\n const finalCte = new WithBuilder(context)\n .addName(finalCteName)\n .addStmt(\n new SelectBuilder()\n .addColumns([\n toColumn(toColumnRef('*', RUNTIME_TABLE_NAME)),\n toColumn(toColumnRef(currentColumnId)),\n ])\n .addFrom([\n { type: 'from', table: RUNTIME_TABLE_NAME } as From,\n toJoin(\n 'INNER JOIN',\n aggCte.name.value,\n context.primaryKeyColumns\n .map((id) =>\n toBinaryExpression(\n '=',\n toColumnRef(id, RUNTIME_TABLE_NAME),\n toColumnRef(id, aggCte.name.value),\n ),\n )\n .reduce((acc, expr) => toBinaryExpression('AND', acc, expr)),\n ),\n ])\n .build(),\n )\n .build();\n\n // since this transformation depends on primary key columns, manually add primary columns to the dependencies\n context.primaryKeyColumns.forEach((id) => context.addColumnDep(id));\n const select = new SelectBuilder().addWith([unionCte, aggCte, finalCte]).build();\n return select;\n}\n\n/**\n * Transforms `MODE` call expression to SQL expression.\n */\nfunction modeTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): Select {\n modeTransformValidator(context, args);\n const currentColumnId = context.currentColumnId;\n const valueColumnName = `val_${currentColumnId}`;\n const freqColumn = `freq_${currentColumnId}`;\n const rankColumn = `rank_${currentColumnId}`;\n\n // Step 1: Union CTE\n const unionCte = new WithBuilder(context)\n .addName(`cte_union_${currentColumnId}`)\n .addStmt(\n args.reverse().reduce(\n (acc, arg) => {\n const builder = new SelectBuilder()\n .addColumns([\n ...context.primaryKeyColumns.map((id) => toColumn(toColumnRef(id))),\n toColumn(arg, valueColumnName),\n ])\n .addFrom([\n {\n type: 'from',\n db: null,\n schema: undefined,\n table: RUNTIME_TABLE_NAME,\n as: null,\n },\n ]);\n\n if (acc) {\n builder.addSetOp('UNION ALL').addNext(acc);\n }\n\n return builder.build();\n },\n undefined as Select | undefined,\n )!,\n )\n .build();\n\n // Step 2: Frequency CTE\n const freqCte = new WithBuilder(context)\n .addName(`cte_freq_${currentColumnId}`)\n .addStmt(\n new SelectBuilder()\n .addColumns([\n ...context.primaryKeyColumns.map((id) => toColumn(toColumnRef(id))),\n toColumn(toColumnRef(valueColumnName), valueColumnName),\n toColumn(\n {\n type: 'sql_expr',\n value: `COUNT(*) OVER (PARTITION BY ${context.primaryKeyColumns.join(', ')}, ${valueColumnName})`,\n },\n freqColumn,\n ),\n ])\n .addFrom([\n {\n type: 'from',\n db: null,\n schema: undefined,\n table: `cte_union_${currentColumnId}`,\n as: null,\n },\n ])\n .build(),\n )\n .build();\n\n // Step 3: Ranked CTE\n const rankedCte = new WithBuilder(context)\n .addName(`cte_ranked_${currentColumnId}`)\n .addStmt(\n new SelectBuilder()\n .addColumns([\n ...context.primaryKeyColumns.map((id) => toColumn(toColumnRef(id))),\n toColumn(toColumnRef(valueColumnName), valueColumnName),\n toColumn(\n {\n type: 'sql_expr',\n value: `ROW_NUMBER() OVER (PARTITION BY ${context.primaryKeyColumns.join(', ')} ORDER BY ${freqColumn} DESC)`,\n },\n rankColumn,\n ),\n ])\n .addFrom([\n {\n type: 'from',\n db: null,\n schema: undefined,\n table: `cte_freq_${currentColumnId}`,\n as: null,\n },\n ])\n .build(),\n )\n .build();\n\n // Step 4: Mode CTE (where rank = 1)\n const modeCte = new WithBuilder(context)\n .addName(`cte_mode_${currentColumnId}`)\n .addStmt(\n new SelectBuilder()\n .addColumns([\n ...context.primaryKeyColumns.map((id) => toColumn(toColumnRef(id))),\n toColumn(toColumnRef(valueColumnName)),\n ])\n .addFrom([\n {\n type: 'from',\n db: null,\n schema: undefined,\n table: `cte_ranked_${currentColumnId}`,\n as: null,\n },\n ])\n .addWhere({\n type: 'binary_expr',\n operator: '=',\n left: toColumnRef(rankColumn),\n right: { type: 'number', value: 1 },\n })\n .build(),\n )\n .build();\n\n // Step 5: Final CTE (Join runtime table with mode)\n const finalCte = new WithBuilder(context)\n .addName(`cte_${currentColumnId}`)\n .addStmt(\n new SelectBuilder()\n .addColumns([\n toColumn(toColumnRef('*', RUNTIME_TABLE_NAME)),\n toColumn(toColumnRef(valueColumnName, `cte_mode_${currentColumnId}`), currentColumnId),\n ])\n .addFrom([\n {\n type: 'from',\n table: RUNTIME_TABLE_NAME,\n } as From,\n toJoin(\n 'INNER JOIN',\n `cte_mode_${currentColumnId}`,\n context.primaryKeyColumns\n .map((id) =>\n toBinaryExpression(\n '=',\n toColumnRef(id, RUNTIME_TABLE_NAME),\n toColumnRef(id, `cte_mode_${currentColumnId}`),\n ),\n )\n .reduce((acc, expr) => (acc ? toBinaryExpression('AND', acc, expr) : expr))!,\n ),\n ])\n .build(),\n )\n .build();\n context.primaryKeyColumns.forEach((id) => context.addColumnDep(id));\n\n // Final SELECT with all CTEs\n return new SelectBuilder().addWith([unionCte, freqCte, rankedCte, modeCte, finalCte]).build();\n}\n\n/**\n * Transforms `value` call expression to SQL expression.\n */\nfunction valueTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n valueTransformValidator(context, arg);\n const sqlFnName = 'CAST';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [toBinaryExpression('AS', arg, { type: 'default', value: 'FLOAT' })]);\n}\n\n/**\n * Transforms `pct` call expression to SQL expression.\n */\nfunction pctTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): PctObject {\n pctTransformValidator(context, arg);\n return new PctObject(arg);\n}\n\n/**\n * Transforms `xor` call expression to SQL expression.\n */\nfunction xorTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n xorTransformValidator(context, args);\n const [arg1, arg2] = args;\n const notArg2 = toUnaryExpression('NOT', arg2);\n const andLeft = toBinaryExpression('AND', arg1, notArg2);\n\n const notArg1 = toUnaryExpression('NOT', arg1);\n const andRight = toBinaryExpression('AND', notArg1, arg2);\n\n // Combining with OR: (arg1 AND NOT arg2) OR (NOT arg1 AND arg2)\n const xorCondition = toBinaryExpression('OR', andLeft, andRight);\n\n const whenArg = toWhen(xorCondition, { type: 'bit', value: 1 });\n const elseArg = toElse({ type: 'bit', value: 0 });\n\n return toCase({ whenList: [whenArg], elseResult: elseArg });\n}\n\n/**\n * Transforms `text` call expression to SQL expression.\n */\nfunction textTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n textTransformValidator(context, args);\n const sqlFnName = 'FORMAT';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n const [value, format, locale = { type: 'string', value: 'en-US' }] = args;\n const formatPattern = (format as Value).value as string;\n let resolvedPatternExp = format;\n if (!formatPattern.includes('#') && !formatPattern.includes('%')) {\n resolvedPatternExp = { type: 'string', value: datePattern(formatPattern) };\n }\n return toFunction(name, [value, resolvedPatternExp, locale]);\n}\n\nexport function datePattern(formatPattern: string): string {\n // https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings\n const patterns: Record<string, string> = {\n yyyy: 'yyyy',\n yyy: 'yyyy',\n yy: 'yy',\n y: 'y',\n mmmm: 'MMMM',\n mmm: 'MMM',\n mm: 'MM',\n m: '%M',\n dddd: 'dddd',\n ddd: 'ddd',\n dd: 'dd',\n d: '%d',\n };\n\n if (patterns[formatPattern]) {\n return patterns[formatPattern];\n }\n\n // Convert date format patterns to their SQL equivalents\n return formatPattern.replace(/[dmy]{1,4}/g, (match: string) => {\n if (patterns[match]) {\n return patterns[match];\n }\n throw new Error(`Invalid date format pattern: ${match}`); // this should never happen unless the regex and pattern map are inconsistent\n });\n}\n\n/**\n * Transforms `uuid` call expression to `NEWID()` SQL expression\n */\nfunction uuidTransform(_node: acorn.CallExpression, context: ParseContext): ExpressionValue {\n uuidTransformValidator(context);\n const sqlFnName = 'NEWID()';\n return { type: 'sql_expr', value: sqlFnName };\n}\n\n/**\n * Transforms `IFNA` call expression to SQL expression.\n */\nfunction ifNullTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n const argsCount = args.length;\n if (argsCount < 2) {\n throw new Error('IFNA() requires 2 arguments');\n }\n const [value, fallback] = args;\n const response = toFunction({ type: 'default', value: 'COALESCE' }, [value, fallback]);\n return response;\n}\n\nfunction fromExcelDateTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n arg: ExpressionValue,\n): ExpressionValue {\n fromExcelDateTransformValidator(context, arg);\n const correctedSerial = toBinaryExpression('-', arg, {\n type: 'number',\n value: 2,\n });\n\n return toFunction({ type: 'default', value: 'DATEADD' }, [\n { type: 'default', value: 'DAY' },\n correctedSerial,\n { type: 'string', value: '1900-01-01' },\n ]);\n}\n\nfunction hasTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n args: ExpressionValue[],\n searchValue: ExpressionValue,\n): ExpressionValue {\n hasTransformValidator(context, args, searchValue);\n const conditions = args.map((arg) => toBinaryExpression('=', arg, searchValue));\n const [first, ...rest] = conditions;\n const orCondition = rest.reduce((acc, cond) => toBinaryExpression('OR', acc, cond), first);\n\n const whenClause = toWhen(orCondition, { type: 'number', value: 1 });\n const elseClause = toElse({ type: 'number', value: 0 });\n\n return toCase({ whenList: [whenClause], elseResult: elseClause });\n}\n\nfunction hasSomeTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n args: ExpressionValue[],\n ...valueArray: ExpressionValue[]\n): ExpressionValue {\n hasSomeTransformValidator(context, args, valueArray);\n const comparisons: Binary[] = [];\n args.forEach((col) => {\n valueArray.forEach((valGroup) => {\n if (Array.isArray(valGroup)) {\n valGroup.forEach((val) => {\n const comp = toBinaryExpression('=', col, val);\n comparisons.push(comp);\n });\n } else {\n const comp = toBinaryExpression('=', col, valGroup);\n comparisons.push(comp);\n }\n });\n });\n\n const [first, ...rest] = comparisons;\n const orCondition = rest.reduce((acc, cond) => toBinaryExpression('OR', acc, cond), first);\n const whenClause = toWhen(orCondition, { type: 'number', value: 1 });\n const elseClause = toElse({ type: 'number', value: 0 });\n\n return toCase({ whenList: [whenClause], elseResult: elseClause });\n}\n\nfunction filterIfTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n columnArg: ExpressionValue,\n conditionArg: ExpressionValue,\n): ExpressionValue {\n filterIfTransformValidator(context, columnArg, conditionArg);\n const currentColumnId = context.currentColumnId;\n const valueColumnName = `val_${currentColumnId}`;\n const colName =\n columnArg.type === 'column_ref'\n ? (columnArg as ColumnRefItem).column\n : (columnArg as Value).value;\n const conditionBuilder = (valueColumnName: string) => {\n if (conditionArg.type === 'string') {\n const conditionWithLhs = `${colName} ${conditionArg.value}`;\n const localContext = new ParseContext({\n columnConfigMap: {\n ...context.columnConfigMap,\n [valueColumnName]: {\n columnName: valueColumnName,\n columnType: MDM_COLUMN_TYPE.NUMBER,\n columnMeta: { tableName: context.tableName },\n },\n },\n currentColumnId: context.currentColumnId,\n primaryKeyColumns: context.primaryKeyColumns,\n tableName: context.tableName,\n });\n const parser = createJsToSqlParser(localContext);\n return parser.parse(conditionWithLhs);\n }\n throw new Error('Invalid condition type');\n };\n const conditionExpr = conditionBuilder(valueColumnName);\n const whenClause = toWhen(conditionExpr, columnArg);\n const elseClause = toElse({ type: 'null', value: null });\n\n return toCase({\n whenList: [whenClause],\n elseResult: elseClause,\n });\n}\n\nfunction dateTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n date: ExpressionValue,\n format: ExpressionValue,\n year: ExpressionValue,\n): ExpressionValue {\n dateTransformValidator(context, date, format, year);\n if (!year) {\n const sqlFnName = 'FORMAT';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [date, format]);\n }\n const sqlFnName = 'DATEFROMPARTS';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n return toFunction(name, [date, format, year]);\n}\n\nfunction switchTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n switchTransformValidator(context, args);\n const switchExpr = args[0];\n const remainingArgs = args.slice(1);\n const whenList: {\n cond: Binary;\n result: ExpressionValue;\n type: 'when';\n }[] = [];\n\n const hasElse = remainingArgs.length % 2 === 1;\n const elseValue = hasElse\n ? remainingArgs[remainingArgs.length - 1]\n : { type: 'null', value: null };\n\n // Iterate over condition-result pairs\n remainingArgs.slice(0, hasElse ? -1 : undefined).forEach((arg, index, array) => {\n if (index % 2 === 0) {\n const matchValue = arg;\n const resultValue = array[index + 1];\n const condition = toBinaryExpression('=', switchExpr, matchValue);\n whenList.push({\n cond: condition,\n result: resultValue,\n type: 'when',\n });\n }\n });\n\n return toCase({\n whenList,\n elseResult: toElse(elseValue),\n });\n}\n\nfunction hasAllTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n args: ExpressionValue[],\n ...valueArray: ExpressionValue[][]\n): ExpressionValue {\n hasAllTransformValidator(context, args, valueArray);\n const andConditions: Binary[] = [];\n\n valueArray.forEach((valGroup) => {\n const innerComparisons: Binary[] = [];\n if (Array.isArray(valGroup)) {\n valGroup.forEach((val) => {\n args.forEach((col) => {\n innerComparisons.push(toBinaryExpression('=', col, val));\n });\n });\n }\n\n const [first, ...rest] = innerComparisons;\n const orCondition = rest.reduce((acc, cond) => toBinaryExpression('OR', acc, cond), first);\n andConditions.push(orCondition);\n });\n\n const [firstAnd, ...restAnd] = andConditions;\n const finalCondition = restAnd.reduce(\n (acc, cond) => toBinaryExpression('AND', acc, cond),\n firstAnd,\n );\n\n const whenClause = toWhen(finalCondition, { type: 'number', value: 1 });\n const elseClause = toElse({ type: 'number', value: 0 });\n\n return toCase({ whenList: [whenClause], elseResult: elseClause });\n}\n\n/**\n * Transforms `find` call expression to SQL expression.\n */\nfunction findTransform(\n node: acorn.CallExpression,\n context: ParseContext,\n ...args: ExpressionValue[]\n): ExpressionValue {\n const sqlFnName = 'CHARINDEX';\n const name = { type: 'default', value: sqlFnName } as ValueExpr<string>;\n if (args.length < 2) {\n throw new Error('FIND() requires at least 2 arguments (substring, string)');\n }\n\n return toFunction(name, args);\n}\n","import { Value } from '../sql-types';\n\nexport enum DataType {\n NUMBER = 'number',\n STRING = 'string',\n BOOLEAN = 'boolean',\n NULL = 'null',\n}\n\nexport function toValue(dataType: DataType, value: unknown): Value {\n return {\n type: dataType,\n value,\n };\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n\nimport { VisitorInterface } from './VisitorInterface';\nimport * as acorn from 'acorn';\nimport { ParseContext } from '../../ParseContext';\nimport { toValue, DataType } from '../../../sql-lib/literal';\nimport { toColumnRef } from '../../../sql-lib/column';\nimport { ExpressionValue } from '../../../sql-types';\nimport {\n RUNTIME_LOGGEDIN_EMAIL,\n RUNTIME_LOGGEDIN_NAME,\n RUNTIME_CURRENT_DATE,\n RUNTIME_CURRENT_DATETIME,\n} from '../../../runtime_var';\nimport { getArgType } from '@/utils';\n\nconst StaticIdentifierMap = new Map<string, (context: ParseContext) => ExpressionValue>([\n ['COLUMN_COUNT', (context: ParseContext) => toValue(DataType.NUMBER, context.getColumnCount())],\n ['BLANK', (context: ParseContext) => toValue(DataType.NULL, null)],\n ['TRUE', (context: ParseContext) => toValue(DataType.BOOLEAN, true)],\n ['FALSE', (context: ParseContext) => toValue(DataType.BOOLEAN, false)],\n ['LOGGEDIN_EMAIL', (context: ParseContext) => toValue(DataType.STRING, RUNTIME_LOGGEDIN_EMAIL)],\n ['LOGGEDIN_NAME', (context: ParseContext) => toValue(DataType.STRING, RUNTIME_LOGGEDIN_NAME)],\n ['CURRENT_DATE', (context: ParseContext) => toValue(DataType.STRING, RUNTIME_CURRENT_DATE)],\n [\n 'CURRENT_DATETIME',\n (context: ParseContext) => toValue(DataType.STRING, RUNTIME_CURRENT_DATETIME),\n ],\n]);\n\nexport class IdentifierVisitor implements VisitorInterface<acorn.Identifier> {\n /**\n * visitor needs to be implemented as arrow function to avoid `this` binding issue since it will be\n * passed to `acorn-walk` library\n */\n public visitor = (node: acorn.Identifier, context: ParseContext) => {\n try {\n const nameInUpperCase = node.name.toUpperCase();\n\n if (StaticIdentifierMap.has(nameInUpperCase)) {\n context.set(node, StaticIdentifierMap.get(nameInUpperCase)!(context));\n } else if (\n context.formulaIdColumnMap[node.name] ||\n context.deprecatedFormulaColumnMap[node.name]\n ) {\n const columnName =\n context.formulaIdColumnMap[node.name] || context.deprecatedFormulaColumnMap[node.name];\n const formattedColumnName = context.entityNameFormatter(columnName);\n context.set(node, toColumnRef(formattedColumnName));\n context.addColumnDep(columnName);\n // Validating the identifier and setting the return type\n const returnType = getArgType(toColumnRef(formattedColumnName), context);\n Object.assign(context, {\n returnType,\n isValid: true,\n error: undefined,\n });\n }\n } catch (error) {\n Object.assign(context, {\n isValid: false,\n error: error,\n });\n }\n };\n}\n","import { VisitorInterface } from './VisitorInterface';\nimport * as acorn from 'acorn';\nimport { ParseContext } from '../../ParseContext';\nimport { DataType, toValue } from '../../../sql-lib/literal';\nimport { getArgType } from '@/utils';\n\nexport class LiteralVisitor implements VisitorInterface<acorn.Literal> {\n /**\n * visitor needs to be implemented as arrow function to avoid `this` binding issue since it will be\n * passed to `acorn-walk` library\n */\n public visitor = (node: acorn.Literal, context: ParseContext) => {\n try {\n const value = node.value;\n const literalNode = toValue(getDataType(value), value);\n context.set(node, literalNode);\n\n // Validating the Literal and setting the return type\n const returnType = getArgType(literalNode, context);\n Object.assign(context, { returnType, isValid: true, error: undefined });\n } catch (error) {\n Object.assign(context, { isValid: false, error });\n }\n };\n}\n\nfunction getDataType(value: unknown): DataType {\n switch (typeof value) {\n case 'number':\n return DataType.NUMBER;\n case 'string':\n return DataType.STRING;\n case 'boolean':\n return DataType.BOOLEAN;\n default:\n return DataType.NULL;\n }\n}\n","import { VisitorInterface } from './VisitorInterface';\nimport * as acorn from 'acorn';\nimport { ParseContext } from '../../ParseContext';\nimport { toBinaryExpression } from '../../../sql-lib/binary_expr';\nimport { PctObject } from '../../objects/PctObject';\nimport { ExpressionValue } from '../../../sql-types';\nimport { toFunction } from '../../../sql-lib/function';\nimport { MATH_OPERATORS, OPERATOR_MAP } from '../../../constants';\nimport { getArgType } from '@/utils';\n\nexport class BinaryExpressionVisitor implements VisitorInterface<acorn.BinaryExpression> {\n /**\n * visitor needs to be implemented as arrow function to avoid `this` binding issue since it will be\n * passed to `acorn-walk` library\n */\n public visitor = (node: acorn.BinaryExpression, context: ParseContext) => {\n const operator = OPERATOR_MAP.get(node.operator) ?? node.operator;\n let lhs = context.get(node.left) as ExpressionValue;\n let rhs = context.get(node.right) as ExpressionValue;\n if (rhs instanceof PctObject) {\n context.set(node, rhs.resolve(lhs, { type: 'string', value: operator }));\n return;\n }\n\n if (MATH_OPERATORS.has(operator)) {\n // Wrap both sides in COALESCE(..., 0) to make math null-safe\n const lhsType = getArgType(lhs, context);\n const rhsType = getArgType(rhs, context);\n if (lhsType !== 'number' || rhsType !== 'number') {\n context.isValid = false;\n context.error = `Invalid operands for operator \"${operator}\": expected both sides to be numbers`;\n }\n context.returnType = 'number';\n lhs = toFunction({ type: 'default', value: 'COALESCE' }, [lhs, { type: 'number', value: 0 }]);\n rhs = toFunction({ type: 'default', value: 'COALESCE' }, [rhs, { type: 'number', value: 0 }]);\n\n if (operator === '/') {\n lhs = toFunction({ type: 'default', value: 'CAST' }, [\n toBinaryExpression('AS', lhs, { type: 'default', value: 'FLOAT' }),\n ]);\n }\n }\n\n context.set(node, toBinaryExpression(operator, lhs, rhs, MATH_OPERATORS.has(operator)));\n };\n}\n","import { VisitorInterface } from './VisitorInterface';\nimport * as acorn from 'acorn';\nimport { ParseContext } from '../../ParseContext';\n\nexport class ArrayExpressionVisitor implements VisitorInterface<acorn.ArrayExpression> {\n /**\n * visitor needs to be implemented as arrow function to avoid `this` binding issue since it will be\n * passed to `acorn-walk` library\n */\n public visitor = (node: acorn.ArrayExpression, context: ParseContext) => {\n context.set(\n node,\n node.elements.map((arg) => context.get(arg as acorn.Node)),\n );\n };\n}\n","import { VisitorInterface } from './VisitorInterface';\nimport * as acorn from 'acorn';\nimport { ParseContext } from '../../ParseContext';\nimport { ExpressionValue, Value } from '../../../sql-types';\n\nexport class UnaryExpressionVisitor implements VisitorInterface<acorn.UnaryExpression> {\n /**\n * visitor needs to be implemented as arrow function to avoid `this` binding issue since it will be\n * passed to `acorn-walk` library\n */\n public visitor = (node: acorn.UnaryExpression, context: ParseContext) => {\n const expr = context.get(node.argument);\n const op = node.operator;\n if (node.argument.type === 'Literal') {\n context.set(node, resolveLiteral(op, expr as Value));\n return;\n }\n\n throw new Error(`Unsupported unary operator: ${op}`);\n };\n}\n\nfunction resolveLiteral(op: string, arg: Value): ExpressionValue {\n switch (op) {\n case '-':\n return { type: 'number', value: -arg.value };\n case '+':\n return arg;\n default:\n throw new Error(`Unsupported unary operator: ${op}`);\n }\n}\n","import { VisitorInterface } from './VisitorInterface';\nimport * as acorn from 'acorn';\nimport { ParseContext } from '../../ParseContext';\nimport { BaseObject } from '../../objects/BaseObject';\n\nexport class ProgramVisitor implements VisitorInterface<acorn.Program> {\n /**\n * visitor needs to be implemented as arrow function to avoid `this` binding issue since it will be\n * passed to `acorn-walk` library\n */\n public visitor = (node: acorn.Program, context: ParseContext) => {\n let result = context.get(node.body[node.body.length - 1]);\n if (result instanceof BaseObject) {\n result = result.resolve();\n }\n context.set(node, result);\n };\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n\nimport { toFunction } from '../../sql-lib/function';\nimport { SqlFunction, ExpressionValue } from '../../sql-types';\nimport { ParseContext } from '../ParseContext';\nimport { BaseObject, ObjectFn } from './BaseObject';\n\nexport class DateObject extends BaseObject {\n private date: ExpressionValue | SqlFunction;\n\n constructor(date?: ExpressionValue) {\n super();\n this.date = date || toFunction({ type: 'default', value: 'CURRENT_DATE' }, []);\n this._fnMap = new Map<string, ObjectFn<ExpressionValue>>([\n ['NOW', (context: ParseContext) => this],\n ['SET', (context: ParseContext, ...args: ExpressionValue[]) => this.setDate(...args)],\n ]);\n }\n\n setDate(...args: ExpressionValue[]): DateObject {\n this.date = toFunction({ type: 'default', value: 'DATE' }, args);\n return this;\n }\n\n resolve(): ExpressionValue | SqlFunction {\n return this.date;\n }\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n\nimport { VisitorInterface } from './VisitorInterface';\nimport * as acorn from 'acorn';\nimport { ParseContext } from '../../ParseContext';\nimport { BaseObject } from '../../objects/BaseObject';\nimport { DateObject } from '../../objects/DateObject';\n\nconst OBJECT_MAP = new Map<string, (context: ParseContext) => BaseObject>([\n ['DATE', (context: ParseContext) => new DateObject()],\n]);\n\nexport class MemberExpressionVisitor implements VisitorInterface<acorn.MemberExpression> {\n /**\n * visitor needs to be implemented as arrow function to avoid `this` binding issue since it will be\n * passed to `acorn-walk` library\n */\n public visitor = (node: acorn.MemberExpression, context: ParseContext) => {\n const objectName = (node.object as acorn.Identifier).name.toUpperCase();\n const property = (node.property as acorn.Identifier).name.toUpperCase();\n const object = OBJECT_MAP.get(objectName)?.(context);\n if (!object) {\n throw new Error(`Unsupported object: ${objectName}`);\n }\n\n context.set(node, object);\n const isFn = object.fnMap.has(property);\n const isProp = !isFn && object.propertyMap.has(property);\n if (!isFn && !isProp) {\n throw new Error(`Unsupported property: ${property}`);\n } else if (isProp) {\n context.set(node, object.propertyMap.get(property)?.(context));\n }\n // otherwise ignore. It will be resolved later in call expression\n };\n}\n","import { VisitorInterface } from './VisitorInterface';\nimport * as acorn from 'acorn';\nimport { ParseContext } from '../../ParseContext';\nimport { toBinaryExpression } from '../../../sql-lib/binary_expr';\nimport { PctObject } from '../../objects/PctObject';\nimport { ExpressionValue } from '../../../sql-types';\nimport { getArgType } from '@/utils';\n\nexport class AssignmentExpressionVisitor implements VisitorInterface<acorn.AssignmentExpression> {\n public visitor = (node: acorn.AssignmentExpression, context: ParseContext) => {\n const operator = node.operator;\n\n // We're only treating \"=\" as comparison\n if (operator !== '=') {\n context.isValid = false;\n context.error = `Unsupported assignment operator: \"${operator}\"`;\n return;\n }\n const lhs = context.get(node.left) as ExpressionValue;\n const rhs = context.get(node.right) as ExpressionValue;\n if (getArgType(lhs, context) !== getArgType(rhs, context)) {\n context.isValid = false;\n context.error = `Expected both sides dataType to be same`;\n }\n\n if (rhs instanceof PctObject) {\n context.set(node, rhs.resolve(lhs, { type: 'string', value: '=' }));\n return;\n }\n\n const expr = toBinaryExpression('=', lhs, rhs, false);\n context.set(node, expr);\n };\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { ParseContext, ResolvedExpressionType, SqlQueryProps } from './ParseContext';\nimport { VisitorInterface } from './db/base/VisitorInterface';\nimport * as acorn from 'acorn';\nimport * as walk from 'acorn-walk';\nimport { CallExpressionVisitor } from './db/base/CallExpressionVisitor';\nimport { IdentifierVisitor } from './db/base/IdentifierVisitor';\nimport { LiteralVisitor } from './db/base/LiteralVisitor';\nimport { BinaryExpressionVisitor } from './db/base/BinaryExpressionVisitor';\nimport { ArrayExpressionVisitor } from './db/base/ArrayExpressionVisitor';\nimport { UnaryExpressionVisitor } from './db/base/UnaryExpressionVisitor';\nimport { ProgramVisitor } from './db/base/ProgramVisitor';\nimport { MemberExpressionVisitor } from './db/base/MemberExpressionVisitor';\nimport { generateSqlQuery } from '../sql_query_gen';\nimport { AssignmentExpressionVisitor } from './db/base/AssignmentExpressionVisitor';\n\nexport type ResolvedFormulaProps = {\n returnType: string | undefined;\n isValid: boolean;\n error: string | undefined;\n sqlQueryProps: SqlQueryProps;\n deps: string[];\n};\n\n/**\n * Factory function to create database specific parser\n */\nexport function createJsToSqlParser(context: ParseContext): JsToSqlParser {\n // Handles functions based on fabricsql type\n return new JsToSqlParser(context);\n}\n\nexport type VisitorConfig = {\n callExpression?: VisitorInterface<acorn.CallExpression>;\n identifier?: VisitorInterface<acorn.Identifier>;\n literal?: VisitorInterface<acorn.Literal>;\n binaryExpression?: VisitorInterface<acorn.BinaryExpression>;\n arrayExpression?: VisitorInterface<acorn.ArrayExpression>;\n unaryExpression?: VisitorInterface<acorn.UnaryExpression>;\n program?: VisitorInterface<acorn.Program>;\n memberExpression?: VisitorInterface<acorn.MemberExpression>;\n assignmentExpression?: VisitorInterface<acorn.AssignmentExpression>;\n};\n\n/**\n * Parses a JavaScript formula and returns the corresponding SQL AST.\n * - For Database specific overrides, implement the corresponding visitor in `db` directory and\n * pass it to the constructor as part of the `config` parameter.\n * - Use Factory function to compose parser for specific database\n */\nexport class JsToSqlParser {\n private context: ParseContext;\n private callExpression: VisitorInterface<acorn.CallExpression>;\n private identifier: VisitorInterface<acorn.Identifier>;\n private literal: VisitorInterface<acorn.Literal>;\n private binaryExpression: VisitorInterface<acorn.BinaryExpression>;\n private arrayExpression: VisitorInterface<acorn.ArrayExpression>;\n private unaryExpression: VisitorInterface<acorn.UnaryExpression>;\n private program: VisitorInterface<acorn.Program>;\n private memberExpression: VisitorInterface<acorn.MemberExpression>;\n private assignmentExpression: VisitorInterface<acorn.AssignmentExpression>;\n\n constructor(context: ParseContext, config: VisitorConfig = {}) {\n this.context = context;\n this.callExpression = config.callExpression || new CallExpressionVisitor();\n this.identifier = config.identifier || new IdentifierVisitor();\n this.literal = config.literal || new LiteralVisitor();\n this.binaryExpression = config.binaryExpression || new BinaryExpressionVisitor();\n this.arrayExpression = config.arrayExpression || new ArrayExpressionVisitor();\n this.unaryExpression = config.unaryExpression || new UnaryExpressionVisitor();\n this.program = config.program || new ProgramVisitor();\n this.memberExpression = config.memberExpression || new MemberExpressionVisitor();\n this.assignmentExpression = config.assignmentExpression || new AssignmentExpressionVisitor();\n }\n\n parse(formula: string): any {\n // Parse the formula\n const formulaText = this.processFormulaText(formula);\n const jsAst = acorn.parse(formulaText, { ecmaVersion: 2020 });\n\n // Traverse the AST in pre-order to check for 'if' statements\n this.detectIfCondition(jsAst);\n\n // Traverse the AST and generate SQL AST\n walk.recursive(jsAst, this.context.reset(), {\n CallExpression: (node, state, c) => {\n c(node.callee, state);\n node.arguments.forEach((arg) => c(arg, state));\n this.callExpression.visitor(node, state);\n },\n Identifier: (node, state) => {\n this.identifier.visitor(node, state);\n },\n Literal: (node, state) => {\n this.literal.visitor(node, state);\n },\n BinaryExpression: (node, state, c) => {\n c(node.left, state);\n c(node.right, state);\n this.binaryExpression.visitor(node, state);\n },\n AssignmentExpression: (node, state, c) => {\n c(node.left, state);\n c(node.right, state);\n this.assignmentExpression.visitor(node, state);\n },\n ArrayExpression: (node, state, c) => {\n node.elements.forEach((el) => {\n if (el !== null) c(el, state);\n });\n this.arrayExpression.visitor(node, state);\n },\n UnaryExpression: (node, state, c) => {\n c(node.argument, state);\n this.unaryExpression.visitor(node, state);\n },\n MemberExpression: (node, state, c) => {\n c(node.object, state);\n if (node.computed) c(node.property, state);\n this.memberExpression.visitor(node, state);\n },\n Program: (node, state, c) => {\n node.body.forEach((statement) => c(statement, state));\n this.program.visitor(node, state);\n },\n });\n const sqlAst = this.context.getLastEvaluatedValue();\n return sqlAst;\n }\n\n /**\n * Converts the SQL AST to a SQL query string\n */\n toSql(sqlAst: any): string {\n return generateSqlQuery(sqlAst);\n }\n\n /**\n * Creates appropriate SQL query props based on the SQL AST\n */\n toSqlProps(sqlAst: any): SqlQueryProps {\n const sqlQueryStr = this.toSql(sqlAst);\n\n if (this.context.cteCount > 0) {\n return {\n resolvedExpression: {\n type: ResolvedExpressionType.CTE,\n cteName: `cte_${this.context.currentColumnId}`,\n value: [sqlQueryStr],\n },\n };\n }\n\n return {\n resolvedExpression: {\n type: ResolvedExpressionType.COLUMN,\n value: [sqlQueryStr],\n },\n };\n }\n\n /**\n * Returns the resolved formula props for current column along with the dependencies\n */\n getResolvedFormulaProps(sqlAst: any): ResolvedFormulaProps {\n const sqlQueryProps = this.toSqlProps(sqlAst);\n return {\n sqlQueryProps,\n deps: Array.from(this.context.getColumnDeps()),\n returnType: this.context.returnType,\n isValid: this.context.isValid,\n error: this.context.error,\n };\n }\n\n /**\n * Pre walk and detect if the jsAst has 'if'\n */\n private detectIfCondition(jsAst: acorn.Node): void {\n walk.simple(jsAst, {\n CallExpression: (node: acorn.CallExpression) => {\n if (node.callee.type === 'Identifier' && node.callee.name.toUpperCase() === 'IF') {\n this.context.ifCondition = true;\n }\n },\n });\n }\n\n /**\n * Extracts and normalizes formula by adding parentheses to reserved function names\n */\n private processFormulaText(formula: string): string {\n // Extract formula from {{ ... }} or use the string as-is\n const formulaText = formula?.match(/{{([^}]*)}}/)?.[1] ?? formula;\n\n // Reserved function names to patch\n const reservedFunctions = ['NOW', 'TODAY', 'UUID', 'RAND'];\n\n // Patch function names not followed by '(' to add ()\n let patched = formulaText;\n for (const fn of reservedFunctions) {\n const regex = new RegExp(`\\\\b${fn}\\\\b(?!\\\\s*\\\\()`, 'gi');\n patched = patched.replace(regex, `${fn}()`);\n }\n\n if (formulaText.includes('FOREACH')) {\n patched = this.removeForeach(formula);\n }\n return patched;\n }\n\n private removeForeach(input: string): string {\n const foreachRegex = /FOREACH\\(([^,]*),([^()]*)\\)/g;\n return input.replace(foreachRegex, '$2');\n }\n}\n","export function extractColumnIdFromHierarchy(columnId: string): string {\n if (columnId.startsWith('[H] ')) {\n return columnId.substring(4);\n }\n if (columnId.includes('~||~')) {\n const parts = columnId.split('~||~');\n return parts.length > 1 ? parts[1] : columnId;\n }\n return columnId;\n}\n\nexport function getTableNameFromId(columnId: string): string | null {\n const actualColumnId = extractColumnIdFromHierarchy(columnId);\n const lastBracketIndex = actualColumnId.lastIndexOf('[');\n if (lastBracketIndex > 0) {\n return actualColumnId.substring(0, lastBracketIndex).trim();\n }\n return null;\n}\n\nexport function extractTableNameFromColumnId(columnId: string, columnName: string): string {\n if (!columnId || !columnName) {\n return '';\n }\n const sanitizedColumnId = extractColumnIdFromHierarchy(columnId);\n const columnNamePattern = `[${columnName}]`;\n const index = sanitizedColumnId.lastIndexOf(columnNamePattern);\n if (index !== -1) {\n return sanitizedColumnId.substring(0, index);\n }\n return sanitizedColumnId;\n}\n\nexport function getColumnNameFromId(columnId: string): string {\n const actualColumnId = extractColumnIdFromHierarchy(columnId);\n const start = actualColumnId.lastIndexOf('[');\n const end = actualColumnId.lastIndexOf(']');\n if (start >= 0 && end > start) {\n return actualColumnId.substring(start + 1, end);\n }\n return actualColumnId;\n}\n","export const AGGREGATION_TYPE_MAP: Record<string, string> = {\n FIRST: 'MIN',\n LAST: 'MAX',\n STANDARD_DEVIATION: 'STDDEV',\n VARIANCE: 'VAR',\n AVERAGE: 'AVG',\n COUNT_DISTINCT: 'COUNT',\n DISTINCT_COUNT: 'COUNT',\n COUNT: 'COUNT',\n};\n\nexport function mapAggregationType(aggregationType?: string): string {\n if (!aggregationType) return 'SUM';\n const key = aggregationType.toUpperCase();\n return AGGREGATION_TYPE_MAP[key] || key;\n}\n","// Source types for epm query builder\nexport const SOURCE_TYPES = {\n BLEND: 'blend',\n XMLA: 'xmla',\n} as const;\n\nexport type SourceType = (typeof SOURCE_TYPES)[keyof typeof SOURCE_TYPES];\n","export function validateRequiredFields(obj: unknown, fields: string[]): boolean {\n if (!obj) return false;\n const rec = obj as Record<string, unknown>;\n return fields.every((field) => rec[field] !== undefined && rec[field] !== null);\n}\n\nexport function isEmptyOrWhitespace(value: string | undefined | null): boolean {\n return !value || value.trim().length === 0;\n}\n\nexport function isValidIdentifier(identifier: string): boolean {\n return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(identifier);\n}\n","export function formatValue(value: string | number | boolean): string {\n if (typeof value === 'string') {\n return `'${value.replace(/'/g, \"''\")}'`;\n }\n return String(value);\n}\n\nexport function sanitizeIdentifier(identifier: string): string {\n return identifier.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nexport function buildColumnReference(\n tableName: string | undefined,\n columnName: string,\n useQuotes = true,\n): string {\n if (!tableName) return columnName;\n if (useQuotes) {\n return `\"${tableName}\".\"${columnName}\"`;\n }\n return `${tableName}.${columnName}`;\n}\n","export function combineConditions(conditions: string[], operator: 'AND' | 'OR' = 'AND'): string {\n const validConditions = conditions.filter((condition) => condition && condition.trim());\n if (validConditions.length === 0) return '';\n if (validConditions.length === 1) return validConditions[0];\n return `(${validConditions.join(` ${operator} `)})`;\n}\n\nexport function buildSqlSelect(\n items: string[],\n tableName: string,\n whereClause?: string,\n groupBy?: string[],\n orderBy?: string,\n limit?: string,\n): string {\n let query = `SELECT ${items.join(', ')} FROM ${tableName}`;\n if (whereClause) {\n query += ` WHERE ${whereClause}`;\n }\n if (groupBy?.length) {\n query += ` GROUP BY ${groupBy.join(', ')}`;\n }\n if (orderBy) {\n query += ` ORDER BY ${orderBy}`;\n }\n if (limit) {\n query += ` ${limit}`;\n }\n return query;\n}\n\nexport function buildDistinctSelect(\n columns: string[],\n tableName: string,\n whereClause?: string,\n orderBy?: string,\n): string {\n let query = `SELECT DISTINCT ${columns.join(', ')} FROM ${tableName}`;\n if (whereClause) {\n query += ` WHERE ${whereClause}`;\n }\n if (orderBy) {\n query += ` ORDER BY ${orderBy}`;\n }\n return query;\n}\n\nexport function buildLimitClause(offset?: number, limit?: number): string {\n if (limit === undefined) return '';\n if (offset !== undefined && offset > 0) {\n return `LIMIT ${limit} OFFSET ${offset}`;\n }\n return `LIMIT ${limit}`;\n}\n","// helpers: shared utilities used across dialects and builders\nimport {\n EpmQueryBuilderOptions,\n RowColumnConfig,\n OrderByConfig,\n} from '@epm-query-builder/types/query-builder-types';\nimport * as ColumnRefUtils from '@epm-query-builder/base/ColumnRefUtils';\nimport { mapAggregationType as mapAgg } from '@epm-query-builder/constants/Aggregations';\nimport { SOURCE_TYPES } from '@epm-query-builder/constants/Source';\nimport * as Validation from '@epm-query-builder/utils/validation';\nimport * as Format from '@epm-query-builder/utils/format';\nimport * as Sql from '@epm-query-builder/utils/sql';\n\nexport class BaseUtilities {\n static buildSqlSelect(\n items: string[],\n tableName: string,\n whereClause?: string,\n groupBy?: string[],\n orderBy?: string,\n limit?: string,\n ): string {\n return Sql.buildSqlSelect(items, tableName, whereClause, groupBy, orderBy, limit);\n }\n\n static formatColumnWithAlias(column: string, alias: string): string {\n return `${column} AS \"${alias}\"`;\n }\n\n static buildCTETemplate(name: string, query: string): string {\n return `${name} AS (${query})`;\n }\n\n static validateRequiredFields(obj: unknown, fields: string[]): boolean {\n return Validation.validateRequiredFields(obj, fields);\n }\n\n static combineConditions(conditions: string[], operator: 'AND' | 'OR' = 'AND'): string {\n return Sql.combineConditions(conditions, operator);\n }\n\n static formatValue(value: string | number | boolean): string {\n return Format.formatValue(value);\n }\n\n static stringToDate(value: string): string {\n if (!value) return 'NULL';\n\n const dateFormats = [\n /^\\d{4}-\\d{2}-\\d{2}$/, // YYYY-MM-DD\n /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/, // YYYY-MM-DD HH:mm:ss\n /^\\d{2}\\/\\d{2}\\/\\d{4}$/, // MM/DD/YYYY\n /^\\d{2}-\\d{2}-\\d{4}$/, // MM-DD-YYYY\n ];\n\n if (dateFormats.some((format) => format.test(value))) {\n return `DATE('${value}')`;\n }\n\n return `'${value.replace(/'/g, \"''\")}'`;\n }\n\n static formatValueForDataType(value: string | number | boolean, dataType: string): string {\n if (!dataType) {\n return this.formatValue(value);\n }\n\n switch (dataType.toLowerCase()) {\n case 'string':\n return `'${String(value).replace(/'/g, \"''\")}'`;\n case 'date':\n case 'datetime':\n return this.stringToDate(String(value));\n case 'number':\n case 'decimal':\n case 'integer':\n return String(value);\n case 'boolean':\n return String(value).toLowerCase() === 'true' ? 'TRUE' : 'FALSE';\n default:\n return this.formatValue(value);\n }\n }\n\n static buildColumnReference(\n tableName: string | undefined,\n columnName: string,\n useQuotes = true,\n ): string {\n if (!tableName) return columnName;\n\n if (useQuotes) {\n return `\"${tableName}\".\"${columnName}\"`;\n }\n return `${tableName}.${columnName}`;\n }\n\n static extractTableNameFromId(columnId: string): string | null {\n return ColumnRefUtils.getTableNameFromId(columnId);\n }\n\n static getEffectiveColumnName(config: RowColumnConfig): string {\n const actualColumnId = this.extractColumnIdFromHierarchy(config.id);\n return actualColumnId;\n }\n\n static extractColumnIdFromHierarchy(columnId: string): string {\n return ColumnRefUtils.extractColumnIdFromHierarchy(columnId);\n }\n\n static extractTableNameFromColumnId(columnId: string, columnName: string): string {\n return ColumnRefUtils.extractTableNameFromColumnId(columnId, columnName);\n }\n\n static formColumnId(tableName: string, columnName: string): string {\n if (!tableName || !columnName) return columnName || '';\n return `\"${tableName}\".\"${columnName}\"`;\n }\n\n static isValidTableName(tableName: string): boolean {\n return /^[a-zA-Z0-9_[\\]().\\s]+$/.test(tableName);\n }\n\n static getEffectiveTableName(config: RowColumnConfig, options: EpmQueryBuilderOptions): string {\n return (\n config.tableName ||\n BaseUtilities.extractTableNameFromId(config.id) ||\n BaseUtilities.getDefaultTableName(options)\n );\n }\n\n static getDefaultTableName(options: EpmQueryBuilderOptions): string {\n const allItems = [\n ...(options.rows || []),\n ...(options.columns || []),\n ...(options.values || []),\n ];\n\n for (const item of allItems) {\n if (item.tableName) return item.tableName;\n }\n\n for (const item of allItems) {\n const tableFromId = BaseUtilities.extractTableNameFromId(item.id);\n if (tableFromId) return tableFromId;\n }\n\n const tablesFromFilters = this.extractTableNames(options);\n if (tablesFromFilters.length > 0) {\n return tablesFromFilters[0];\n }\n\n return '';\n }\n\n static buildDistinctSelect(\n columns: string[],\n tableName: string,\n whereClause?: string,\n orderBy?: string,\n ): string {\n return Sql.buildDistinctSelect(columns, tableName, whereClause, orderBy);\n }\n\n static buildCountQuery(tableName: string, whereClause?: string): string {\n let query = `SELECT COUNT(*) FROM ${tableName}`;\n\n if (whereClause) {\n query += ` WHERE ${whereClause}`;\n }\n\n return query;\n }\n\n static sanitizeIdentifier(identifier: string): string {\n return Format.sanitizeIdentifier(identifier);\n }\n\n static isEmptyOrWhitespace(value: string | undefined | null): boolean {\n return Validation.isEmptyOrWhitespace(value);\n }\n\n static isValidIdentifier(identifier: string): boolean {\n return Validation.isValidIdentifier(identifier);\n }\n\n static ensureArray<T>(value: T | T[] | undefined): T[] {\n if (!value) return [];\n return Array.isArray(value) ? value : [value];\n }\n\n static hasValue<T>(value: T | undefined | null): value is T {\n return value !== undefined && value !== null;\n }\n\n static buildOrderByClause(orderItems: OrderByConfig[]): string {\n if (!orderItems?.length) return '';\n\n const clauses = orderItems.map((item) => {\n const direction = item.type?.toUpperCase() === 'DESC' ? 'DESC' : 'ASC';\n return `${item.columnName} ${direction}`;\n });\n\n return `ORDER BY ${clauses.join(', ')}`;\n }\n\n static extractUniqueTableNames(options: EpmQueryBuilderOptions): string[] {\n const tables = new Set<string>();\n\n [...(options.rows || []), ...(options.columns || []), ...(options.values || [])].forEach(\n (item) => {\n if (!item) return;\n\n const directTableName = item.tableName;\n\n const inferredTableName =\n !directTableName && item.id ? BaseUtilities.getTableNameFromId(item.id) : null;\n\n const effectiveTableName = directTableName || inferredTableName;\n if (effectiveTableName) {\n tables.add(effectiveTableName);\n }\n },\n );\n\n if (options.superFilters?.children) {\n options.superFilters.children.forEach((child) => {\n if (child.filters?.tableNames) {\n child.filters.tableNames.forEach((tableName) => {\n if (tableName) tables.add(tableName);\n });\n }\n });\n }\n\n return Array.from(tables);\n }\n\n static buildLimitClause(offset?: number, limit?: number): string {\n return Sql.buildLimitClause(offset, limit);\n }\n\n static buildMonthOrderKey(columnExpression: string): string {\n const expr = `TRIM(CAST(${columnExpression} AS VARCHAR))`;\n return `COALESCE(\n EXTRACT(MONTH FROM TRY_STRPTIME(${expr}, '%b')),\n EXTRACT(MONTH FROM TRY_STRPTIME(${expr}, '%B')),\n EXTRACT(MONTH FROM TRY_STRPTIME(LOWER(${expr}), '%b')),\n EXTRACT(MONTH FROM TRY_STRPTIME(LOWER(${expr}), '%B')),\n TRY_CAST(${columnExpression} AS INTEGER),\n 13\n )`;\n }\n\n static buildQuarterOrderKey(columnExpression: string): string {\n const expr = `TRIM(LOWER(CAST(${columnExpression} AS VARCHAR)))`;\n return `COALESCE(\n EXTRACT(QUARTER FROM TRY_STRPTIME(${expr}, '%b')),\n EXTRACT(QUARTER FROM TRY_STRPTIME(${expr}, '%B')),\n CASE WHEN ${expr} LIKE 'q1%' THEN 1 WHEN ${expr} LIKE 'q2%' THEN 2 WHEN ${expr} LIKE 'q3%' THEN 3 WHEN ${expr} LIKE 'q4%' THEN 4 ELSE NULL END,\n TRY_CAST(${columnExpression} AS INTEGER),\n 5\n )`;\n }\n\n static buildMeasureExpression(\n tableName: string,\n columnName: string,\n aggregationType?: string,\n ): string {\n if (!aggregationType || aggregationType === 'NONE') {\n return `\"${tableName}\".\"${columnName}\"`;\n }\n\n const mappedAggregation = this.mapAggregationType(aggregationType);\n return `${mappedAggregation}(\"${tableName}\".\"${columnName}\")`;\n }\n\n static mapAggregationType(aggregationType: string): string {\n return mapAgg(aggregationType);\n }\n\n static buildWhereCondition(conditions: string[], operator: 'AND' | 'OR' = 'AND'): string {\n const validConditions = conditions.filter((condition) => condition && condition.trim());\n\n if (validConditions.length === 0) return '';\n if (validConditions.length === 1) return validConditions[0];\n\n return `(${validConditions.join(` ${operator} `)})`;\n }\n\n static getTableNameFromId(columnId: string): string | null {\n return ColumnRefUtils.getTableNameFromId(columnId);\n }\n\n static getTableNameFromColumnId(columnId: string, columnName?: string): string {\n if (!columnId) return '';\n if (columnName) {\n return this.extractTableNameFromColumnId(columnId, columnName);\n }\n return this.getTableNameFromId(columnId) || '';\n }\n\n static sanitizeHierarchyPrefix(columnId: string): string {\n return ColumnRefUtils.extractColumnIdFromHierarchy(columnId);\n }\n\n static extractTableNames(options: EpmQueryBuilderOptions): string[] {\n if (!options.superFilters?.children) {\n return [];\n }\n const tableNames = new Set<string>();\n options.superFilters.children.forEach((child) => {\n if (child.filters?.tableNames) {\n child.filters.tableNames.forEach((tableName) => {\n tableNames.add(tableName);\n });\n }\n });\n return Array.from(tableNames);\n }\n\n static formatColumnReferenceForDb(\n config: RowColumnConfig,\n options: EpmQueryBuilderOptions,\n ): string {\n const source = this.getSource(options);\n const actualColumnId = this.extractColumnIdFromHierarchy(config.id);\n const idForDb = source === SOURCE_TYPES.BLEND ? config.id : actualColumnId;\n if (options.databaseDetails?.databaseType === 'duckdb') {\n const useDot = this.shouldUseDotNotation(options);\n if (useDot) {\n const tableName =\n config.tableName ||\n this.getTableNameFromId(config.id) ||\n this.getDefaultTableNameFromOptions(options) ||\n this.extractTableNames(options)[0] ||\n '';\n const effectiveColumnName = idForDb;\n if (tableName) {\n return this.buildColumnReference(tableName, effectiveColumnName);\n }\n return `\"${effectiveColumnName}\"`;\n }\n return `\"${idForDb}\"`;\n }\n const tableName =\n config.tableName ||\n this.getTableNameFromId(config.id) ||\n this.extractTableNames(options)[0] ||\n '';\n const effectiveColumnName = idForDb;\n return `${tableName}.${effectiveColumnName}`;\n }\n\n static buildDimensionReference(\n items: RowColumnConfig[] | undefined,\n options: EpmQueryBuilderOptions,\n ): string[] {\n return items?.map((item) => this.formatColumnReferenceForDb(item, options)) || [];\n }\n\n static getDefaultTableNameFromOptions(options: EpmQueryBuilderOptions): string {\n const rows = options.rows || [];\n const columns = options.columns || [];\n const values = options.values || [];\n const allItems = [...rows, ...columns, ...values];\n if (allItems.length > 0 && allItems[0].tableName) {\n return allItems[0].tableName;\n }\n const tablesFromFilters = this.extractTableNames(options);\n if (tablesFromFilters.length > 0) {\n return tablesFromFilters[0];\n }\n return '';\n }\n\n static formatTableColumnReference(tableName: string, columnName: string): string {\n return `\"${tableName}\".\"${columnName}\"`;\n }\n\n static sanitizeIdentifierString(identifier: string): string {\n return identifier.replace(/[^a-zA-Z0-9_]/g, '_');\n }\n\n static isValidTableNameString(tableName: string): string | boolean {\n return /^[a-zA-Z0-9_[\\]().\\s]+$/.test(tableName);\n }\n\n static formatTableNameForDb(tableName: string, databaseType?: string): string {\n if (databaseType === 'duckdb' || tableName.includes(' ') || tableName.includes('-')) {\n return `\"${tableName}\"`;\n }\n return tableName;\n }\n\n static shouldUseDotNotation(options: EpmQueryBuilderOptions): boolean {\n const src = this.getSource(options);\n return src === SOURCE_TYPES.BLEND;\n }\n\n static getSource(options: EpmQueryBuilderOptions): string {\n const source =\n (options as unknown as { config?: { source?: string } })?.config?.source ||\n (options as unknown as { source?: string })?.source ||\n this.safeGet<string>(\n options.databaseDetails as unknown as Record<string, unknown>,\n 'source',\n '',\n ) ||\n '';\n return String(source || '').toLowerCase();\n }\n\n static buildFilterConditionForOperator(\n column: string,\n operator: string,\n value: string | number | boolean,\n ): string {\n const formattedValue = typeof value === 'string' ? BaseUtilities.formatValue(value) : value;\n switch (operator.toUpperCase()) {\n case 'IS_EQUAL_TO':\n case 'IS':\n return `${column} = ${formattedValue}`;\n case 'IS_NOT_EQUAL_TO':\n case 'IS_NOT':\n return `${column} != ${formattedValue}`;\n case 'IS_GREATER_THAN':\n return `${column} > ${formattedValue}`;\n case 'IS_GREATER_THAN_OR_EQUAL_TO':\n return `${column} >= ${formattedValue}`;\n case 'IS_LESS_THAN':\n return `${column} < ${formattedValue}`;\n case 'IS_LESS_THAN_OR_EQUAL_TO':\n return `${column} <= ${formattedValue}`;\n case 'IS_BLANK':\n return `${column} IS NULL`;\n case 'IS_NOT_BLANK':\n return `${column} IS NOT NULL`;\n default:\n return `${column} = ${formattedValue}`;\n }\n }\n\n static normalizeComparisonOperator(operator: string): string {\n const canonical = (operator || '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+|_+$/g, '');\n switch (canonical) {\n case 'is':\n case 'equals':\n case 'is_equal_to':\n return '=';\n case 'is_not':\n case 'not_equals':\n case 'is_not_equal_to':\n return '!=';\n case 'is_greater_than':\n return '>';\n case 'is_greater_than_or_equal_to':\n return '>=';\n case 'is_less_than':\n return '<';\n case 'is_less_than_or_equal_to':\n return '<=';\n case 'is_blank':\n return 'IS NULL';\n case 'is_not_blank':\n return 'IS NOT NULL';\n default:\n return '=';\n }\n }\n\n static validateRequiredField<T>(\n value: T | undefined | null,\n fieldName: string,\n context?: string,\n ): T {\n if (value === undefined || value === null) {\n const contextMsg = context ? ` in ${context}` : '';\n throw new Error(`Required field '${fieldName}' is missing${contextMsg}`);\n }\n return value;\n }\n\n static safeGet<T>(\n obj: Record<string, unknown> | undefined,\n key: string,\n defaultValue?: T,\n ): T | undefined {\n if (!obj || !(key in obj)) {\n return defaultValue;\n }\n return obj[key] as T;\n }\n\n static extractDimensionsFromOptions(options: EpmQueryBuilderOptions): string[] {\n const rowDimensions = this.buildDimensionReference(options.rows, options);\n const columnDimensions = this.buildDimensionReference(options.columns, options);\n return [...rowDimensions, ...columnDimensions];\n }\n\n static extractMeasuresFromOptions(options: EpmQueryBuilderOptions): unknown[] {\n return options.values || [];\n }\n\n static getSelectedColumnsFromOptions(options: EpmQueryBuilderOptions): string[] {\n if (options.rows?.length) {\n return options.rows.map((row) => row.columnName);\n }\n return options.selectedColumns || [];\n }\n\n static hasDimensionsInOptions(options: EpmQueryBuilderOptions): boolean {\n const rowCount = options.rows?.length || 0;\n const columnCount = options.columns?.length || 0;\n return rowCount + columnCount > 0;\n }\n\n static hasMeasuresInOptions(options: EpmQueryBuilderOptions): boolean {\n return (options.values?.length || 0) > 0;\n }\n\n static shouldGenerateRollupForOptions(options: EpmQueryBuilderOptions): boolean {\n return !options.skipRollup && this.hasDimensionsInOptions(options);\n }\n\n static shouldGenerateAnalyticalQueryForOptions(options: EpmQueryBuilderOptions): boolean {\n return (\n this.hasMeasuresInOptions(options) ||\n (this.shouldGenerateRollupForOptions(options) && this.hasMeasuresInOptions(options))\n );\n }\n\n static formatColumnNameWithFallbackString(columnName: string, columnId: string): string {\n const actualColumnId = this.extractColumnIdFromHierarchy(columnId);\n return columnName || actualColumnId;\n }\n\n static buildBasicGroupByClauseForOptions(options: EpmQueryBuilderOptions): string {\n const dimensions = this.extractDimensionsFromOptions(options);\n return dimensions.length > 0 ? `GROUP BY ${dimensions.join(', ')}` : '';\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static generateConcatenatedIdMeasure(dimensionMappings: Record<string, any>): [string, string] {\n if (!dimensionMappings || Object.keys(dimensionMappings).length === 0) {\n return ['', ''];\n }\n\n const targetTable = Object.keys(dimensionMappings)[0];\n const mappings = dimensionMappings[targetTable];\n\n if (!mappings || mappings.length === 0) {\n return ['', targetTable];\n }\n\n const concatenatedColumns = mappings\n .map(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (mapping: any) => `COALESCE(\"${mapping.targetTable}\".\"${mapping.targetField}\", '')`,\n )\n .join(\" || '|' || \");\n\n const measure = `MEASURE '${targetTable}'[CONCATENATED_IDS] = ${concatenatedColumns}`;\n\n return [measure, targetTable];\n }\n}\n","// shared sql helpers used by all dialects\nimport {\n EpmQueryBuilderOptions,\n MeasureConfig,\n RowColumnConfig,\n OrderByConfig,\n} from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\n\nexport abstract class BaseSqlBuilder {\n protected options: EpmQueryBuilderOptions;\n\n constructor(options: EpmQueryBuilderOptions) {\n this.options = options;\n }\n\n protected buildSelectClause(items: string[]): string {\n if (items.length === 0) {\n return 'SELECT 1';\n }\n return `SELECT ${items.join(', ')}`;\n }\n\n protected buildFromClause(tableName: string, joins?: string[]): string {\n let fromClause = `FROM ${tableName}`;\n\n if (joins?.length) {\n fromClause += ` ${joins.join(' ')}`;\n }\n\n return fromClause;\n }\n\n protected buildWhereClause(conditions: string[]): string {\n const validConditions = conditions.filter((c) => c && c.trim());\n\n if (validConditions.length === 0) {\n return '';\n }\n\n const combinedCondition = BaseUtilities.combineConditions(validConditions, 'AND');\n return `WHERE ${combinedCondition}`;\n }\n\n protected buildGroupByClause(columns: string[]): string {\n if (columns.length === 0) {\n return '';\n }\n\n return `GROUP BY ${columns.join(', ')}`;\n }\n\n protected buildHavingClause(conditions: string[]): string {\n const validConditions = conditions.filter((c) => c && c.trim());\n\n if (validConditions.length === 0) {\n return '';\n }\n\n const combinedCondition = BaseUtilities.combineConditions(validConditions, 'AND');\n return `HAVING ${combinedCondition}`;\n }\n\n protected buildOrderByClause(orderItems: OrderByConfig[]): string {\n if (!orderItems?.length) {\n return '';\n }\n\n const clauses = orderItems.map((item) => {\n const direction = this.mapSortDirection(item.type);\n const column = this.resolveOrderByColumn(item);\n return `${column} ${direction}`;\n });\n\n return `ORDER BY ${clauses.join(', ')}`;\n }\n\n protected buildLimitClause(limit?: number, offset?: number): string {\n return BaseUtilities.buildLimitClause(offset, limit);\n }\n\n protected buildDistinctClause(columns: string[]): string {\n return `SELECT DISTINCT ${columns.join(', ')}`;\n }\n\n protected buildCountClause(distinctColumn?: string): string {\n if (distinctColumn) {\n return `SELECT COUNT(DISTINCT ${distinctColumn})`;\n }\n return 'SELECT COUNT(*)';\n }\n\n protected buildCTEClause(ctes: string[]): string {\n if (ctes.length === 0) return '';\n return `WITH ${ctes.join(',\\n')}`;\n }\n\n protected buildUnionClause(\n queries: string[],\n unionType: 'UNION' | 'UNION ALL' = 'UNION',\n ): string {\n if (queries.length < 2) {\n return queries[0] || '';\n }\n return queries.join(` ${unionType} `);\n }\n\n protected buildCompleteQuery(parts: {\n cte?: string;\n select: string;\n from: string;\n where?: string;\n groupBy?: string;\n having?: string;\n orderBy?: string;\n limit?: string;\n }): string {\n const queryParts = [\n parts.cte,\n parts.select,\n parts.from,\n parts.where,\n parts.groupBy,\n parts.having,\n parts.orderBy,\n parts.limit,\n ].filter((part) => part && part.trim());\n\n const joined = queryParts.join('\\n');\n return joined.replace(/\\n{2,}/g, '\\n');\n }\n\n protected extractMeasures(): MeasureConfig[] {\n return this.options.values || [];\n }\n\n protected formatColumnReference(config: RowColumnConfig): string {\n return BaseUtilities.buildColumnReference(\n BaseUtilities.getEffectiveTableName(config, this.options),\n BaseUtilities.getEffectiveColumnName(config),\n );\n }\n\n protected formatColumnWithAlias(config: RowColumnConfig): string {\n const columnRef = this.formatColumnReference(config);\n return BaseUtilities.formatColumnWithAlias(columnRef, config.label || config.id);\n }\n\n protected getDefaultTableName(): string {\n return BaseUtilities.getDefaultTableName(this.options);\n }\n\n protected extractUniqueTableNames(): string[] {\n return BaseUtilities.extractUniqueTableNames(this.options);\n }\n\n protected hasDimensions(): boolean {\n return Boolean(this.options.rows?.length || this.options.columns?.length);\n }\n\n protected hasMeasures(): boolean {\n return Boolean(this.options.values?.length);\n }\n\n protected shouldGenerateSubquery(): boolean {\n return this.hasMeasures() && this.hasDimensions();\n }\n\n protected abstract mapSortDirection(direction?: string): 'ASC' | 'DESC';\n protected abstract resolveOrderByColumn(orderBy: OrderByConfig): string;\n protected abstract buildJoinClause(joinType: string, table: string, condition: string): string;\n}\n","// base class: common helpers for dialect query builders\nimport {\n EpmQueryBuilderOptions,\n OrderByConfig,\n} from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\nimport { BaseSqlBuilder } from '@epm-query-builder/base/BaseSqlBuilder';\n\nexport abstract class BaseQueryBuilder extends BaseSqlBuilder {\n constructor(options: EpmQueryBuilderOptions) {\n super(options);\n }\n\n abstract generateQuery(): string;\n\n protected shouldGenerateAnalyticalQuery(): boolean {\n return BaseUtilities.shouldGenerateAnalyticalQueryForOptions(this.options);\n }\n\n protected shouldGenerateRollup(): boolean {\n return BaseUtilities.shouldGenerateRollupForOptions(this.options);\n }\n\n protected hasComplexFilters(): boolean {\n return Boolean(this.options.superFilters?.children?.length);\n }\n\n protected buildBasicGroupByClause(): string {\n return BaseUtilities.buildBasicGroupByClauseForOptions(this.options);\n }\n\n protected mapSortDirection(direction?: string): 'ASC' | 'DESC' {\n return direction?.toUpperCase() === 'DESC' ? 'DESC' : 'ASC';\n }\n\n protected resolveOrderByColumn(orderBy: OrderByConfig): string {\n if (orderBy.isColumnPresentInOutput) {\n if (orderBy.aggregationType) {\n return `\"${orderBy.aggregationType}__${orderBy.tableName}[${orderBy.columnName}]\"`;\n }\n return `\"${orderBy.tableName}[${orderBy.columnName}]\"`;\n }\n\n const tableName = orderBy.tableName || '';\n return `${tableName}.${orderBy.columnName}`;\n }\n\n protected buildJoinClause(joinType: string, table: string, condition: string): string {\n return `${joinType} ${table} ON ${condition}`;\n }\n}\n","import {\n FilterConfig,\n RangeFilter,\n RankingConfig,\n} from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\nimport * as ColumnRefUtils from '@epm-query-builder/base/ColumnRefUtils';\n\nexport class SharedFilterBuilder {\n private static mapToCanonicalOperator(op: string): string {\n const norm = (op || '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+|_+$/g, '');\n switch (norm) {\n case 'contains':\n return 'CONTAINS';\n case 'does_not_contain':\n case 'does_not_contains':\n case 'not_contains':\n case 'not_contain':\n return 'DOES_NOT_CONTAIN';\n case 'starts_with':\n return 'STARTS_WITH';\n case 'does_not_start_with':\n case 'does_not_starts_with':\n case 'not_starts_with':\n case 'not_start_with':\n return 'DOES_NOT_START_WITH';\n case 'ends_with':\n return 'ENDS_WITH';\n case 'does_not_end_with':\n case 'not_ends_with':\n case 'not_end_with':\n return 'DOES_NOT_END_WITH';\n case 'equals':\n case 'is_equal_to':\n case 'is':\n return 'EQUALS';\n case 'not_equals':\n case 'is_not_equal_to':\n case 'is_not':\n return 'NOT_EQUALS';\n case 'is_blank':\n case 'blank':\n return 'IS_BLANK';\n case 'is_not_blank':\n case 'not_blank':\n return 'IS_NOT_BLANK';\n default:\n return norm.toUpperCase();\n }\n }\n static buildRangeCondition(column: string, range: RangeFilter): string {\n const parts: string[] = [];\n\n if (range.from !== undefined && range.fromCondition) {\n parts.push(this.buildRangeOperatorCondition(column, range.fromCondition, range.from));\n }\n\n if (range.to !== undefined && range.toCondition) {\n parts.push(this.buildRangeOperatorCondition(column, range.toCondition, range.to));\n }\n\n if (range.operator && range.value !== undefined) {\n parts.push(this.buildRangeOperatorCondition(column, range.operator, range.value));\n }\n\n if (parts.length === 0) return '';\n\n const joiner = (range.logicalOperator || 'AND').toUpperCase() === 'OR' ? 'OR' : 'AND';\n return parts.length === 1 ? parts[0] : `(${parts.join(` ${joiner} `)})`;\n }\n\n private static buildRangeOperatorCondition(\n column: string,\n operator: string,\n value: string | number | boolean,\n ): string {\n const operatorCode = this.mapToCanonicalOperator(operator);\n\n const escapedValue = String(value).replace(/'/g, \"''\");\n\n switch (operatorCode) {\n case 'CONTAINS':\n return `LOWER(${column}) LIKE LOWER('%${escapedValue}%')`;\n case 'DOES_NOT_CONTAIN':\n case 'NOT_CONTAINS':\n case 'NOT CONTAINS':\n return `LOWER(${column}) NOT LIKE LOWER('%${escapedValue}%')`;\n case 'STARTS_WITH':\n return `LOWER(${column}) LIKE LOWER('${escapedValue}%')`;\n case 'DOES_NOT_START_WITH':\n case 'NOT_STARTS_WITH':\n case 'NOT STARTS WITH':\n return `LOWER(${column}) NOT LIKE LOWER('${escapedValue}%')`;\n case 'ENDS_WITH':\n return `LOWER(${column}) LIKE LOWER('%${escapedValue}')`;\n case 'DOES_NOT_END_WITH':\n case 'NOT_ENDS_WITH':\n case 'NOT ENDS WITH':\n return `LOWER(${column}) NOT LIKE LOWER('%${escapedValue}')`;\n case 'EQUALS':\n case 'IS_EQUAL_TO':\n case 'IS':\n return BaseUtilities.buildFilterConditionForOperator(column, 'IS_EQUAL_TO', value);\n case 'NOT_EQUALS':\n case 'IS_NOT_EQUAL_TO':\n case 'IS_NOT':\n return BaseUtilities.buildFilterConditionForOperator(column, 'IS_NOT_EQUAL_TO', value);\n case 'IS_GREATER_THAN':\n return BaseUtilities.buildFilterConditionForOperator(column, 'IS_GREATER_THAN', value);\n case 'IS_GREATER_THAN_OR_EQUAL_TO':\n return BaseUtilities.buildFilterConditionForOperator(\n column,\n 'IS_GREATER_THAN_OR_EQUAL_TO',\n value,\n );\n case 'IS_LESS_THAN':\n return BaseUtilities.buildFilterConditionForOperator(column, 'IS_LESS_THAN', value);\n case 'IS_LESS_THAN_OR_EQUAL_TO':\n return BaseUtilities.buildFilterConditionForOperator(\n column,\n 'IS_LESS_THAN_OR_EQUAL_TO',\n value,\n );\n case 'IS_BLANK':\n return BaseUtilities.buildFilterConditionForOperator(column, 'IS_BLANK', '');\n case 'IS_NOT_BLANK':\n return BaseUtilities.buildFilterConditionForOperator(column, 'IS_NOT_BLANK', '');\n case 'IS_EMPTY':\n return `TRIM(${column}) = ''`;\n case 'IS_NOT_EMPTY':\n return `TRIM(${column}) != ''`;\n default:\n return `LOWER(${column}) LIKE LOWER('%${escapedValue}%')`;\n }\n }\n\n static buildRangeFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.rangeFilter?.length) {\n return '';\n }\n\n const column = this.getColumnReference(filter);\n const conditions = filter.rangeFilter\n .map((range) => this.buildRangeCondition(column, range))\n .filter((condition) => condition);\n\n return BaseUtilities.combineConditions(\n conditions,\n (filter.logicalOperator as 'AND' | 'OR') || 'AND',\n );\n }\n\n static buildValuesFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.valuesFilter?.length) {\n return '';\n }\n\n const column = this.getColumnReference(filter);\n const values = filter.valuesFilter\n .flatMap((vf) => (Array.isArray(vf.id) ? vf.id : [vf.id]))\n .filter((v) => v !== undefined);\n\n if (values.length === 0) return '';\n\n const operator =\n filter.valuesFilterApplicationType?.toUpperCase() === 'EXCLUDE' ? 'NOT IN' : 'IN';\n const valueList = values.map((v) => BaseUtilities.formatValue(v.toString())).join(',');\n\n return `${column} ${operator} (${valueList})`;\n }\n\n static buildRankingFilter(filter: FilterConfig): string {\n const rankingConfigs =\n filter.rankingFilter || (filter.rankingConfig ? [filter.rankingConfig] : []);\n\n if (!rankingConfigs.length || !filter.columnNames?.length) {\n return '';\n }\n\n const conditions = rankingConfigs.map((rankingConfig) =>\n this.buildSingleRankingCondition(filter, rankingConfig),\n );\n\n return BaseUtilities.combineConditions(\n conditions,\n (filter.logicalOperator as 'AND' | 'OR') || 'AND',\n );\n }\n\n private static buildSingleRankingCondition(\n filter: FilterConfig,\n rankingConfig: RankingConfig,\n ): string {\n const column = filter.columnNames![0];\n const tableName = filter.tableNames?.[0] || rankingConfig.rankByTableName || '';\n\n const rankByColumnId =\n rankingConfig.rankByColumnId ||\n `${rankingConfig.rankByTableName || ''}[${rankingConfig.rankByColumnName || column}]`;\n const actualColumnId = BaseUtilities.extractColumnIdFromHierarchy(rankByColumnId);\n\n const rankByColumnRef = tableName\n ? BaseUtilities.buildColumnReference(tableName, actualColumnId)\n : `\"${actualColumnId}\"`;\n\n const aggregationType = BaseUtilities.mapAggregationType(\n rankingConfig.rankByAggregationType || 'SUM',\n );\n const orderDirection = rankingConfig.type === 'TOP' ? 'DESC' : 'ASC';\n\n const measureExpression =\n aggregationType !== 'NONE' ? `${aggregationType}(${rankByColumnRef})` : rankByColumnRef;\n\n if (rankingConfig.isPercentage) {\n const percentileValue = rankingConfig.value / 100;\n return `PERCENT_RANK() OVER (ORDER BY ${measureExpression} ${orderDirection}) <= ${percentileValue}`;\n } else {\n return `ROW_NUMBER() OVER (ORDER BY ${measureExpression} ${orderDirection}) <= ${rankingConfig.value}`;\n }\n }\n\n static buildSearchFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.searchConditions?.length) {\n return '';\n }\n\n const column = this.getColumnReference(filter);\n const conditions = filter.searchConditions.map((condition) => {\n const operatorCode = this.mapToCanonicalOperator(condition.operator || '');\n const rawValue = String(condition.value ?? '');\n const escapedValue = rawValue.replace(/'/g, \"''\");\n\n switch (operatorCode) {\n case 'CONTAINS':\n return `LOWER(${column}) LIKE LOWER('%${escapedValue}%')`;\n case 'DOES_NOT_CONTAIN':\n return `LOWER(${column}) NOT LIKE LOWER('%${escapedValue}%')`;\n case 'STARTS_WITH':\n return `LOWER(${column}) LIKE LOWER('${escapedValue}%')`;\n case 'DOES_NOT_START_WITH':\n return `LOWER(${column}) NOT LIKE LOWER('${escapedValue}%')`;\n case 'ENDS_WITH':\n return `LOWER(${column}) LIKE LOWER('%${escapedValue}')`;\n case 'DOES_NOT_END_WITH':\n return `LOWER(${column}) NOT LIKE LOWER('%${escapedValue}')`;\n case 'EQUALS':\n return `${column} = ${BaseUtilities.formatValue(rawValue)}`;\n case 'NOT_EQUALS':\n return `${column} != ${BaseUtilities.formatValue(rawValue)}`;\n case 'IS_BLANK':\n return `${column} IS NULL`;\n case 'IS_NOT_BLANK':\n return `${column} IS NOT NULL`;\n case 'IS_EMPTY':\n return `TRIM(${column}) = ''`;\n case 'IS_NOT_EMPTY':\n return `TRIM(${column}) != ''`;\n default:\n return `LOWER(${column}) LIKE LOWER('%${escapedValue}%')`;\n }\n });\n\n return BaseUtilities.combineConditions(conditions, 'AND');\n }\n\n static buildBlankFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.blankFilterConfig) {\n return '';\n }\n\n const column = this.getColumnReference(filter);\n const blankConfig = filter.blankFilterConfig;\n\n if (blankConfig.operator === 'IS_BLANK') {\n if (blankConfig.treatEmptyStringAsBlank) {\n return `(${column} IS NULL OR TRIM(${column}) = '')`;\n } else {\n return `${column} IS NULL`;\n }\n } else {\n if (blankConfig.treatEmptyStringAsBlank) {\n return `(${column} IS NOT NULL AND TRIM(${column}) != '')`;\n } else {\n return `${column} IS NOT NULL`;\n }\n }\n }\n\n static buildTupleFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.valuesFilter?.length) {\n return '';\n }\n\n const columns = filter.columnNames;\n const tupleConditions: string[] = [];\n\n filter.valuesFilter.forEach((valueItem) => {\n if (Array.isArray(valueItem.id)) {\n const tupleValues = valueItem.id\n .map((id, index) => `${columns[index]} = ${BaseUtilities.formatValue(id.toString())}`)\n .join(' AND ');\n tupleConditions.push(`(${tupleValues})`);\n }\n });\n\n if (tupleConditions.length === 0) return '';\n\n const isInclude = filter.valuesFilterApplicationType === 'INCLUDE';\n if (tupleConditions.length === 1) {\n return tupleConditions[0];\n }\n const joiner = isInclude ? ' OR ' : ' AND NOT ';\n const combined = tupleConditions.join(joiner);\n return `(${combined})`;\n }\n\n static buildRelativePeriodFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.relativePeriodFilter) {\n return '';\n }\n\n const column = this.getColumnReference(filter);\n return this.buildRelativePeriodCondition(column, filter.relativePeriodFilter);\n }\n\n static buildDateHierarchyFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.dateHierarchyConfig) {\n return '';\n }\n\n const tableName = filter.tableNames?.[0];\n const column = BaseUtilities.buildColumnReference(tableName, filter.columnNames[0]);\n const hierarchyConfig = filter.dateHierarchyConfig;\n\n if (!hierarchyConfig.level) {\n return `${column} IS NOT NULL`;\n }\n\n if (!hierarchyConfig.values?.length) {\n let hierarchyFunction: string;\n switch (hierarchyConfig.level) {\n case 'YEAR':\n hierarchyFunction = `EXTRACT(YEAR FROM ${column})`;\n break;\n case 'QUARTER':\n hierarchyFunction = `EXTRACT(QUARTER FROM ${column})`;\n break;\n case 'MONTH':\n hierarchyFunction = `EXTRACT(MONTH FROM ${column})`;\n break;\n case 'DAY':\n hierarchyFunction = `EXTRACT(DAY FROM ${column})`;\n break;\n case 'WEEK':\n hierarchyFunction = `EXTRACT(WEEK FROM ${column})`;\n break;\n case 'DAYOFWEEK':\n hierarchyFunction = `EXTRACT(DAYOFWEEK FROM ${column})`;\n break;\n default:\n return `${column} IS NOT NULL`;\n }\n return `${hierarchyFunction} IS NOT NULL`;\n }\n\n let hierarchyFunction: string;\n switch (hierarchyConfig.level) {\n case 'YEAR':\n hierarchyFunction = `EXTRACT(YEAR FROM ${column})`;\n break;\n case 'QUARTER':\n hierarchyFunction = `EXTRACT(QUARTER FROM ${column})`;\n break;\n case 'MONTH':\n hierarchyFunction = `EXTRACT(MONTH FROM ${column})`;\n break;\n case 'DAY':\n hierarchyFunction = `EXTRACT(DAY FROM ${column})`;\n break;\n case 'WEEK':\n hierarchyFunction = `EXTRACT(WEEK FROM ${column})`;\n break;\n case 'DAYOFWEEK':\n hierarchyFunction = `EXTRACT(DAYOFWEEK FROM ${column})`;\n break;\n default:\n return `${column} IS NOT NULL`;\n }\n\n if (hierarchyConfig.values.length === 1) {\n return `${hierarchyFunction} = ${hierarchyConfig.values[0]}`;\n } else {\n const valuesList = hierarchyConfig.values.join(', ');\n return `${hierarchyFunction} IN (${valuesList})`;\n }\n }\n\n static buildFieldParameterFilter(filter: FilterConfig): string {\n if (!filter.fieldParameterMapping) {\n return '';\n }\n\n const mapping = filter.fieldParameterMapping;\n if (!mapping.targetField) {\n return '';\n }\n\n const tableName = mapping.targetTable;\n const column = BaseUtilities.buildColumnReference(tableName, mapping.targetField);\n\n if (mapping.filterValues?.length) {\n if (mapping.filterValues.length === 1) {\n return `${column} = '${mapping.filterValues[0]}'`;\n } else {\n const valuesList = mapping.filterValues.map((v) => `'${v}'`).join(', ');\n return `${column} IN (${valuesList})`;\n }\n }\n\n return `${column} IS NOT NULL`;\n }\n\n static buildDateFilter(filter: FilterConfig): string {\n if (!filter.dateRangeFilter?.length) return '';\n\n const column = this.getColumnReference(filter);\n const conditions = filter.dateRangeFilter.map((dateRange) => {\n const startDate = BaseUtilities.stringToDate(dateRange.startDate);\n const endDate = BaseUtilities.stringToDate(dateRange.endDate);\n return `${column} BETWEEN ${startDate} AND ${endDate}`;\n });\n\n return BaseUtilities.combineConditions(conditions, 'AND');\n }\n\n private static getColumnReference(filter: FilterConfig): string {\n const columnId = filter.columnIds?.[0];\n const columnFromName = filter.columnNames?.[0];\n const tableName =\n filter.tableNames?.[0] ||\n (columnId ? ColumnRefUtils.getTableNameFromId(columnId) || undefined : undefined);\n\n if (columnId) {\n const actualId = BaseUtilities.extractColumnIdFromHierarchy(columnId);\n const columnOnly = ColumnRefUtils.getColumnNameFromId(actualId);\n return tableName\n ? BaseUtilities.buildColumnReference(tableName, columnOnly)\n : `\"${columnOnly}\"`;\n }\n\n if (columnFromName) {\n return tableName\n ? BaseUtilities.buildColumnReference(tableName, columnFromName)\n : `\"${columnFromName}\"`;\n }\n return '';\n }\n\n static buildFilterCondition(filter: FilterConfig): string {\n if (!filter) return '';\n\n switch (filter.filterType?.toUpperCase()) {\n case 'VALUES':\n return this.buildValuesFilter(filter);\n case 'RANGE':\n return this.buildRangeFilter(filter);\n case 'DATE':\n case 'DATE_RANGE':\n return this.buildDateFilter(filter);\n case 'RANKING':\n return this.buildRankingFilter(filter);\n case 'SEARCH':\n return this.buildSearchFilter(filter);\n case 'BLANK':\n return this.buildBlankFilter(filter);\n case 'TUPLE':\n return this.buildTupleFilter(filter);\n case 'RELATIVE_PERIOD':\n return this.buildRelativePeriodFilter(filter);\n case 'DATE_HIERARCHY':\n return this.buildDateHierarchyFilter(filter);\n case 'FIELD_PARAMETER':\n return this.buildFieldParameterFilter(filter);\n default:\n return '';\n }\n }\n\n static buildRelativePeriodCondition(\n column: string,\n config: { duration: number; period: string; relativeDateFilter: string },\n ): string {\n const now = 'CURRENT_DATE';\n const duration = config.duration;\n const period = config.period;\n\n switch (config.relativeDateFilter) {\n case 'IS_IN_THE_LAST':\n switch (period) {\n case 'DAYS':\n return `${column} >= ${now} - INTERVAL '${duration} days'`;\n case 'WEEKS':\n return `${column} >= ${now} - INTERVAL '${duration} weeks'`;\n case 'MONTHS':\n return `${column} >= ${now} - INTERVAL '${duration} months'`;\n case 'YEARS':\n return `${column} >= ${now} - INTERVAL '${duration} years'`;\n default:\n return `${column} >= ${now} - INTERVAL '${duration} days'`;\n }\n case 'IS_IN_THE_NEXT':\n switch (period) {\n case 'DAYS':\n return `${column} <= ${now} + INTERVAL '${duration} days'`;\n case 'WEEKS':\n return `${column} <= ${now} + INTERVAL '${duration} weeks'`;\n case 'MONTHS':\n return `${column} <= ${now} + INTERVAL '${duration} months'`;\n case 'YEARS':\n return `${column} <= ${now} + INTERVAL '${duration} years'`;\n default:\n return `${column} <= ${now} + INTERVAL '${duration} days'`;\n }\n case 'IS_IN_THIS':\n switch (period) {\n case 'DAYS':\n return `DATE_TRUNC('day', ${column}) = DATE_TRUNC('day', ${now})`;\n case 'WEEKS':\n return `DATE_TRUNC('week', ${column}) = DATE_TRUNC('week', ${now})`;\n case 'MONTHS':\n return `DATE_TRUNC('month', ${column}) = DATE_TRUNC('month', ${now})`;\n case 'YEARS':\n return `DATE_TRUNC('year', ${column}) = DATE_TRUNC('year', ${now})`;\n default:\n return `DATE_TRUNC('day', ${column}) = DATE_TRUNC('day', ${now})`;\n }\n default:\n return `${column} = ${now}`;\n }\n }\n}\n","export abstract class QueryBuilderError extends Error {\n abstract readonly code: string;\n\n constructor(\n message: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = this.constructor.name;\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\nexport class InvalidConfigurationError extends QueryBuilderError {\n readonly code = 'INVALID_CONFIGURATION';\n\n constructor(message: string, details?: Record<string, unknown>) {\n super(`Configuration Error: ${message}`, details);\n }\n}\n\nexport class FilterValidationError extends QueryBuilderError {\n readonly code = 'FILTER_VALIDATION_ERROR';\n\n constructor(filterType: string, message: string, details?: Record<string, unknown>) {\n super(`Filter Validation Error (${filterType}): ${message}`, details);\n }\n}\n\nexport class MeasureValidationError extends QueryBuilderError {\n readonly code = 'MEASURE_VALIDATION_ERROR';\n\n constructor(measureName: string, message: string, details?: Record<string, unknown>) {\n super(`Measure Validation Error (${measureName}): ${message}`, details);\n }\n}\n\nexport class PaginationError extends QueryBuilderError {\n readonly code = 'PAGINATION_ERROR';\n\n constructor(command: string, message: string, details?: Record<string, unknown>) {\n super(`Pagination Error (${command}): ${message}`, details);\n }\n}\n\nexport class QueryGenerationError extends QueryBuilderError {\n readonly code = 'QUERY_GENERATION_ERROR';\n\n constructor(message: string, details?: Record<string, unknown>) {\n super(`Query Generation Error: ${message}`, details);\n }\n}\n\nexport class TableNotFoundError extends QueryBuilderError {\n readonly code = 'TABLE_NOT_FOUND';\n\n constructor(tableName?: string, details?: Record<string, unknown>) {\n super(\n tableName\n ? `Table not found: ${tableName}`\n : 'No table name found in configuration. Please specify tableName in rows, columns, or values.',\n details,\n );\n }\n}\n","import {\n FilterConfig,\n SuperFilterConfig,\n SuperFilterChild,\n MeasureFilterConfig,\n RangeFilter,\n EpmQueryBuilderOptions,\n} from '@epm-query-builder/types/query-builder-types';\nimport { SharedFilterBuilder } from '@epm-query-builder/base/SharedFilterBuilder';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\nimport { FilterValidationError } from '@epm-query-builder/errors/QueryBuilderErrors';\n\nexport class BaseSuperFilterBuilder {\n protected options: EpmQueryBuilderOptions;\n\n constructor(options: EpmQueryBuilderOptions) {\n this.options = options;\n }\n\n buildWhereClause(): string {\n if (!this.options.superFilters) {\n return '';\n }\n\n return this.buildNestedFilterGroups(this.options.superFilters);\n }\n\n protected buildNestedFilterGroups(superFilters: SuperFilterConfig): string {\n if (!superFilters.children?.length) {\n return '';\n }\n\n const childConditions = superFilters.children\n .map((child) => this.buildSuperFilterChild(child))\n .filter((condition) => condition);\n\n if (childConditions.length === 0) {\n return '';\n }\n\n const operator = superFilters.condition?.toUpperCase() === 'OR' ? ' OR ' : ' AND ';\n return childConditions.length === 1\n ? childConditions[0]\n : `(${childConditions.join(operator)})`;\n }\n\n protected buildSuperFilterChild(child: SuperFilterChild): string {\n if (child.isGroup && child.children) {\n const nestedGroup: SuperFilterConfig = {\n groupId: child.groupId || 'nested',\n groupLabel: child.groupLabel || 'nested',\n condition: child.condition || 'AND',\n children: child.children,\n };\n return this.buildNestedFilterGroups(nestedGroup);\n } else if (child.isFilter && child.filters) {\n return this.buildFilterCondition(child.filters);\n } else if (child.filters) {\n return this.buildFilterCondition(child.filters);\n }\n return '';\n }\n\n protected buildFilterCondition(filter: FilterConfig): string {\n if (!filter) return '';\n\n if (filter.filterType?.toUpperCase() === 'MEASURE') {\n return this.buildMeasureFilter();\n }\n\n if (\n filter.filterType?.toUpperCase() === 'RANGE' &&\n Array.isArray(filter.aggregationType) &&\n filter.aggregationType.length > 0\n ) {\n return '';\n }\n return SharedFilterBuilder.buildFilterCondition(filter);\n }\n\n protected buildValuesFilter(filter: FilterConfig): string {\n if (filter.isCrossHighlight === true) {\n return this.buildCrossHighlightFilter(filter);\n }\n return SharedFilterBuilder.buildValuesFilter(filter);\n }\n\n protected buildRangeFilter(filter: FilterConfig): string {\n return SharedFilterBuilder.buildRangeFilter(filter);\n }\n\n protected buildDateFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.dateRangeFilter?.length) {\n return '';\n }\n\n const column = filter.columnNames[0];\n const dateRange = filter.dateRangeFilter[0];\n\n const startDate = BaseUtilities.formatValue(dateRange.startDate);\n const endDate = BaseUtilities.formatValue(dateRange.endDate);\n\n return `${column} BETWEEN ${startDate} AND ${endDate}`;\n }\n\n protected buildMeasureFilter(): string {\n const measureFilters = this.extractMeasureFilters();\n if (measureFilters.length === 0) {\n return '';\n }\n\n const conditions = measureFilters.map((filter) => this.buildMeasureCondition(filter));\n return BaseUtilities.combineConditions(\n conditions.filter((c) => c),\n 'AND',\n );\n }\n\n protected extractMeasureFilters(): MeasureFilterConfig[] {\n if (!this.options.superFilters?.children) {\n return [];\n }\n\n const measureFilters: MeasureFilterConfig[] = [];\n\n this.extractMeasureFiltersRecursively(this.options.superFilters.children, measureFilters);\n return measureFilters;\n }\n\n private extractMeasureFiltersRecursively(\n children: SuperFilterChild[],\n measureFilters: MeasureFilterConfig[],\n ): void {\n children.forEach((child) => {\n if (child.filters) {\n const filter = child.filters;\n const isMeasureFilterType = filter.filterType === 'MEASURE';\n const isRangeWithAggregation =\n filter.filterType === 'RANGE' &&\n Array.isArray(filter.aggregationType) &&\n filter.aggregationType.length > 0;\n\n if (isMeasureFilterType || isRangeWithAggregation) {\n if (filter.rangeFilter?.length) {\n filter.rangeFilter.forEach((range: RangeFilter) => {\n const hasFrom =\n range.from !== undefined && range.from !== null && range.fromCondition;\n const hasTo = range.to !== undefined && range.to !== null && range.toCondition;\n const hasLegacyOperator =\n range.operator &&\n range.value !== undefined &&\n range.value !== null &&\n !hasFrom &&\n !hasTo;\n\n if (hasFrom) {\n measureFilters.push({\n id: `${filter.tableNames?.[0]}.${filter.columnNames?.[0]}`,\n columnName: filter.columnNames?.[0] || '',\n tableName: filter.tableNames?.[0] || '',\n aggregationType: filter.aggregationType?.[0],\n operator: this.normalizeRangeOperator(range.fromCondition),\n value: range.from,\n dataType: filter.dataType?.[0] || 'string',\n logicalOperator:\n hasTo && range.logicalOperator\n ? range.logicalOperator\n : filter.logicalOperator || 'AND',\n });\n }\n\n if (hasTo) {\n measureFilters.push({\n id: `${filter.tableNames?.[0]}.${filter.columnNames?.[0]}`,\n columnName: filter.columnNames?.[0] || '',\n tableName: filter.tableNames?.[0] || '',\n aggregationType: filter.aggregationType?.[0],\n operator: this.normalizeRangeOperator(range.toCondition),\n value: range.to,\n dataType: filter.dataType?.[0] || 'string',\n logicalOperator:\n hasFrom && range.logicalOperator\n ? range.logicalOperator\n : filter.logicalOperator || 'AND',\n });\n }\n\n if (hasLegacyOperator) {\n measureFilters.push({\n id: `${filter.tableNames?.[0]}.${filter.columnNames?.[0]}`,\n columnName: filter.columnNames?.[0] || '',\n tableName: filter.tableNames?.[0] || '',\n aggregationType: filter.aggregationType?.[0],\n operator: this.normalizeRangeOperator(range.operator),\n value: range.value,\n dataType: filter.dataType?.[0] || 'string',\n logicalOperator: filter.logicalOperator || 'AND',\n });\n }\n });\n }\n }\n }\n\n if (child.children) {\n this.extractMeasureFiltersRecursively(child.children, measureFilters);\n }\n });\n }\n\n private normalizeRangeOperator(operator: string): string {\n if (!operator) return 'IS_EQUAL_TO';\n\n const normalized = operator.toUpperCase().trim();\n\n switch (normalized) {\n case 'IS':\n case 'EQUALS':\n return 'IS_EQUAL_TO';\n case 'IS_NOT':\n case 'NOT_EQUALS':\n return 'IS_NOT_EQUAL_TO';\n case 'IS_GREATER_THAN':\n return 'IS_GREATER_THAN';\n case 'IS_GREATER_THAN_OR_EQUAL_TO':\n case 'IS_ON_OR_AFTER':\n return 'IS_GREATER_THAN_OR_EQUAL_TO';\n case 'IS_LESS_THAN':\n case 'IS_BEFORE':\n return 'IS_LESS_THAN';\n case 'IS_LESS_THAN_OR_EQUAL_TO':\n case 'IS_ON_OR_BEFORE':\n return 'IS_LESS_THAN_OR_EQUAL_TO';\n case 'IS_BLANK':\n return 'IS_BLANK';\n case 'IS_NOT_BLANK':\n return 'IS_NOT_BLANK';\n default:\n return normalized.includes('_') ? normalized : 'IS_EQUAL_TO';\n }\n }\n\n protected buildMeasureCondition(filter: MeasureFilterConfig): string {\n const measureExpr = filter.aggregationType\n ? `${filter.aggregationType.toUpperCase()}(\"${filter.tableName}\".\"${filter.columnName}\")`\n : `\"${filter.tableName}\".\"${filter.columnName}\"`;\n\n const value = filter.dataType === 'string' ? `'${filter.value}'` : filter.value;\n\n switch (filter.operator.toUpperCase()) {\n case 'IS':\n case 'IS_EQUAL_TO':\n return `${measureExpr} = ${value}`;\n case 'IS_NOT':\n case 'IS_NOT_EQUAL_TO':\n return `${measureExpr} != ${value}`;\n case 'IS_GREATER_THAN':\n return `${measureExpr} > ${value}`;\n case 'IS_GREATER_THAN_OR_EQUAL_TO':\n return `${measureExpr} >= ${value}`;\n case 'IS_LESS_THAN':\n return `${measureExpr} < ${value}`;\n case 'IS_LESS_THAN_OR_EQUAL_TO':\n return `${measureExpr} <= ${value}`;\n case 'IS_BLANK':\n return `${measureExpr} IS NULL`;\n case 'IS_NOT_BLANK':\n return `${measureExpr} IS NOT NULL`;\n default:\n return `${measureExpr} = ${value}`;\n }\n }\n\n protected buildTupleFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.valuesFilter?.length) {\n return '';\n }\n\n const columns = filter.columnNames;\n const tupleConditions: string[] = [];\n\n filter.valuesFilter.forEach((valueItem) => {\n if (Array.isArray(valueItem.id)) {\n const tupleValues = valueItem.id\n .map((id, index) => `${columns[index]} = ${BaseUtilities.formatValue(id.toString())}`)\n .join(' AND ');\n tupleConditions.push(`(${tupleValues})`);\n }\n });\n\n const operator = filter.valuesFilterApplicationType === 'INCLUDE' ? 'OR' : 'AND NOT';\n const result =\n tupleConditions.length > 0\n ? tupleConditions.length === 1\n ? tupleConditions[0]\n : `(${tupleConditions.join(` ${operator} `)})`\n : '';\n\n return filter.isCrossHighlight === true ? this.wrapWithCrossHighlight(result) : result;\n }\n\n protected buildSearchFilter(filter: FilterConfig): string {\n return SharedFilterBuilder.buildSearchFilter(filter);\n }\n\n protected buildRankingFilter(filter: FilterConfig): string {\n return SharedFilterBuilder.buildRankingFilter(filter);\n }\n\n protected buildBlankFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.blankFilterConfig) {\n return '';\n }\n\n const column = filter.columnNames[0];\n const blankConfig = filter.blankFilterConfig;\n\n if (blankConfig.operator === 'IS_BLANK') {\n if (blankConfig.treatEmptyStringAsBlank) {\n return `(${column} IS NULL OR TRIM(${column}) = '')`;\n } else {\n return `${column} IS NULL`;\n }\n } else {\n if (blankConfig.treatEmptyStringAsBlank) {\n return `(${column} IS NOT NULL AND TRIM(${column}) != '')`;\n } else {\n return `${column} IS NOT NULL`;\n }\n }\n }\n\n protected buildRelativePeriodFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.relativePeriodFilter) {\n return '';\n }\n\n const tableName =\n filter.tableNames?.[0] || BaseUtilities.getDefaultTableNameFromOptions(this.options);\n const column = BaseUtilities.buildColumnReference(tableName, filter.columnNames[0]);\n return this.buildRelativePeriodCondition(column, filter.relativePeriodFilter);\n }\n\n protected buildDateHierarchyFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.dateHierarchyConfig) {\n return '';\n }\n\n const tableName =\n filter.tableNames?.[0] || BaseUtilities.getDefaultTableNameFromOptions(this.options);\n const column = BaseUtilities.buildColumnReference(tableName, filter.columnNames[0]);\n const hierarchyConfig = filter.dateHierarchyConfig;\n\n if (!hierarchyConfig.level) {\n return `${column} IS NOT NULL`;\n }\n\n if (!hierarchyConfig.values?.length) {\n let hierarchyFunction: string;\n switch (hierarchyConfig.level) {\n case 'YEAR':\n hierarchyFunction = `EXTRACT(YEAR FROM ${column})`;\n break;\n case 'QUARTER':\n hierarchyFunction = `EXTRACT(QUARTER FROM ${column})`;\n break;\n case 'MONTH':\n hierarchyFunction = `EXTRACT(MONTH FROM ${column})`;\n break;\n case 'DAY':\n hierarchyFunction = `EXTRACT(DAY FROM ${column})`;\n break;\n case 'WEEK':\n hierarchyFunction = `EXTRACT(WEEK FROM ${column})`;\n break;\n case 'DAYOFWEEK':\n hierarchyFunction = `EXTRACT(DAYOFWEEK FROM ${column})`;\n break;\n default:\n return `${column} IS NOT NULL`;\n }\n return `${hierarchyFunction} IS NOT NULL`;\n }\n\n let hierarchyFunction: string;\n switch (hierarchyConfig.level) {\n case 'YEAR':\n hierarchyFunction = `EXTRACT(YEAR FROM ${column})`;\n break;\n case 'QUARTER':\n hierarchyFunction = `EXTRACT(QUARTER FROM ${column})`;\n break;\n case 'MONTH':\n hierarchyFunction = `EXTRACT(MONTH FROM ${column})`;\n break;\n case 'DAY':\n hierarchyFunction = `EXTRACT(DAY FROM ${column})`;\n break;\n case 'WEEK':\n hierarchyFunction = `EXTRACT(WEEK FROM ${column})`;\n break;\n case 'DAYOFWEEK':\n hierarchyFunction = `EXTRACT(DAYOFWEEK FROM ${column})`;\n break;\n default:\n throw new FilterValidationError(\n 'DATE_HIERARCHY',\n `unsupported level: ${hierarchyConfig.level}`,\n {\n level: hierarchyConfig.level,\n supportedLevels: ['YEAR', 'QUARTER', 'MONTH', 'DAY', 'WEEK', 'DAYOFWEEK'],\n },\n );\n }\n\n if (hierarchyConfig.values.length === 1) {\n return `${hierarchyFunction} = ${hierarchyConfig.values[0]}`;\n } else {\n const valuesList = hierarchyConfig.values.join(', ');\n return `${hierarchyFunction} IN (${valuesList})`;\n }\n }\n\n protected buildFieldParameterFilter(filter: FilterConfig): string {\n if (!filter.fieldParameterMapping) {\n return '';\n }\n\n const mapping = filter.fieldParameterMapping;\n if (!mapping.targetField) {\n return '';\n }\n\n const tableName =\n mapping.targetTable || BaseUtilities.getDefaultTableNameFromOptions(this.options);\n const column = BaseUtilities.buildColumnReference(tableName, mapping.targetField);\n\n if (mapping.filterValues?.length) {\n if (mapping.filterValues.length === 1) {\n return `${column} = '${mapping.filterValues[0]}'`;\n } else {\n const valuesList = mapping.filterValues.map((v) => `'${v}'`).join(', ');\n return `${column} IN (${valuesList})`;\n }\n }\n\n return `${column} IS NOT NULL`;\n }\n\n protected buildRelativePeriodCondition(\n column: string,\n config: { duration: number; period: string; relativeDateFilter: string },\n ): string {\n const now = 'CURRENT_DATE';\n const duration = config.duration;\n const period = config.period;\n\n switch (config.relativeDateFilter) {\n case 'IS_IN_THE_LAST':\n switch (period) {\n case 'DAYS':\n return `${column} >= ${now} - INTERVAL '${duration} days'`;\n case 'WEEKS':\n return `${column} >= ${now} - INTERVAL '${duration} weeks'`;\n case 'MONTHS':\n return `${column} >= ${now} - INTERVAL '${duration} months'`;\n case 'YEARS':\n return `${column} >= ${now} - INTERVAL '${duration} years'`;\n default:\n return `${column} >= ${now} - INTERVAL '${duration} days'`;\n }\n case 'IS_IN_THE_NEXT':\n switch (period) {\n case 'DAYS':\n return `${column} <= ${now} + INTERVAL '${duration} days'`;\n case 'WEEKS':\n return `${column} <= ${now} + INTERVAL '${duration} weeks'`;\n case 'MONTHS':\n return `${column} <= ${now} + INTERVAL '${duration} months'`;\n case 'YEARS':\n return `${column} <= ${now} + INTERVAL '${duration} years'`;\n default:\n return `${column} <= ${now} + INTERVAL '${duration} days'`;\n }\n case 'IS_IN_THIS':\n switch (period) {\n case 'DAYS':\n return `DATE_TRUNC('day', ${column}) = DATE_TRUNC('day', ${now})`;\n case 'WEEKS':\n return `DATE_TRUNC('week', ${column}) = DATE_TRUNC('week', ${now})`;\n case 'MONTHS':\n return `DATE_TRUNC('month', ${column}) = DATE_TRUNC('month', ${now})`;\n case 'YEARS':\n return `DATE_TRUNC('year', ${column}) = DATE_TRUNC('year', ${now})`;\n default:\n return `DATE_TRUNC('day', ${column}) = DATE_TRUNC('day', ${now})`;\n }\n default:\n return `${column} = ${now}`;\n }\n }\n\n private wrapWithCrossHighlight(condition: string): string {\n return condition;\n }\n\n private buildCrossHighlightFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.valuesFilter?.length) {\n return '';\n }\n\n const column = filter.columnNames[0];\n const values = filter.valuesFilter\n .flatMap((vf) => (Array.isArray(vf.id) ? vf.id : [vf.id]))\n .filter((v) => v !== undefined);\n const valueList = values.map((v) => BaseUtilities.formatValue(v.toString())).join(',');\n\n return `${column} IN (${valueList})`;\n }\n\n protected calculateTopNValue(value: number, totalCount: number, isPercentage: boolean): number {\n if (totalCount === 0 || !isPercentage) {\n return value;\n }\n return Math.floor((value * totalCount) / 100);\n }\n\n protected calculateDistinctRowsCount(filter: FilterConfig, defaultCount: number): number {\n if (filter.distinctRowsCount && filter.distinctRowsCount > 0) {\n return filter.distinctRowsCount;\n }\n\n if (this.options.superFilters?.children) {\n for (const child of this.options.superFilters.children) {\n if (Array.isArray(child.filters) && child.filters.length > 0) {\n const firstFilter = child.filters[0];\n if (firstFilter.distinctRowsCount && firstFilter.distinctRowsCount > 0) {\n return firstFilter.distinctRowsCount;\n }\n }\n }\n }\n\n return defaultCount;\n }\n\n protected extractFilters(): {\n columnName: string;\n values: string[];\n applicationType: string;\n }[] {\n if (!this.options.superFilters?.children) {\n return [];\n }\n\n const filters: {\n columnName: string;\n values: string[];\n applicationType: string;\n }[] = [];\n\n this.options.superFilters.children.forEach((child) => {\n const filter = child.filters;\n if (!filter) return;\n\n switch (filter.filterType) {\n case 'VALUES':\n if (filter.columnNames?.length > 0) {\n const columnName = filter.columnNames[0];\n const values =\n filter.valuesFilter\n ?.flatMap((vf) => (Array.isArray(vf.id) ? vf.id : [vf.id]))\n .filter((v) => v !== undefined) || [];\n const applicationType = filter.valuesFilterApplicationType || 'include';\n\n filters.push({\n columnName,\n values,\n applicationType,\n });\n }\n break;\n case 'RANGE':\n break;\n case 'DATE':\n break;\n default:\n break;\n }\n });\n\n return filters;\n }\n\n protected applyLogicalOperator(conditions: string[], filter: FilterConfig): string {\n if (!conditions.length) return '';\n if (conditions.length === 1) return conditions[0];\n\n const logicalOp = filter.logicalOperator?.toUpperCase() === 'OR' ? 'OR' : 'AND';\n return conditions.join(` ${logicalOp} `);\n }\n\n protected handleTupleFilter(filter: FilterConfig): boolean {\n return Boolean(filter.isTupleFilter || (filter.columnIds && filter.columnIds.length > 1));\n }\n\n protected handleCrossHighlight(filter: FilterConfig): boolean {\n return Boolean(filter.isCrossHighlight);\n }\n\n protected validateDataTypes(filter: FilterConfig): boolean {\n if (!filter.dataType?.length || !filter.columnDataType?.length) {\n return true;\n }\n return filter.dataType.every((type) =>\n ['string', 'number', 'date', 'boolean'].includes(type.toLowerCase()),\n );\n }\n\n protected processSourceTypes(filter: FilterConfig): string[] {\n return filter.sourceType || [];\n }\n\n protected isRankingFilterEnabled(filter: FilterConfig): boolean {\n return Boolean(filter.isRankingFilter || filter.rankingConfig);\n }\n}\n","import {\n EpmQueryBuilderOptions,\n FilterConfig,\n RankingConfig,\n} from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\nimport { SharedFilterBuilder } from '@epm-query-builder/base/SharedFilterBuilder';\nimport { mapAggregationType as mapAgg } from '@epm-query-builder/constants/Aggregations';\n\nexport abstract class BaseCTEGenerator {\n protected options: EpmQueryBuilderOptions;\n\n constructor(options: EpmQueryBuilderOptions) {\n this.options = options;\n }\n\n protected generateCTE(name: string, query: string): string {\n return BaseUtilities.buildCTETemplate(name, query);\n }\n\n protected buildFilterCTE(filter: FilterConfig, counter: number): string {\n const variableName = `filter_${counter}`;\n const specificCTE = this.buildSpecificFilterCTE(filter, variableName);\n\n if (!specificCTE) return '';\n\n return this.generateCTE(variableName, specificCTE);\n }\n\n protected buildBasicFilterCTE(filter: FilterConfig, _variableName?: string): string {\n void _variableName;\n if (!filter.columnNames?.length || !filter.tableNames?.length) {\n return '';\n }\n\n const column = filter.columnNames[0];\n const tableName = filter.tableNames[0];\n const condition = SharedFilterBuilder.buildFilterCondition(filter);\n\n if (!condition) return '';\n\n return BaseUtilities.buildDistinctSelect([column], tableName, condition);\n }\n\n protected buildTupleFilterCTE(filter: FilterConfig, _variableName: string): string {\n void _variableName;\n if (!filter.columnNames?.length || filter.columnNames.length < 2) {\n return this.buildBasicFilterCTE(filter);\n }\n\n const tableName = filter.tableNames?.[0] || '';\n const columns = filter.columnNames;\n\n if (!filter.valuesFilter?.length) return '';\n\n const tupleConditions = filter.valuesFilter\n .map((vf) => {\n const ids = Array.isArray(vf.id) ? vf.id : [vf.id];\n if (ids.length !== columns.length) return null;\n\n const columnValuePairs = columns\n .map((col, idx) => `${col} = ${BaseUtilities.formatValue(ids[idx].toString())}`)\n .join(' AND ');\n\n return `(${columnValuePairs})`;\n })\n .filter((condition): condition is string => Boolean(condition));\n\n if (!tupleConditions.length) return '';\n\n const tupleClause = BaseUtilities.combineConditions(tupleConditions, 'OR');\n const isExclude = filter.valuesFilterApplicationType?.toUpperCase() === 'EXCLUDE';\n const finalCondition = isExclude ? `NOT (${tupleClause})` : `(${tupleClause})`;\n\n return BaseUtilities.buildDistinctSelect(columns, tableName, finalCondition);\n }\n\n protected buildComplexFilterCTE(filter: FilterConfig, variableName: string): string {\n const filterType = filter.filterType?.toUpperCase();\n\n if (filterType === 'TUPLE') {\n return this.buildTupleFilterCTE(filter, variableName);\n }\n\n const condition = SharedFilterBuilder.buildFilterCondition(filter);\n if (!condition) return '';\n\n const column = filter.columnNames?.[0];\n const tableName = filter.tableNames?.[0] || '';\n if (!column) return '';\n return BaseUtilities.buildDistinctSelect([column], tableName, condition);\n }\n\n generateFilterCTEs(): string {\n if (!this.options.superFilters?.children) {\n return '';\n }\n\n const filterCTEs: string[] = [];\n let variableCounter = 1;\n\n this.options.superFilters.children.forEach((child) => {\n const filter = child.filters;\n if (!filter) return;\n\n if (this.isComplexFilter(filter)) {\n const cte = this.buildFilterCTE(filter, variableCounter++);\n if (cte) {\n filterCTEs.push(cte);\n }\n }\n });\n\n return filterCTEs.length > 0 ? `WITH ${filterCTEs.join(',\\n')}` : '';\n }\n\n protected buildRankingFilterCTE(filter: FilterConfig, _variableName: string): string {\n void _variableName;\n const rankingConfigs =\n filter.rankingFilter || (filter.rankingConfig ? [filter.rankingConfig] : []);\n\n if (!rankingConfigs.length || !filter.columnNames?.length) {\n return '';\n }\n\n const column = filter.columnNames[0];\n const tableName = filter.tableNames?.[0] || '';\n\n if (rankingConfigs.length === 1) {\n return this.buildSingleRankingCTE(filter, rankingConfigs[0], column, tableName);\n }\n\n const cteQueries = rankingConfigs\n .map((rankingConfig) => this.buildSingleRankingCTE(filter, rankingConfig, column, tableName))\n .filter((query) => query);\n\n if (!cteQueries.length) return '';\n\n const operator = filter.logicalOperator?.toUpperCase() === 'OR' ? 'UNION' : 'INTERSECT';\n return cteQueries.join(` ${operator} `);\n }\n\n private buildSingleRankingCTE(\n filter: FilterConfig,\n rankingConfig: RankingConfig,\n column: string,\n tableName: string,\n ): string {\n const rankByColumnId =\n rankingConfig.rankByColumnId ||\n `${rankingConfig.rankByTableName || ''}[${rankingConfig.rankByColumnName || column}]`;\n const actualColumnId = BaseUtilities.extractColumnIdFromHierarchy(rankByColumnId);\n const rankColumn = actualColumnId;\n const rankTable = rankingConfig.rankByTableName || tableName;\n const aggregationType = this.mapAggregationType(rankingConfig.rankByAggregationType || 'SUM');\n\n const topNValue = this.calculateTopNValue(\n rankingConfig.value,\n filter.distinctRowsCount || 1000000,\n rankingConfig.isPercentage || false,\n );\n\n const rankByRef = rankTable ? `\"${rankTable}\".\"${rankColumn}\"` : `\"${rankColumn}\"`;\n\n if (rankingConfig.type === 'BOTH') {\n const topValue = Math.ceil(topNValue / 2);\n const bottomValue = Math.floor(topNValue / 2);\n\n const topQuery = this.buildRankingSelectQuery(\n column,\n tableName,\n rankByRef,\n aggregationType,\n 'DESC',\n topValue,\n );\n\n const bottomQuery = this.buildRankingSelectQuery(\n column,\n tableName,\n rankByRef,\n aggregationType,\n 'ASC',\n bottomValue,\n );\n\n return `(${topQuery}) UNION ALL (${bottomQuery})`;\n }\n\n const orderDirection = rankingConfig.type === 'TOP' ? 'DESC' : 'ASC';\n\n return this.buildRankingSelectQuery(\n column,\n tableName,\n rankByRef,\n aggregationType,\n orderDirection,\n topNValue,\n rankingConfig.isPercentage,\n );\n }\n\n private buildRankingSelectQuery(\n column: string,\n tableName: string,\n rankByRef: string,\n aggregationType: string,\n orderDirection: string,\n topNValue: number,\n isPercentage?: boolean,\n ): string {\n if (isPercentage) {\n const percentileValue = topNValue / 100;\n const condition = `PERCENT_RANK() OVER (ORDER BY ${aggregationType}(${rankByRef}) ${orderDirection}) <= ${percentileValue}`;\n return BaseUtilities.buildDistinctSelect([`\"${column}\"`], `\"${tableName}\"`, condition);\n } else {\n const orderByClause = `${aggregationType}(${rankByRef}) ${orderDirection} LIMIT ${topNValue}`;\n return BaseUtilities.buildDistinctSelect(\n [`\"${column}\"`],\n `\"${tableName}\"`,\n undefined,\n orderByClause,\n );\n }\n }\n\n private mapAggregationType(aggregationType: string): string {\n return mapAgg(aggregationType);\n }\n\n protected buildSearchFilterCTE(filter: FilterConfig, _variableName: string): string {\n void _variableName;\n if (!BaseUtilities.validateRequiredFields(filter, ['columnNames', 'searchConditions'])) {\n return '';\n }\n\n const column = filter.columnNames![0];\n const tableName = filter.tableNames?.[0] || '';\n\n const conditions = filter.searchConditions!.map((condition) => {\n const canonical = (condition.operator || '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+|_+$/g, '');\n const rawValue = String(condition.value ?? '');\n const escapedValue = rawValue.replace(/'/g, \"''\");\n\n switch (canonical) {\n case 'contains':\n return `LOWER(${column}) LIKE LOWER('%${escapedValue}%')`;\n case 'does_not_contain':\n case 'not_contains':\n case 'not_contain':\n return `LOWER(${column}) NOT LIKE LOWER('%${escapedValue}%')`;\n case 'starts_with':\n return `LOWER(${column}) LIKE LOWER('${escapedValue}%')`;\n case 'does_not_start_with':\n case 'not_starts_with':\n case 'not_start_with':\n return `LOWER(${column}) NOT LIKE LOWER('${escapedValue}%')`;\n case 'ends_with':\n return `LOWER(${column}) LIKE LOWER('%${escapedValue}')`;\n case 'does_not_end_with':\n case 'not_ends_with':\n case 'not_end_with':\n return `LOWER(${column}) NOT LIKE LOWER('%${escapedValue}')`;\n case 'equals':\n case 'is_equal_to':\n case 'is':\n return `${column} = ${BaseUtilities.formatValue(rawValue)}`;\n case 'not_equals':\n case 'is_not_equal_to':\n case 'is_not':\n return `${column} != ${BaseUtilities.formatValue(rawValue)}`;\n case 'is_blank':\n case 'blank':\n return `${column} IS NULL`;\n case 'is_not_blank':\n case 'not_blank':\n return `${column} IS NOT NULL`;\n case 'is_empty':\n return `TRIM(${column}) = ''`;\n case 'is_not_empty':\n return `TRIM(${column}) != ''`;\n default:\n return `LOWER(${column}) LIKE LOWER('%${escapedValue}%')`;\n }\n });\n\n const whereCondition = BaseUtilities.combineConditions(conditions, 'AND');\n return BaseUtilities.buildDistinctSelect([column], tableName, whereCondition);\n }\n\n protected buildBlankFilterCTE(filter: FilterConfig, _variableName: string): string {\n void _variableName;\n if (!BaseUtilities.validateRequiredFields(filter, ['columnNames', 'blankFilterConfig'])) {\n return '';\n }\n\n const column = filter.columnNames![0];\n const tableName = filter.tableNames?.[0] || '';\n const blankConfig = filter.blankFilterConfig!;\n\n let condition: string;\n if (blankConfig.operator === 'IS_BLANK') {\n if (blankConfig.treatEmptyStringAsBlank) {\n condition = `(${column} IS NULL OR TRIM(${column}) = '')`;\n } else {\n condition = `${column} IS NULL`;\n }\n } else {\n if (blankConfig.treatEmptyStringAsBlank) {\n condition = `(${column} IS NOT NULL AND TRIM(${column}) != '')`;\n } else {\n condition = `${column} IS NOT NULL`;\n }\n }\n\n return BaseUtilities.buildDistinctSelect([column], tableName, condition);\n }\n\n protected buildRelativePeriodFilterCTE(filter: FilterConfig, _variableName: string): string {\n void _variableName;\n if (!BaseUtilities.validateRequiredFields(filter, ['columnNames', 'relativePeriodFilter'])) {\n return '';\n }\n\n const column = filter.columnNames![0];\n const tableName = filter.tableNames?.[0] || '';\n const relativePeriod = filter.relativePeriodFilter!;\n\n const condition = this.buildRelativePeriodCondition(column, relativePeriod);\n return BaseUtilities.buildDistinctSelect([column], tableName, condition);\n }\n\n protected buildDateHierarchyFilterCTE(filter: FilterConfig, _variableName: string): string {\n void _variableName;\n if (!BaseUtilities.validateRequiredFields(filter, ['columnNames', 'dateHierarchyConfig'])) {\n return '';\n }\n\n const column = filter.columnNames![0];\n const tableName = filter.tableNames?.[0] || '';\n const hierarchyConfig = filter.dateHierarchyConfig!;\n\n let hierarchyFunction: string;\n switch (hierarchyConfig.level) {\n case 'YEAR':\n hierarchyFunction = `EXTRACT(YEAR FROM ${column})`;\n break;\n case 'QUARTER':\n hierarchyFunction = `EXTRACT(QUARTER FROM ${column})`;\n break;\n case 'MONTH':\n hierarchyFunction = `EXTRACT(MONTH FROM ${column})`;\n break;\n case 'DAY':\n hierarchyFunction = `EXTRACT(DAY FROM ${column})`;\n break;\n default:\n hierarchyFunction = column;\n }\n\n const selectColumn = `${hierarchyFunction} AS ${column}_${hierarchyConfig.level.toLowerCase()}`;\n return BaseUtilities.buildDistinctSelect([selectColumn], tableName);\n }\n\n protected buildFieldParameterFilterCTE(filter: FilterConfig, _variableName: string): string {\n void _variableName;\n if (!filter.fieldParameterMapping) {\n return '';\n }\n\n const mapping = filter.fieldParameterMapping;\n const tableName = mapping.targetTable;\n\n if (!tableName || !mapping.targetField) return '';\n\n return BaseUtilities.buildDistinctSelect([mapping.targetField], tableName);\n }\n\n protected buildRelativePeriodCondition(\n column: string,\n config: { duration: number; period: string; relativeDateFilter: string },\n ): string {\n const now = 'CURRENT_DATE';\n const duration = config.duration;\n const period = config.period;\n\n switch (config.relativeDateFilter) {\n case 'IS_IN_THE_LAST':\n switch (period) {\n case 'DAYS':\n return `${column} >= ${now} - INTERVAL '${duration} days'`;\n case 'WEEKS':\n return `${column} >= ${now} - INTERVAL '${duration} weeks'`;\n case 'MONTHS':\n return `${column} >= ${now} - INTERVAL '${duration} months'`;\n case 'YEARS':\n return `${column} >= ${now} - INTERVAL '${duration} years'`;\n default:\n return `${column} >= ${now} - INTERVAL '${duration} days'`;\n }\n case 'IS_IN_THE_NEXT':\n switch (period) {\n case 'DAYS':\n return `${column} <= ${now} + INTERVAL '${duration} days'`;\n case 'WEEKS':\n return `${column} <= ${now} + INTERVAL '${duration} weeks'`;\n case 'MONTHS':\n return `${column} <= ${now} + INTERVAL '${duration} months'`;\n case 'YEARS':\n return `${column} <= ${now} + INTERVAL '${duration} years'`;\n default:\n return `${column} <= ${now} + INTERVAL '${duration} days'`;\n }\n case 'IS_IN_THIS':\n switch (period) {\n case 'DAYS':\n return `DATE_TRUNC('day', ${column}) = DATE_TRUNC('day', ${now})`;\n case 'WEEKS':\n return `DATE_TRUNC('week', ${column}) = DATE_TRUNC('week', ${now})`;\n case 'MONTHS':\n return `DATE_TRUNC('month', ${column}) = DATE_TRUNC('month', ${now})`;\n case 'YEARS':\n return `DATE_TRUNC('year', ${column}) = DATE_TRUNC('year', ${now})`;\n default:\n return `DATE_TRUNC('day', ${column}) = DATE_TRUNC('day', ${now})`;\n }\n default:\n return `${column} = ${now}`;\n }\n }\n\n private calculateTopNValue(value: number, totalCount: number, isPercentage: boolean): number {\n if (totalCount === 0 || !isPercentage) {\n return value;\n }\n return Math.floor((value * totalCount) / 100);\n }\n\n protected isComplexFilter(filter: FilterConfig): boolean {\n return Boolean(\n filter.filterType === 'TUPLE' ||\n filter.filterType === 'RANKING' ||\n filter.filterType === 'SEARCH' ||\n filter.filterType === 'BLANK' ||\n filter.filterType === 'RELATIVE_PERIOD' ||\n filter.filterType === 'DATE_HIERARCHY' ||\n filter.filterType === 'FIELD_PARAMETER' ||\n filter.isCrossHighlight ||\n (filter.filterType === 'RANGE' && filter.rangeFilter && filter.rangeFilter.length > 1) ||\n (filter.filterType === 'VALUES' && filter.valuesFilter && filter.valuesFilter.length > 10),\n );\n }\n\n abstract buildSpecificFilterCTE(filter: FilterConfig, variableName: string): string;\n}\n","import { BaseSuperFilterBuilder } from '@epm-query-builder/base/BaseSuperFilterBuilder';\nimport { FilterConfig, EpmQueryBuilderOptions } from '@epm-query-builder/types/query-builder-types';\nimport { BaseCTEGenerator } from '@epm-query-builder/base/BaseCTEGenerator';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\nimport { SharedFilterBuilder } from '@epm-query-builder/base/SharedFilterBuilder';\nimport { SOURCE_TYPES } from '@epm-query-builder/constants/Source';\n\nexport class DuckDbSuperFilterBuilder extends BaseSuperFilterBuilder {\n private cteGenerator: BaseCTEGenerator;\n\n constructor(options: EpmQueryBuilderOptions) {\n super(options);\n this.cteGenerator = new (class extends BaseCTEGenerator {\n buildSpecificFilterCTE(filter: FilterConfig, variableName: string): string {\n if (filter.filterType?.toUpperCase() === 'RANKING') {\n return '';\n }\n const source = BaseUtilities.getSource(this.options);\n if (source === SOURCE_TYPES.BLEND) {\n const fromIds = filter.columnIds || [];\n const fromNames = filter.columnNames || [];\n const resolvedNames: string[] = [];\n const maxLen = Math.max(fromIds.length, fromNames.length);\n for (let i = 0; i < Math.max(maxLen, 1); i += 1) {\n const id = fromIds[i];\n const name = fromNames[i];\n if (id) {\n resolvedNames.push(id);\n } else if (name) {\n resolvedNames.push(name);\n }\n }\n const adjusted: FilterConfig = {\n ...filter,\n columnNames: resolvedNames.length ? resolvedNames : filter.columnNames,\n columnIds: [],\n };\n\n const condition = SharedFilterBuilder.buildFilterCondition(adjusted);\n if (!condition) return '';\n\n const tableName = adjusted.tableNames?.[0] || '';\n const useDot = BaseUtilities.shouldUseDotNotation(this.options);\n const tableForRef =\n tableName || BaseUtilities.getDefaultTableNameFromOptions(this.options);\n const selectColumnName = adjusted.columnNames?.[0] || '';\n const columnRef = useDot\n ? BaseUtilities.buildColumnReference(tableForRef, selectColumnName)\n : `\"${selectColumnName}\"`;\n\n return BaseUtilities.buildDistinctSelect([columnRef], tableName, condition);\n }\n return this.buildComplexFilterCTE(filter, variableName);\n }\n protected isComplexFilter(filter: FilterConfig): boolean {\n if (filter.filterType?.toUpperCase() === 'RANKING') {\n return false;\n }\n return super.isComplexFilter(filter);\n }\n })(options);\n }\n buildWhereClause(): string {\n if (!this.options.superFilters) {\n return '';\n }\n\n return this.buildNestedFilterGroups(this.options.superFilters);\n }\n\n buildFilterCTE(): string {\n const complex = this.hasComplexFilters() ? this.cteGenerator.generateFilterCTEs() : '';\n const orGroup = this.buildOrGroupCTE();\n\n if (!complex && !orGroup) return '';\n\n const complexDefs = complex.replace(/^\\s*WITH\\s+/i, '');\n\n if (complexDefs && !orGroup) return complexDefs;\n if (!complexDefs && orGroup) return orGroup;\n\n return `${complexDefs},\\n${orGroup}`;\n }\n\n protected buildMeasureFilter(): string {\n const measureFilters = this.extractMeasureFilters();\n if (measureFilters.length === 0) {\n return '';\n }\n\n const conditions = measureFilters.map((filter) => this.buildMeasureCondition(filter));\n return BaseUtilities.combineConditions(\n conditions.filter((c) => c),\n 'AND',\n );\n }\n\n protected buildValuesFilter(filter: FilterConfig): string {\n if (!filter.columnNames?.length || !filter.valuesFilter?.length) {\n return '';\n }\n\n const source = BaseUtilities.getSource(this.options);\n const columnFromIds = filter.columnIds?.[0];\n const columnFromNames = filter.columnNames[0];\n const resolvedForDb =\n source === SOURCE_TYPES.BLEND\n ? columnFromIds || columnFromNames\n : BaseUtilities.extractColumnIdFromHierarchy(columnFromIds || columnFromNames);\n const useDot = BaseUtilities.shouldUseDotNotation(this.options);\n const columnReference = useDot\n ? BaseUtilities.buildColumnReference(\n filter.tableNames?.[0] || BaseUtilities.getDefaultTableNameFromOptions(this.options),\n resolvedForDb,\n )\n : `\"${resolvedForDb}\"`;\n\n const values = filter.valuesFilter\n .flatMap((vf) => (Array.isArray(vf.id) ? vf.id : [vf.id]))\n .filter((v) => v !== undefined);\n\n if (values.length === 0) {\n return '';\n }\n\n if (filter.isCrossHighlight === true) {\n return SharedFilterBuilder.buildValuesFilter(this.adjustFilterForBlend(filter));\n }\n\n const operator =\n filter.valuesFilterApplicationType?.toUpperCase() === 'INCLUDE' ? 'IN' : 'NOT IN';\n const valueList = values.map((v) => BaseUtilities.formatValue(v.toString())).join(',');\n\n return `${columnReference} ${operator} (${valueList})`;\n }\n\n private adjustFilterForBlend(filter: FilterConfig): FilterConfig {\n const src = BaseUtilities.getSource(this.options);\n if (src !== SOURCE_TYPES.BLEND) return filter;\n const fromIds = filter.columnIds || [];\n const fromNames = filter.columnNames || [];\n const resolvedNames: string[] = [];\n const maxLen = Math.max(fromIds.length, fromNames.length);\n for (let i = 0; i < Math.max(maxLen, 1); i += 1) {\n const id = fromIds[i];\n const name = fromNames[i];\n if (id) {\n resolvedNames.push(id);\n } else if (name) {\n resolvedNames.push(name);\n }\n }\n return {\n ...filter,\n columnNames: resolvedNames.length ? resolvedNames : filter.columnNames,\n columnIds: [],\n };\n }\n\n protected buildFilterCondition(filter: FilterConfig): string {\n if (!filter) return '';\n const type = filter.filterType?.toUpperCase();\n if (type === 'MEASURE') return '';\n\n const normalized = this.normalizeFilterColumns(filter);\n\n if (type === 'VALUES') return this.buildValuesFilter(normalized);\n if (type === 'RANGE') {\n const hasAgg =\n Array.isArray(normalized.aggregationType) && normalized.aggregationType.length > 0;\n if (hasAgg) {\n // if RANGE filter has aggregationType but only checks for blank/not blank,\n // generate a WHERE clause on the base column (non-aggregated).\n if (this.hasOnlyBlankRangeComparisons(normalized)) {\n return this.buildBlankRangeWhere(normalized);\n }\n return '';\n }\n }\n const adjusted = this.adjustFilterForBlend(normalized);\n switch (type) {\n case 'RANGE':\n return SharedFilterBuilder.buildRangeFilter(adjusted);\n case 'DATE':\n case 'DATE_RANGE':\n return SharedFilterBuilder.buildDateFilter(adjusted);\n case 'RANKING':\n return '';\n case 'SEARCH':\n return SharedFilterBuilder.buildSearchFilter(adjusted);\n case 'BLANK':\n return SharedFilterBuilder.buildBlankFilter(adjusted);\n case 'TUPLE':\n return SharedFilterBuilder.buildTupleFilter(adjusted);\n case 'RELATIVE_PERIOD':\n return SharedFilterBuilder.buildRelativePeriodFilter(adjusted);\n case 'DATE_HIERARCHY':\n return SharedFilterBuilder.buildDateHierarchyFilter(adjusted);\n case 'FIELD_PARAMETER':\n return SharedFilterBuilder.buildFieldParameterFilter(adjusted);\n default:\n return '';\n }\n }\n\n private normalizeFilterColumns(filter: FilterConfig): FilterConfig {\n const columnIds = filter.columnIds || [];\n const source = BaseUtilities.getSource(this.options);\n const normalizedColumnNames = columnIds.length\n ? columnIds.map((id) => BaseUtilities.extractColumnIdFromHierarchy(id))\n : filter.columnNames || [];\n\n return {\n ...filter,\n columnNames: normalizedColumnNames,\n columnIds: source === SOURCE_TYPES.BLEND ? filter.columnIds : [],\n };\n }\n\n private isBlankOperator(op?: string): boolean {\n if (!op) return false;\n const canonical = op.toUpperCase().replace(/[^A-Z_]+/g, '_');\n return canonical === 'IS_BLANK' || canonical === 'IS_NOT_BLANK';\n }\n\n private hasOnlyBlankRangeComparisons(filter: FilterConfig): boolean {\n if (!filter?.rangeFilter?.length) return false;\n let sawBlank = false;\n for (const r of filter.rangeFilter) {\n const parts = [r.fromCondition, r.toCondition, r.operator].filter(Boolean) as string[];\n if (parts.length === 0) continue;\n const hasNonBlank = parts.some((p) => !this.isBlankOperator(p));\n if (hasNonBlank) return false;\n const hasBlank = parts.some((p) => this.isBlankOperator(p));\n if (hasBlank) sawBlank = true;\n }\n return sawBlank;\n }\n\n private buildColumnReferenceForWhere(filter: FilterConfig): string {\n const source = BaseUtilities.getSource(this.options);\n const idFromPayload = filter.columnIds?.[0];\n const actualIdFromName =\n (filter.tableNames?.[0] || '') && (filter.columnNames?.[0] || '')\n ? `${filter.tableNames?.[0]}[${filter.columnNames?.[0]}]`\n : filter.columnNames?.[0] || '';\n const actualColumnId = BaseUtilities.extractColumnIdFromHierarchy(\n idFromPayload || actualIdFromName,\n );\n const idForDb =\n source === SOURCE_TYPES.BLEND ? idFromPayload || actualColumnId : actualColumnId;\n\n const useDot = BaseUtilities.shouldUseDotNotation(this.options);\n const tableName =\n filter.tableNames?.[0] || BaseUtilities.getDefaultTableNameFromOptions(this.options);\n\n if (useDot && tableName) {\n return BaseUtilities.buildColumnReference(tableName, idForDb);\n }\n return `\"${idForDb}\"`;\n }\n\n private buildBlankRangeWhere(filter: FilterConfig): string {\n if (!filter.rangeFilter?.length) return '';\n const columnRef = this.buildColumnReferenceForWhere(filter);\n\n const rangeConditions: string[] = [];\n for (const r of filter.rangeFilter) {\n const parts: string[] = [];\n if (this.isBlankOperator(r.fromCondition)) {\n parts.push(\n `${columnRef} ${r.fromCondition?.toUpperCase() === 'IS_NOT_BLANK' ? 'IS NOT NULL' : 'IS NULL'}`,\n );\n }\n if (this.isBlankOperator(r.toCondition)) {\n parts.push(\n `${columnRef} ${r.toCondition?.toUpperCase() === 'IS_NOT_BLANK' ? 'IS NOT NULL' : 'IS NULL'}`,\n );\n }\n if (parts.length > 0) {\n const joiner = (r.logicalOperator || 'AND').toUpperCase() === 'OR' ? 'OR' : 'AND';\n rangeConditions.push(parts.length === 1 ? parts[0] : `(${parts.join(` ${joiner} `)})`);\n }\n }\n const topJoiner = (filter.logicalOperator as 'AND' | 'OR') || 'AND';\n return BaseUtilities.buildWhereCondition(rangeConditions, topJoiner);\n }\n\n private isComplexFilter(filter: FilterConfig): boolean {\n return Boolean(\n filter.filterType === 'TUPLE' ||\n filter.filterType === 'RANKING' ||\n filter.filterType === 'SEARCH' ||\n filter.filterType === 'BLANK' ||\n filter.filterType === 'RELATIVE_PERIOD' ||\n filter.filterType === 'DATE_HIERARCHY' ||\n filter.filterType === 'FIELD_PARAMETER' ||\n filter.isCrossHighlight ||\n (filter.filterType === 'RANGE' && filter.rangeFilter && filter.rangeFilter.length > 1) ||\n (filter.filterType === 'VALUES' && filter.valuesFilter && filter.valuesFilter.length > 10),\n );\n }\n\n protected hasComplexFilters(): boolean {\n return Boolean(\n this.options.superFilters?.children?.some(\n (child) => child.filters && this.isComplexFilter(child.filters),\n ),\n );\n }\n\n protected checkRankingFilters(): void {\n if (!this.options.superFilters?.children) return;\n\n const hasRankingFilter = this.options.superFilters.children.some(\n (child) =>\n Array.isArray(child.filters) &&\n child.filters.some((filter: FilterConfig) => filter.filterType === 'RANKING'),\n );\n\n if (hasRankingFilter && !this.options.isRankingFilterIncluded) {\n this.options.isRankingFilterIncluded = true;\n }\n }\n\n private buildOrGroupCTE(): string {\n const sf = this.options.superFilters;\n if (!sf || sf.condition?.toUpperCase() !== 'OR' || !sf.children?.length) {\n return '';\n }\n\n const dims = [\n ...BaseUtilities.buildDimensionReference(this.options.rows, this.options),\n ...BaseUtilities.buildDimensionReference(this.options.columns, this.options),\n ];\n if (dims.length === 0) return '';\n\n const tableName = BaseUtilities.formatTableNameForDb(\n BaseUtilities.getDefaultTableNameFromOptions(this.options),\n this.options.databaseDetails?.databaseType as string,\n );\n\n const selectCols = dims.map((expr, idx) => `${expr} AS __or_dim${idx + 1}`).join(', ');\n\n const parts: string[] = [];\n sf.children.forEach((child) => {\n const cond = this.buildSuperFilterChild(child);\n if (cond && cond.trim()) {\n parts.push(`SELECT DISTINCT ${selectCols} FROM ${tableName} WHERE ${cond}`);\n }\n });\n\n if (parts.length === 0) return '';\n return `__or_group AS (\\n${parts.join('\\nUNION\\n')}\\n)`;\n }\n\n buildOrGroupExistsClause(): string {\n const sf = this.options.superFilters;\n if (!sf || sf.condition?.toUpperCase() !== 'OR' || !sf.children?.length) {\n return '';\n }\n const dims = [\n ...BaseUtilities.buildDimensionReference(this.options.rows, this.options),\n ...BaseUtilities.buildDimensionReference(this.options.columns, this.options),\n ];\n if (dims.length === 0) return '';\n const comparisons = dims.map((expr, idx) => `${expr} = g.__or_dim${idx + 1}`).join(' AND ');\n return `EXISTS (SELECT 1 FROM __or_group g WHERE ${comparisons})`;\n }\n}\n","import {\n EpmQueryBuilderOptions,\n MeasureConfig,\n} from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\n\nexport abstract class BaseMeasureBuilder {\n protected options: EpmQueryBuilderOptions;\n\n constructor(options: EpmQueryBuilderOptions) {\n this.options = options;\n }\n\n protected buildStandardAggregation(measure: MeasureConfig): string {\n // If no aggregation type, use the measure ID directly without prefix\n const hasAggregation = measure.aggregationType && measure.aggregationType.trim() !== '';\n if (!hasAggregation) {\n return measure.id;\n }\n\n const original = (measure.aggregationType || 'SUM').toUpperCase();\n const aliasPrefix =\n original === 'FIRST'\n ? 'FIRST'\n : original === 'LAST'\n ? 'LAST'\n : BaseUtilities.mapAggregationType(original);\n return `${aliasPrefix}__${measure.id}`;\n }\n\n protected buildCalculatedMeasure(measure: MeasureConfig): string {\n return `\"${measure.id}\"`;\n }\n\n protected buildConditionalMeasure(measure: MeasureConfig): string {\n // If no aggregation type, use the measure ID directly without prefix\n const hasAggregation = measure.aggregationType && measure.aggregationType.trim() !== '';\n if (!hasAggregation) {\n return measure.id;\n }\n\n const original = (measure.aggregationType || 'SUM').toUpperCase();\n const aliasPrefix =\n original === 'FIRST'\n ? 'FIRST'\n : original === 'LAST'\n ? 'LAST'\n : BaseUtilities.mapAggregationType(original);\n return `${aliasPrefix}__${measure.id}`;\n }\n\n protected isMeasureType(measure: MeasureConfig): boolean {\n return measure.type?.toLowerCase() === 'measure';\n }\n\n protected formatMeasureAlias(measure: MeasureConfig): string {\n if (this.isMeasureType(measure)) {\n return `${measure.tableName}[${measure.columnName}]`;\n }\n // If no aggregation type, use column name without prefix\n const hasAggregation = measure.aggregationType && measure.aggregationType.trim() !== '';\n if (!hasAggregation) {\n return `${measure.tableName}[${measure.columnName}]`;\n }\n return `${measure.aggregationType}__${measure.tableName}[${measure.columnName}]`;\n }\n\n protected getMeasures(): MeasureConfig[] {\n return (this.options.values || []) as MeasureConfig[];\n }\n\n protected buildMeasureExpressions(): string[] {\n const measures = this.getMeasures();\n\n return measures.map((measure) => {\n if (this.isMeasureType(measure)) {\n return this.buildCalculatedMeasure(measure);\n }\n return this.buildStandardAggregation(measure);\n });\n }\n\n protected buildMeasureSelectClause(): string {\n const expressions = this.buildMeasureExpressions();\n return expressions.join(', ');\n }\n}\n","import {\n EpmQueryBuilderOptions,\n MeasureConfig,\n} from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\n\nexport class BaseAnalyticalFunctions {\n protected options: EpmQueryBuilderOptions;\n\n constructor(options: EpmQueryBuilderOptions) {\n this.options = options;\n }\n\n buildWindowFunction(measure: MeasureConfig, windowSpec?: string): string {\n const baseAggregation = this.buildBasicAggregation(measure);\n const partitionBy = this.extractPartitionColumns();\n const orderBy = this.extractOrderColumns();\n\n let windowClause = 'OVER (';\n\n if (partitionBy.length > 0) {\n windowClause += `PARTITION BY ${partitionBy.join(', ')} `;\n }\n\n if (orderBy.length > 0) {\n windowClause += `ORDER BY ${orderBy.join(', ')} `;\n }\n\n if (windowSpec) {\n windowClause += windowSpec;\n }\n\n windowClause += ')';\n\n return `${baseAggregation} ${windowClause}`;\n }\n\n buildRankingFunction(\n measure: MeasureConfig,\n rankType: 'ROW_NUMBER' | 'RANK' | 'DENSE_RANK' | 'PERCENT_RANK' = 'ROW_NUMBER',\n ): string {\n const orderBy = this.extractOrderColumns();\n const partitionBy = this.extractPartitionColumns();\n\n let windowClause = 'OVER (';\n\n if (partitionBy.length > 0) {\n windowClause += `PARTITION BY ${partitionBy.join(', ')} `;\n }\n\n if (orderBy.length > 0) {\n windowClause += `ORDER BY ${orderBy.join(', ')}`;\n }\n\n windowClause += ')';\n\n return `${rankType}() ${windowClause}`;\n }\n\n buildLagLeadFunction(\n measure: MeasureConfig,\n functionType: 'LAG' | 'LEAD',\n offset = 1,\n defaultValue?: string,\n ): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n const partitionBy = this.extractPartitionColumns();\n const orderBy = this.extractOrderColumns();\n\n let windowClause = 'OVER (';\n\n if (partitionBy.length > 0) {\n windowClause += `PARTITION BY ${partitionBy.join(', ')} `;\n }\n\n if (orderBy.length > 0) {\n windowClause += `ORDER BY ${orderBy.join(', ')}`;\n }\n\n windowClause += ')';\n\n const params = [columnRef, offset.toString()];\n if (defaultValue !== undefined) {\n params.push(defaultValue);\n }\n\n return `${functionType}(${params.join(', ')}) ${windowClause}`;\n }\n\n buildPercentileFunction(measure: MeasureConfig, percentile: number, continuous = true): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n const functionName = continuous ? 'PERCENTILE_CONT' : 'PERCENTILE_DISC';\n\n return `${functionName}(${percentile}) WITHIN GROUP (ORDER BY ${columnRef})`;\n }\n\n buildNtileFunction(measure: MeasureConfig, buckets: number): string {\n const partitionBy = this.extractPartitionColumns();\n const orderBy = this.extractOrderColumns();\n\n let windowClause = 'OVER (';\n\n if (partitionBy.length > 0) {\n windowClause += `PARTITION BY ${partitionBy.join(', ')} `;\n }\n\n if (orderBy.length > 0) {\n windowClause += `ORDER BY ${orderBy.join(', ')}`;\n }\n\n windowClause += ')';\n\n return `NTILE(${buckets}) ${windowClause}`;\n }\n\n buildMovingAggregation(\n measure: MeasureConfig,\n aggregationType: string,\n windowSize: number,\n ): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n const partitionBy = this.extractPartitionColumns();\n const orderBy = this.extractOrderColumns();\n\n let windowClause = 'OVER (';\n\n if (partitionBy.length > 0) {\n windowClause += `PARTITION BY ${partitionBy.join(', ')} `;\n }\n\n if (orderBy.length > 0) {\n windowClause += `ORDER BY ${orderBy.join(', ')} `;\n }\n\n windowClause += `ROWS ${windowSize} PRECEDING)`;\n\n return `${aggregationType.toUpperCase()}(${columnRef}) ${windowClause}`;\n }\n\n buildCumulativeAggregation(measure: MeasureConfig, aggregationType: string): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n const partitionBy = this.extractPartitionColumns();\n const orderBy = this.extractOrderColumns();\n\n let windowClause = 'OVER (';\n\n if (partitionBy.length > 0) {\n windowClause += `PARTITION BY ${partitionBy.join(', ')} `;\n }\n\n if (orderBy.length > 0) {\n windowClause += `ORDER BY ${orderBy.join(', ')} `;\n }\n\n windowClause += 'ROWS UNBOUNDED PRECEDING)';\n\n return `${aggregationType.toUpperCase()}(${columnRef}) ${windowClause}`;\n }\n\n protected buildBasicAggregation(measure: MeasureConfig): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n const aggregationType = measure.aggregationType || 'SUM';\n\n return `${aggregationType.toUpperCase()}(${columnRef})`;\n }\n\n protected extractPartitionColumns(): string[] {\n const rows = this.options.rows || [];\n return rows.map((row) =>\n BaseUtilities.buildColumnReference(row.tableName, row.columnName || row.id),\n );\n }\n\n protected extractOrderColumns(): string[] {\n if (!this.options.orderBy?.length) {\n return [];\n }\n\n return this.options.orderBy.map((order) => {\n const direction = order.type === 'DESC' ? 'DESC' : 'ASC';\n const column = BaseUtilities.buildColumnReference(\n order.tableName,\n order.columnName || order.id,\n );\n return `${column} ${direction}`;\n });\n }\n}\n","import {\n EpmQueryBuilderOptions,\n MeasureConfig,\n} from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\n\nexport class BaseAdvancedAggregations {\n protected options: EpmQueryBuilderOptions;\n\n constructor(options: EpmQueryBuilderOptions) {\n this.options = options;\n }\n\n buildArrayAggregation(measure: MeasureConfig, distinct = false): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n const distinctClause = distinct ? 'DISTINCT ' : '';\n\n return `ARRAY_AGG(${distinctClause}${columnRef})`;\n }\n\n buildStringAggregation(measure: MeasureConfig, separator = ', ', distinct = false): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n const distinctClause = distinct ? 'DISTINCT ' : '';\n\n return `STRING_AGG(${distinctClause}${columnRef}, '${separator}')`;\n }\n\n buildJsonAggregation(measure: MeasureConfig, distinct = false): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n const distinctClause = distinct ? 'DISTINCT ' : '';\n\n return `JSON_AGG(${distinctClause}${columnRef})`;\n }\n\n buildJsonObjectAggregation(keyColumn: string, valueColumn: string): string {\n return `JSON_OBJECT_AGG(${keyColumn}, ${valueColumn})`;\n }\n\n buildApproximateCountDistinct(measure: MeasureConfig): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n\n return `APPROX_COUNT_DISTINCT(${columnRef})`;\n }\n\n buildCorrelation(measure1: MeasureConfig, measure2: MeasureConfig): string {\n const columnRef1 = BaseUtilities.buildColumnReference(\n measure1.tableName,\n measure1.columnName || measure1.id,\n );\n const columnRef2 = BaseUtilities.buildColumnReference(\n measure2.tableName,\n measure2.columnName || measure2.id,\n );\n\n return `CORR(${columnRef1}, ${columnRef2})`;\n }\n\n buildCovariance(measure1: MeasureConfig, measure2: MeasureConfig, population = false): string {\n const columnRef1 = BaseUtilities.buildColumnReference(\n measure1.tableName,\n measure1.columnName || measure1.id,\n );\n const columnRef2 = BaseUtilities.buildColumnReference(\n measure2.tableName,\n measure2.columnName || measure2.id,\n );\n const functionName = population ? 'COVAR_POP' : 'COVAR_SAMP';\n\n return `${functionName}(${columnRef1}, ${columnRef2})`;\n }\n\n buildRegressionStats(\n xMeasure: MeasureConfig,\n yMeasure: MeasureConfig,\n statType: 'SLOPE' | 'INTERCEPT' | 'R2',\n ): string {\n const xColumnRef = BaseUtilities.buildColumnReference(\n xMeasure.tableName,\n xMeasure.columnName || xMeasure.id,\n );\n const yColumnRef = BaseUtilities.buildColumnReference(\n yMeasure.tableName,\n yMeasure.columnName || yMeasure.id,\n );\n\n switch (statType) {\n case 'SLOPE':\n return `REGR_SLOPE(${yColumnRef}, ${xColumnRef})`;\n case 'INTERCEPT':\n return `REGR_INTERCEPT(${yColumnRef}, ${xColumnRef})`;\n case 'R2':\n return `REGR_R2(${yColumnRef}, ${xColumnRef})`;\n default:\n return `REGR_SLOPE(${yColumnRef}, ${xColumnRef})`;\n }\n }\n\n buildBitAggregations(measure: MeasureConfig, operation: 'AND' | 'OR' | 'XOR'): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n\n switch (operation) {\n case 'AND':\n return `BIT_AND(${columnRef})`;\n case 'OR':\n return `BIT_OR(${columnRef})`;\n case 'XOR':\n return `BIT_XOR(${columnRef})`;\n default:\n return `BIT_AND(${columnRef})`;\n }\n }\n\n buildBoolAggregations(measure: MeasureConfig, operation: 'AND' | 'OR'): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n\n switch (operation) {\n case 'AND':\n return `BOOL_AND(${columnRef})`;\n case 'OR':\n return `BOOL_OR(${columnRef})`;\n default:\n return `BOOL_AND(${columnRef})`;\n }\n }\n\n buildGeometricMean(measure: MeasureConfig): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n\n return `EXP(AVG(LN(${columnRef})))`;\n }\n\n buildHarmonicMean(measure: MeasureConfig): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n\n return `COUNT(${columnRef}) / SUM(1.0 / ${columnRef})`;\n }\n}\n","import {\n MeasureConfig,\n EpmQueryBuilderOptions,\n} from '@epm-query-builder/types/query-builder-types';\nimport { BaseAdvancedAggregations } from '@epm-query-builder/base/BaseAdvancedAggregations';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\n\nexport class DuckDbAdvancedAggregations extends BaseAdvancedAggregations {\n constructor(options: EpmQueryBuilderOptions) {\n super(options);\n }\n\n buildHistogramAggregation(measure: MeasureConfig, binCount = 10): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n\n return `HISTOGRAM(${columnRef}) WITH ${binCount} BINS`;\n }\n\n buildReservoirSample(measure: MeasureConfig, sampleSize: number): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n\n return `RESERVOIR_SAMPLE(${columnRef}, ${sampleSize})`;\n }\n\n buildQuantileAggregation(measure: MeasureConfig, quantiles: number[]): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n const quantileList = quantiles.join(', ');\n\n return `QUANTILE(${columnRef}, [${quantileList}])`;\n }\n\n buildMadAggregation(measure: MeasureConfig): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n\n return `MAD(${columnRef})`;\n }\n\n buildModeAggregation(measure: MeasureConfig): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n\n return `MODE(${columnRef})`;\n }\n\n buildProductAggregation(measure: MeasureConfig): string {\n const columnRef = BaseUtilities.buildColumnReference(\n measure.tableName,\n measure.columnName || measure.id,\n );\n\n return `PRODUCT(${columnRef})`;\n }\n}\n","import { BaseMeasureBuilder } from '@epm-query-builder/base/BaseMeasureBuilder';\nimport {\n MeasureConfig,\n FilterConfig,\n EpmQueryBuilderOptions,\n SuperFilterChild,\n} from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\nimport { BaseAnalyticalFunctions } from '@epm-query-builder/base/BaseAnalyticalFunctions';\nimport { BaseAdvancedAggregations } from '@epm-query-builder/base/BaseAdvancedAggregations';\nimport { DuckDbAdvancedAggregations } from './DuckDbAdvancedAggregations';\nimport { SOURCE_TYPES } from '@epm-query-builder/constants/Source';\n\nexport class DuckDbMeasureBuilder extends BaseMeasureBuilder {\n private analyticalFunctions: BaseAnalyticalFunctions;\n private advancedAggregations: BaseAdvancedAggregations;\n private duckDbAdvancedAggregations: DuckDbAdvancedAggregations;\n\n constructor(options: EpmQueryBuilderOptions) {\n super(options);\n this.analyticalFunctions = new BaseAnalyticalFunctions(options);\n this.advancedAggregations = new BaseAdvancedAggregations(options);\n this.duckDbAdvancedAggregations = new DuckDbAdvancedAggregations(options);\n }\n\n buildMeasureSelects(): string[] {\n const measures = this.getMeasures();\n const columns: string[] = [];\n\n measures.forEach((measure) => {\n let measureExpr: string;\n if (this.isMeasureType(measure)) {\n measureExpr = this.buildCalculatedMeasure(measure);\n } else if (this.isAnalyticalMeasure(measure)) {\n measureExpr = this.buildAnalyticalMeasure(measure, measure.aggregationType || 'SUM');\n } else if (this.isAdvancedAggregation(measure)) {\n measureExpr = this.buildAdvancedAggregation(measure, measure.aggregationType || 'SUM');\n } else {\n measureExpr = this.buildDuckDbAggregation(measure);\n }\n\n columns.push(measureExpr);\n\n if (this.options.isCrossHighlightEnabled && this.hasCrossHighlightFilters()) {\n const crossHighlightExpr = this.buildCrossHighlightMeasure(measure);\n const alias = measure.label || measure.columnName;\n columns.push(`${crossHighlightExpr} AS \"${alias}_CrossHighlight\"`);\n }\n });\n\n this.addCustomMeasures(columns);\n this.addDimensionIdMeasures(columns);\n\n return columns;\n }\n\n buildMeasureFilterCTE(): string {\n const measureFilters = this.extractMeasureFilters();\n\n if (measureFilters.length === 0) {\n return '';\n }\n\n const filterCTEs = measureFilters\n .filter((filter): filter is FilterConfig => 'filterType' in filter)\n .map((filter, index) => this.generateMeasureFilterCTE(filter, index + 1));\n\n return filterCTEs.join(',\\n');\n }\n\n buildHavingClause(): string {\n const measureFilters = this.extractMeasureFilters();\n\n if (measureFilters.length === 0) {\n return '';\n }\n\n const conditions = measureFilters\n .filter((filter): filter is FilterConfig => 'filterType' in filter)\n .map((filter) => this.buildMeasureFilterCondition(filter))\n .filter((condition) => condition);\n\n if (conditions.length === 0) {\n return '';\n }\n\n const combined = BaseUtilities.combineConditions(conditions, 'AND');\n\n const dims = this.extractDimensions();\n if (dims.length > 0) {\n const isLeaf = dims.map((d) => `GROUPING(${d}) = 0`).join(' AND ');\n return `((${isLeaf}) AND (${combined})) OR (NOT (${isLeaf}))`;\n }\n\n return combined;\n }\n\n protected buildDuckDbAggregation(measure: MeasureConfig): string {\n const aggregationType = this.mapDuckDbAggregationType(measure.aggregationType);\n const originalAgg = measure.aggregationType?.toUpperCase();\n const hasAggregation = measure.aggregationType && measure.aggregationType.trim() !== '';\n\n const source = BaseUtilities.getSource(this.options);\n const isBlend = source === SOURCE_TYPES.BLEND;\n if (isBlend) {\n const actualColumnId = BaseUtilities.extractColumnIdFromHierarchy(measure.id);\n const tableForBlend =\n measure.tableName || BaseUtilities.getDefaultTableNameFromOptions(this.options) || '';\n\n // If no aggregation type, use column name directly without prefix for the alias\n // but still apply SUM for the aggregation to satisfy GROUP BY requirements\n const aliasName = hasAggregation\n ? `${(measure.aggregationType || aggregationType).toUpperCase()}__${actualColumnId}`\n : actualColumnId;\n const qualifiedInnerRef = `\"${tableForBlend}\".\"${aliasName}\"`;\n\n // If no aggregation type, apply SUM but use clean alias without prefix\n if (!hasAggregation) {\n return `SUM(${qualifiedInnerRef}) as \"${aliasName}\"`;\n }\n\n if (originalAgg === 'FIRST') {\n return `MIN(${qualifiedInnerRef}) as \"${aliasName}\"`;\n }\n if (originalAgg === 'LAST') {\n return `MAX(${qualifiedInnerRef}) as \"${aliasName}\"`;\n }\n if (\n originalAgg === 'COUNT_DISTINCT' ||\n originalAgg === 'DISTINCT_COUNT' ||\n originalAgg === 'DISTINCTCOUNT'\n ) {\n return `COUNT(DISTINCT ${qualifiedInnerRef}) as \"${aliasName}\"`;\n }\n\n return `${aggregationType}(${qualifiedInnerRef}) as \"${aliasName}\"`;\n }\n\n let columnRef: string;\n if (this.options.databaseDetails?.databaseType === 'duckdb') {\n const actualColumnId = BaseUtilities.extractColumnIdFromHierarchy(measure.id);\n columnRef = `\"${actualColumnId}\"`;\n } else {\n const actualColumnId = BaseUtilities.extractColumnIdFromHierarchy(measure.id);\n const effectiveColumnName = measure.columnName || actualColumnId;\n columnRef = `${measure.tableName}.${effectiveColumnName}`;\n }\n\n let aggregationExpr: string;\n\n // If no aggregation type, apply default SUM aggregation but use clean alias without prefix\n if (!hasAggregation) {\n aggregationExpr = `SUM(${columnRef}) as ${columnRef}`;\n } else if (originalAgg === 'FIRST') {\n aggregationExpr = `MIN(${columnRef}) as \"FIRST__${columnRef.replace(/\"/g, '')}\"`;\n } else if (originalAgg === 'LAST') {\n aggregationExpr = `MAX(${columnRef}) as \"LAST__${columnRef.replace(/\"/g, '')}\"`;\n } else {\n switch (aggregationType) {\n case 'COUNT':\n if (\n measure.aggregationType?.toUpperCase() === 'COUNT_DISTINCT' ||\n measure.aggregationType?.toUpperCase() === 'DISTINCT_COUNT' ||\n measure.aggregationType?.toUpperCase() === 'DISTINCTCOUNT'\n ) {\n aggregationExpr = `COUNT(DISTINCT ${columnRef}) as \"COUNT_DISTINCT__${columnRef.replace(/\"/g, '')}\"`;\n } else {\n aggregationExpr = `COUNT(${columnRef}) as \"COUNT__${columnRef.replace(/\"/g, '')}\"`;\n }\n break;\n case 'STRING_AGG':\n aggregationExpr = `STRING_AGG(${columnRef}) as \"STRING_AGG__${columnRef.replace(/\"/g, '')}\"`;\n break;\n case 'MEDIAN':\n aggregationExpr = `MEDIAN(${columnRef}) as \"MEDIAN__${columnRef.replace(/\"/g, '')}\"`;\n break;\n case 'MODE':\n aggregationExpr = `MODE(${columnRef}) as \"MODE__${columnRef.replace(/\"/g, '')}\"`;\n break;\n case 'CONCATENATED':\n aggregationExpr = `STRING_AGG(${columnRef}) as \"CONCATENATED__${columnRef.replace(/\"/g, '')}\"`;\n break;\n case 'CONCATENATED_IDS':\n aggregationExpr = `STRING_AGG(${columnRef}) as \"CONCATENATED_IDS__${columnRef.replace(/\"/g, '')}\"`;\n break;\n default:\n aggregationExpr = `${aggregationType}(${columnRef}) as \"${aggregationType}__${columnRef.replace(/\"/g, '')}\"`;\n }\n }\n\n if (this.needsFilterClause()) {\n const filterCondition = this.buildMeasureFilterForAggregation();\n if (this.options.databaseDetails?.databaseType === 'duckdb') {\n return `${aggregationExpr} FILTER (WHERE ${filterCondition})`;\n }\n return `${aggregationExpr} FILTER (WHERE ${filterCondition}) AS \"${measure.label}\"`;\n }\n\n if (this.options.databaseDetails?.databaseType === 'duckdb') {\n return aggregationExpr;\n }\n return `${aggregationExpr} AS \"${measure.label}\"`;\n }\n\n private mapDuckDbAggregationType(aggregationType?: string): string {\n if (!aggregationType) return 'SUM';\n\n const duckDbMapping: Record<string, string> = {\n SUM: 'SUM',\n COUNT: 'COUNT',\n AVG: 'AVG',\n MIN: 'MIN',\n MAX: 'MAX',\n\n FIRST: 'MIN',\n LAST: 'MAX',\n STANDARD_DEVIATION: 'STDDEV_POP',\n VARIANCE: 'VAR_POP',\n COUNT_DISTINCT: 'COUNT',\n MEDIAN: 'MEDIAN',\n MODE: 'MODE',\n\n CONCATENATED: 'STRING_AGG',\n CONCATENATED_IDS: 'STRING_AGG',\n\n DISTINCTCOUNT: 'COUNT',\n DISTINCT_COUNT: 'COUNT',\n COUNTA: 'COUNT',\n AVERAGE: 'AVG',\n MINIMUM: 'MIN',\n MAXIMUM: 'MAX',\n };\n\n return duckDbMapping[aggregationType.toUpperCase()] || aggregationType.toUpperCase();\n }\n\n private extractMeasureFilters(): FilterConfig[] {\n if (!this.options.superFilters?.children) {\n return [];\n }\n\n const measureFilters: FilterConfig[] = [];\n this.extractMeasureFiltersRecursively(this.options.superFilters.children, measureFilters);\n return measureFilters;\n }\n\n private extractMeasureFiltersRecursively(\n children: SuperFilterChild[],\n measureFilters: FilterConfig[],\n ): void {\n children.forEach((child) => {\n if (child.filters) {\n const filter = child.filters;\n const isMeasureFilterType = filter.filterType === 'MEASURE';\n const hasMeasureColumnType = Array.isArray(filter.columnType)\n ? filter.columnType.some((type) => type?.toUpperCase() === 'MEASURE')\n : false;\n const isAggregatedRange =\n filter.filterType === 'RANGE' &&\n Array.isArray(filter.aggregationType) &&\n filter.aggregationType.length > 0;\n\n if (isMeasureFilterType || hasMeasureColumnType || isAggregatedRange) {\n measureFilters.push(filter);\n }\n }\n\n if (child.children) {\n this.extractMeasureFiltersRecursively(child.children, measureFilters);\n }\n });\n }\n\n private generateMeasureFilterCTE(filter: FilterConfig, counter: number): string {\n const variableName = `measure_filter_${counter}`;\n\n if (!filter.rangeFilter?.length) {\n return '';\n }\n\n const tableName = filter.tableNames?.[0] || '';\n const aggregationType = this.mapDuckDbAggregationType(filter.aggregationType?.[0]);\n const columnRef = this.resolveColumnRef(filter);\n\n const conditions = this.buildRangeConditionsForAggregation(columnRef, filter, aggregationType);\n\n const dims = this.extractDimensions();\n if (dims.length === 0) {\n return '';\n }\n const selectDims = dims.map((d, idx) => `${d} AS __mf_dim${idx + 1}`).join(', ');\n const groupByDims = dims.join(', ');\n\n return `${variableName} AS (\n SELECT ${selectDims}\n FROM ${tableName}\n GROUP BY ${groupByDims}\n HAVING ${conditions.join(' AND ')}\n )`;\n }\n\n private buildMeasureFilterCondition(filter: FilterConfig): string {\n if (!filter.rangeFilter?.length) {\n return '';\n }\n\n const aggregationType = this.mapDuckDbAggregationType(filter.aggregationType?.[0]);\n const columnRef = this.resolveColumnRef(filter);\n const conditions = this.buildRangeConditionsForAggregation(columnRef, filter, aggregationType);\n return conditions.length === 1 ? conditions[0] : `(${conditions.join(' AND ')})`;\n }\n\n private needsFilterClause(): boolean {\n return false;\n }\n\n private buildMeasureFilterForAggregation(): string {\n return '1=1';\n }\n\n buildMeasureFilterWhereClause(): string {\n const measureFilters = this.extractMeasureFilters();\n if (measureFilters.length === 0) {\n return '';\n }\n const dims = this.extractDimensions();\n if (dims.length === 0) {\n return '';\n }\n\n const clauses: string[] = [];\n let counter = 0;\n for (const f of measureFilters) {\n if (!('filterType' in f)) continue;\n if (!f.rangeFilter?.length) continue;\n counter += 1;\n const eqs = dims.map((d, idx) => `${d} = mf.__mf_dim${idx + 1}`).join(' AND ');\n clauses.push(`EXISTS (SELECT 1 FROM measure_filter_${counter} mf WHERE ${eqs})`);\n }\n return BaseUtilities.combineConditions(clauses.filter(Boolean), 'AND');\n }\n\n private extractDimensions(): string[] {\n const rowDimensions = BaseUtilities.buildDimensionReference(this.options.rows, this.options);\n const columnDimensions = BaseUtilities.buildDimensionReference(\n this.options.columns,\n this.options,\n );\n return [...rowDimensions, ...columnDimensions];\n }\n\n private combineFilterConditions(conditions: string[], operator: 'AND' | 'OR' = 'AND'): string {\n return BaseUtilities.combineConditions(conditions, operator);\n }\n\n private hasCrossHighlightFilters(): boolean {\n return Boolean(\n this.options.superFilters?.children?.some(\n (child) =>\n Array.isArray(child.filters) &&\n child.filters.some((filter: FilterConfig) => filter.isCrossHighlight),\n ),\n );\n }\n\n private buildCrossHighlightMeasure(measure: MeasureConfig): string {\n const baseAggregation = this.buildDuckDbAggregation(measure);\n const crossHighlightConditions = this.getCrossHighlightConditions();\n\n if (!crossHighlightConditions.length) {\n return baseAggregation;\n }\n\n const whereClause = crossHighlightConditions.join(' AND ');\n return `CASE WHEN ${whereClause} THEN ${baseAggregation} ELSE NULL END`;\n }\n\n private getCrossHighlightConditions(): string[] {\n const conditions: string[] = [];\n\n if (!this.options.superFilters?.children) return conditions;\n\n this.options.superFilters.children.forEach((child) => {\n if (Array.isArray(child.filters)) {\n child.filters.forEach((filter: FilterConfig) => {\n if (\n filter.isCrossHighlight &&\n filter.columnNames?.length &&\n filter.valuesFilter?.length\n ) {\n const tableName =\n filter.tableNames?.[0] || BaseUtilities.getDefaultTableNameFromOptions(this.options);\n const columnName = filter.columnNames[0];\n const columnRef = `\"${tableName}\".\"${columnName}\"`;\n\n if (filter.valuesFilter.length === 1) {\n const value = filter.valuesFilter[0];\n const displayValue = typeof value === 'object' ? value.id : value;\n conditions.push(`${columnRef} = '${displayValue}'`);\n } else {\n const valuesList = filter.valuesFilter\n .map((v) => `'${typeof v === 'object' ? v.id : v}'`)\n .join(', ');\n conditions.push(`${columnRef} IN (${valuesList})`);\n }\n }\n });\n }\n });\n\n return conditions;\n }\n\n private addCustomMeasures(columns: string[]): void {\n if (!this.options.customMeasures?.length) return;\n\n this.options.customMeasures.forEach((customMeasure) => {\n const duckDbMeasure = this.convertCustomMeasure(customMeasure);\n if (duckDbMeasure && duckDbMeasure.trim()) {\n columns.push(duckDbMeasure);\n }\n });\n }\n\n private convertCustomMeasure(measure: string): string {\n if (measure.includes('CONCATENATEX')) {\n const convertedMeasure = measure\n .replace(/CONCATENATEX\\s*\\(/gi, 'STRING_AGG(')\n .replace(/,\\s*\",\"\\s*\\)/gi, \", ',' ORDER BY 1)\")\n .replace(/,\\s*\"\\|\"\\s*\\)/gi, \", '|' ORDER BY 1)\");\n return convertedMeasure;\n }\n\n return measure;\n }\n\n private addDimensionIdMeasures(columns: string[]): void {\n if (!this.options.dimensionIdMappings) return;\n\n Object.entries(this.options.dimensionIdMappings).forEach(([tableName, mappings]) => {\n if (mappings && mappings.length > 0) {\n const concatenatedColumns = mappings\n .map((mapping) => `\"${tableName}\".\"${mapping.targetField}\"`)\n .join(\" || '|' || \");\n\n columns.push(`${concatenatedColumns} AS \"${tableName}_ConcatenatedIds\"`);\n }\n });\n }\n\n private isAnalyticalMeasure(measure: MeasureConfig): boolean {\n const analyticalTypes = [\n 'ROW_NUMBER',\n 'RANK',\n 'DENSE_RANK',\n 'PERCENT_RANK',\n 'LAG',\n 'LEAD',\n 'CUMULATIVE_SUM',\n 'CUMULATIVE_COUNT',\n 'MOVING_AVG',\n 'PERCENTILE_25',\n 'PERCENTILE_75',\n 'MEDIAN',\n ];\n return Boolean(\n measure.aggregationType && analyticalTypes.includes(measure.aggregationType.toUpperCase()),\n );\n }\n\n private isAdvancedAggregation(measure: MeasureConfig): boolean {\n const advancedTypes = [\n 'ARRAY_AGG',\n 'ARRAY_AGG_DISTINCT',\n 'JSON_AGG',\n 'APPROX_COUNT_DISTINCT',\n 'PRODUCT',\n 'GEOMETRIC_MEAN',\n 'HARMONIC_MEAN',\n 'MAD',\n 'STRING_AGG_SEMICOLON',\n 'STRING_AGG_PIPE',\n 'HISTOGRAM',\n 'QUANTILES',\n 'RESERVOIR_SAMPLE',\n 'BIT_AND',\n 'BIT_OR',\n 'BIT_XOR',\n 'BOOL_AND',\n 'BOOL_OR',\n ];\n return Boolean(\n measure.aggregationType && advancedTypes.includes(measure.aggregationType.toUpperCase()),\n );\n }\n\n buildAnalyticalMeasure(measure: MeasureConfig, analyticalType: string): string {\n switch (analyticalType.toUpperCase()) {\n case 'ROW_NUMBER':\n return this.analyticalFunctions.buildRankingFunction(measure, 'ROW_NUMBER');\n case 'RANK':\n return this.analyticalFunctions.buildRankingFunction(measure, 'RANK');\n case 'DENSE_RANK':\n return this.analyticalFunctions.buildRankingFunction(measure, 'DENSE_RANK');\n case 'PERCENT_RANK':\n return this.analyticalFunctions.buildRankingFunction(measure, 'PERCENT_RANK');\n case 'LAG':\n return this.analyticalFunctions.buildLagLeadFunction(measure, 'LAG', 1);\n case 'LEAD':\n return this.analyticalFunctions.buildLagLeadFunction(measure, 'LEAD', 1);\n case 'CUMULATIVE_SUM':\n return this.analyticalFunctions.buildCumulativeAggregation(measure, 'SUM');\n case 'CUMULATIVE_COUNT':\n return this.analyticalFunctions.buildCumulativeAggregation(measure, 'COUNT');\n case 'MOVING_AVG':\n return this.analyticalFunctions.buildMovingAggregation(measure, 'AVG', 3);\n case 'PERCENTILE_25':\n return this.analyticalFunctions.buildPercentileFunction(measure, 0.25);\n case 'PERCENTILE_75':\n return this.analyticalFunctions.buildPercentileFunction(measure, 0.75);\n case 'MEDIAN':\n return this.buildDuckDbAggregation(measure);\n default:\n return this.buildDuckDbAggregation(measure);\n }\n }\n\n buildAdvancedAggregation(\n measure: MeasureConfig,\n aggregationType: string,\n options?: Record<string, unknown>,\n ): string {\n switch (aggregationType.toUpperCase()) {\n case 'STRING_AGG_SEMICOLON':\n return this.advancedAggregations.buildStringAggregation(measure, '; ', false);\n case 'STRING_AGG_PIPE':\n return this.advancedAggregations.buildStringAggregation(measure, ' | ', false);\n case 'HISTOGRAM': {\n const binCount = (options?.binCount as number) || 10;\n return this.duckDbAdvancedAggregations.buildHistogramAggregation(measure, binCount);\n }\n case 'QUANTILES': {\n const quantiles = (options?.quantiles as number[]) || [0.25, 0.5, 0.75];\n return this.duckDbAdvancedAggregations.buildQuantileAggregation(measure, quantiles);\n }\n case 'RESERVOIR_SAMPLE': {\n const sampleSize = (options?.sampleSize as number) || 100;\n return this.duckDbAdvancedAggregations.buildReservoirSample(measure, sampleSize);\n }\n case 'BIT_AND':\n return this.advancedAggregations.buildBitAggregations(measure, 'AND');\n case 'BIT_OR':\n return this.advancedAggregations.buildBitAggregations(measure, 'OR');\n case 'BIT_XOR':\n return this.advancedAggregations.buildBitAggregations(measure, 'XOR');\n case 'BOOL_AND':\n return this.advancedAggregations.buildBoolAggregations(measure, 'AND');\n case 'BOOL_OR':\n return this.advancedAggregations.buildBoolAggregations(measure, 'OR');\n default:\n return this.buildDuckDbAggregation(measure);\n }\n }\n\n private resolveColumnRef(filter: FilterConfig): string {\n if (this.options.databaseDetails?.databaseType === 'duckdb') {\n const actualId = BaseUtilities.extractColumnIdFromHierarchy(\n filter.columnIds?.[0] ||\n `${filter.tableNames?.[0] || ''}[${filter.columnNames?.[0] || ''}]`,\n );\n return `\"${actualId}\"`;\n }\n const tableName = filter.tableNames?.[0] || '';\n const column = filter.columnNames?.[0] || '';\n return `${tableName}.${column}`;\n }\n\n private buildRangeConditionsForAggregation(\n columnRef: string,\n filter: FilterConfig,\n aggregationType: string,\n ): string[] {\n const conditions: string[] = [];\n filter.rangeFilter?.forEach((range) => {\n const rangeParts: string[] = [];\n if (range.from !== undefined && range.fromCondition) {\n const op = this.normalizeOperator(range.fromCondition);\n if (op === 'IS NULL' || op === 'IS NOT NULL') {\n rangeParts.push(`${aggregationType}(${columnRef}) ${op}`);\n } else {\n const value = typeof range.from === 'string' ? `'${range.from}'` : range.from;\n rangeParts.push(`${aggregationType}(${columnRef}) ${op} ${value}`);\n }\n }\n if (range.to !== undefined && range.toCondition) {\n const op = this.normalizeOperator(range.toCondition);\n if (op === 'IS NULL' || op === 'IS NOT NULL') {\n rangeParts.push(`${aggregationType}(${columnRef}) ${op}`);\n } else {\n const value = typeof range.to === 'string' ? `'${range.to}'` : range.to;\n rangeParts.push(`${aggregationType}(${columnRef}) ${op} ${value}`);\n }\n }\n if (rangeParts.length === 0 && range.operator && range.value !== undefined) {\n const op = this.normalizeOperator(range.operator);\n if (op === 'IS NULL' || op === 'IS NOT NULL') {\n rangeParts.push(`${aggregationType}(${columnRef}) ${op}`);\n } else {\n const value = typeof range.value === 'string' ? `'${range.value}'` : range.value;\n rangeParts.push(`${aggregationType}(${columnRef}) ${op} ${value}`);\n }\n }\n if (rangeParts.length > 0) {\n const joiner = (range.logicalOperator || 'AND').toUpperCase() === 'OR' ? 'OR' : 'AND';\n conditions.push(\n rangeParts.length === 1 ? rangeParts[0] : `(${rangeParts.join(` ${joiner} `)})`,\n );\n }\n });\n return conditions;\n }\n\n private normalizeOperator(op: string): string {\n return BaseUtilities.normalizeComparisonOperator(op);\n }\n}\n","import { EpmQueryBuilderOptions } from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\n\n// computes grouping sets and rollup indicators for rollup queries\nexport abstract class BaseRollupBuilder {\n protected options: EpmQueryBuilderOptions;\n\n constructor(options: EpmQueryBuilderOptions) {\n this.options = options;\n }\n\n protected shouldGenerateRollup(): boolean {\n return BaseUtilities.shouldGenerateRollupForOptions(this.options);\n }\n\n protected hasDimensions(): boolean {\n return BaseUtilities.hasDimensionsInOptions(this.options);\n }\n\n // extracts dimension references for rollup\n protected getDimensions(): string[] {\n const rowDimensions = BaseUtilities.buildDimensionReference(this.options.rows, this.options);\n const columnDimensions = BaseUtilities.buildDimensionReference(\n this.options.columns,\n this.options,\n );\n return [...rowDimensions, ...columnDimensions];\n }\n\n // builds grouping sets for subtotal/grand total computation\n // generates hierarchical rollup combinations for rows and columns separately\n // avoiding cross-product combinations that create unwanted blank cells\n protected buildGroupingSets(): string {\n const rowDimensions = BaseUtilities.buildDimensionReference(this.options.rows, this.options);\n const columnDimensions = BaseUtilities.buildDimensionReference(\n this.options.columns,\n this.options,\n );\n\n const allDimensions = [...rowDimensions, ...columnDimensions];\n if (allDimensions.length === 0) {\n return '';\n }\n\n const groupingSets: string[] = [];\n const seenCombinations = new Set<string>();\n\n const addGroupingSet = (dims: string[]) => {\n if (dims.length === 0) {\n if (!seenCombinations.has('()')) {\n groupingSets.push('()');\n seenCombinations.add('()');\n }\n } else {\n const key = dims.join(',');\n if (!seenCombinations.has(key)) {\n groupingSets.push(`(${dims.join(', ')})`);\n seenCombinations.add(key);\n }\n }\n };\n\n addGroupingSet(allDimensions);\n\n for (let i = 0; i < rowDimensions.length; i++) {\n addGroupingSet(rowDimensions.slice(0, i + 1));\n }\n\n for (let i = 0; i < columnDimensions.length; i++) {\n addGroupingSet(columnDimensions.slice(0, i + 1));\n }\n\n const dimPrefix: string[] = [];\n for (const rowDim of rowDimensions) {\n dimPrefix.push(rowDim);\n const colPrefix: string[] = [];\n for (const colDim of columnDimensions) {\n colPrefix.push(colDim);\n const combined = [...dimPrefix, ...colPrefix];\n addGroupingSet(combined);\n }\n }\n\n if (rowDimensions.length > 0 || columnDimensions.length > 0) {\n addGroupingSet([]);\n }\n\n return `GROUPING SETS (${groupingSets.join(', ')})`;\n }\n\n // emits boolean flags to identify totals in output rows\n protected generateRollupIndicators(): string[] {\n const indicators: string[] = [];\n const rowCount = this.options.rows?.length || 0;\n const columnCount = this.options.columns?.length || 0;\n\n if (rowCount > 0) {\n indicators.push(\n 'CASE WHEN GROUPING_ID() & 1 = 1 THEN true ELSE false END AS \"IsRowGrandTotal\"',\n );\n\n for (let i = 1; i < rowCount; i++) {\n const mask = Math.pow(2, i);\n indicators.push(\n `CASE WHEN GROUPING_ID() & ${mask} = ${mask} THEN true ELSE false END AS \"IsDM${i - 1}Total\"`,\n );\n }\n }\n\n if (columnCount > 0) {\n const columnMask = Math.pow(2, rowCount);\n indicators.push(\n `CASE WHEN GROUPING_ID() & ${columnMask} = ${columnMask} THEN true ELSE false END AS \"IsColumnGrandTotal\"`,\n );\n\n for (let i = 1; i < columnCount; i++) {\n const mask = Math.pow(2, rowCount + i);\n indicators.push(\n `CASE WHEN GROUPING_ID() & ${mask} = ${mask} THEN true ELSE false END AS \"IsDM${rowCount + i - 1}Total\"`,\n );\n }\n }\n\n return indicators;\n }\n\n protected buildBasicGroupByClause(): string {\n return BaseUtilities.buildBasicGroupByClauseForOptions(this.options);\n }\n\n // standard combinations generator used for grouping sets\n protected generateCombinations<T>(array: T[], size: number): T[][] {\n if (size === 0) return [[]];\n if (size > array.length) return [];\n\n const combinations: T[][] = [];\n\n for (let i = 0; i <= array.length - size; i++) {\n const head = array[i];\n const tailCombinations = this.generateCombinations(array.slice(i + 1), size - 1);\n\n for (const tail of tailCombinations) {\n combinations.push([head, ...tail]);\n }\n }\n\n return combinations;\n }\n}\n","import { BaseRollupBuilder } from '@epm-query-builder/base/BaseRollupBuilder';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\n\nexport class DuckDbRollupBuilder extends BaseRollupBuilder {\n buildGroupByClause(): string {\n if (!this.shouldGenerateRollup()) {\n return this.buildBasicGroupByClause();\n }\n\n const groupingSets = this.buildGroupingSets();\n if (!groupingSets) {\n return '';\n }\n return `GROUP BY ${groupingSets}`;\n }\n\n buildRollupSelects(): string[] {\n if (!this.shouldGenerateRollup()) {\n return [];\n }\n\n const selects: string[] = [];\n\n selects.push(...this.buildRollupTotalIndicators());\n\n return selects;\n }\n\n buildNullFilterConditions(): string[] {\n if (!this.shouldGenerateRollup()) {\n return [];\n }\n\n const dimensions = this.getDimensions();\n if (dimensions.length === 0) {\n return [];\n }\n\n return dimensions.map((dim) => `${dim} IS NOT NULL`);\n }\n\n private buildGroupingIndicators(): string[] {\n const dimensions = this.getDimensions();\n const indicators: string[] = [];\n dimensions.forEach(() => {\n // intentionally omitted raw GROUPING columns from the sql output, need to handle separately in the case of IB\n });\n return indicators;\n }\n\n private buildRollupTotalIndicators(): string[] {\n const indicators: string[] = [];\n const rowCount = this.options.rows?.length || 0;\n const columnCount = this.options.columns?.length || 0;\n\n if (rowCount > 0) {\n const rowDimensions = this.getRowDimensions();\n\n if (rowDimensions.length > 0) {\n const groupingCondition = rowDimensions\n .map((_, index) => `GROUPING(${rowDimensions[index]}) = 1`)\n .join(' AND ');\n\n indicators.push(\n `CASE WHEN ${groupingCondition} THEN true ELSE false END AS \"[IsRowGrandTotal]\"`,\n );\n\n for (let i = 1; i < rowCount; i++) {\n const partialGroupingCondition = rowDimensions\n .slice(i)\n .map((_, idx) => `GROUPING(${rowDimensions[i + idx]}) = 1`)\n .join(' AND ');\n\n const nonGroupingCondition = rowDimensions\n .slice(0, i)\n .map((_, idx) => `GROUPING(${rowDimensions[idx]}) = 0`)\n .join(' AND ');\n\n const dmCondition =\n i === 1\n ? `(${nonGroupingCondition} AND ${partialGroupingCondition}) OR (${groupingCondition})`\n : `${nonGroupingCondition} AND ${partialGroupingCondition}`;\n\n indicators.push(\n `CASE WHEN ${dmCondition} THEN true ELSE false END AS \"[IsDM${i - 1}Total]\"`,\n );\n }\n }\n }\n\n if (columnCount > 0) {\n const columnDimensions = this.getColumnDimensions();\n\n if (columnDimensions.length > 0) {\n const groupingCondition = columnDimensions\n .map((_, index) => `GROUPING(${columnDimensions[index]}) = 1`)\n .join(' AND ');\n\n indicators.push(\n `CASE WHEN ${groupingCondition} THEN true ELSE false END AS \"[IsColumnGrandTotal]\"`,\n );\n\n for (let i = 1; i < columnCount; i++) {\n const partialGroupingCondition = columnDimensions\n .slice(i)\n .map((_, idx) => `GROUPING(${columnDimensions[i + idx]}) = 1`)\n .join(' AND ');\n\n const nonGroupingCondition = columnDimensions\n .slice(0, i)\n .map((_, idx) => `GROUPING(${columnDimensions[idx]}) = 0`)\n .join(' AND ');\n\n indicators.push(\n `CASE WHEN ${nonGroupingCondition} AND ${partialGroupingCondition} THEN true ELSE false END AS \"[IsDM${rowCount + i - 1}Total]\"`,\n );\n }\n }\n }\n\n return indicators;\n }\n\n private getRowDimensions(): string[] {\n return BaseUtilities.buildDimensionReference(this.options.rows, this.options);\n }\n\n private getColumnDimensions(): string[] {\n return BaseUtilities.buildDimensionReference(this.options.columns, this.options);\n }\n}\n","import { EpmQueryBuilderOptions } from '@epm-query-builder/types/query-builder-types';\n\n// pagination helpers: build limit/offset fragments and metadata\nexport abstract class BasePaginationBuilder {\n protected options: EpmQueryBuilderOptions;\n\n constructor(options: EpmQueryBuilderOptions) {\n this.options = options;\n }\n\n // builds dialect-agnostic limit clause\n protected buildLimitClause(): string {\n const pagination = this.options.pagination;\n const limit = pagination?.limit || pagination?.take;\n if (!pagination || !limit || limit <= 0) {\n return '';\n }\n\n return `LIMIT ${limit}`;\n }\n\n // builds offset clause when offset provided\n protected buildOffsetClause(offset = 0): string {\n if (offset <= 0) {\n return '';\n }\n\n return `OFFSET ${offset}`;\n }\n\n // composes limit and offset when both exist\n protected buildLimitOffsetClause(offset = 0): string {\n const limitClause = this.buildLimitClause();\n const offsetClause = this.buildOffsetClause(offset);\n\n const clauses = [limitClause, offsetClause].filter((clause) => clause);\n return clauses.join(' ');\n }\n\n // derives count selection from a base query for pagination metadata\n protected buildCountQuery(baseQuery: string): string {\n const fromIndex = baseQuery.toLowerCase().indexOf('from');\n if (fromIndex === -1) {\n return '';\n }\n\n const fromClause = baseQuery.substring(fromIndex);\n const orderByIndex = fromClause.toLowerCase().lastIndexOf('order by');\n const limitIndex = fromClause.toLowerCase().lastIndexOf('limit');\n\n let cleanFromClause = fromClause;\n if (orderByIndex !== -1) {\n cleanFromClause = fromClause.substring(0, orderByIndex).trim();\n }\n if (limitIndex !== -1 && (orderByIndex === -1 || limitIndex < orderByIndex)) {\n cleanFromClause = fromClause.substring(0, limitIndex).trim();\n }\n\n return `SELECT COUNT(*) as total ${cleanFromClause}`;\n }\n\n protected hasPagination(): boolean {\n return Boolean(\n this.options.pagination && (this.options.pagination.limit || this.options.pagination.take),\n );\n }\n\n protected getPaginationLimit(): number {\n return this.options.pagination?.limit || this.options.pagination?.take || 100;\n }\n\n // computes basic pagination metadata for consumers\n protected buildPaginationMetadata(\n totalCount: number,\n limit: number,\n offset = 0,\n ): Record<string, unknown> {\n const currentPage = Math.floor(offset / limit) + 1;\n const totalPages = Math.ceil(totalCount / limit);\n const hasNextPage = currentPage < totalPages;\n const hasPreviousPage = currentPage > 1;\n\n return {\n totalCount,\n limit,\n offset,\n currentPage,\n totalPages,\n hasNextPage,\n hasPreviousPage,\n };\n }\n}\n","import { BasePaginationBuilder } from '@epm-query-builder/base/BasePaginationBuilder';\nimport { PaginationConfig } from '@epm-query-builder/types/query-builder-types';\nimport { PaginationError } from '@epm-query-builder/errors/QueryBuilderErrors';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\n\nexport class DuckDbPaginationBuilder extends BasePaginationBuilder {\n buildLimitClause(): string {\n if (!this.options.pagination) {\n return '';\n }\n\n const { skip = 0, limit } = this.options.pagination;\n\n if (limit === undefined || limit <= 0) {\n return '';\n }\n\n if (skip > 0) {\n return `LIMIT ${limit} OFFSET ${skip}`;\n }\n\n return `LIMIT ${limit}`;\n }\n\n buildOffsetClause(): string {\n if (!this.options.pagination?.skip) {\n return '';\n }\n\n return `OFFSET ${this.options.pagination.skip}`;\n }\n\n buildAdditionalWhere(): string {\n const reference = this.options.pagination?.reference;\n\n if (!reference || !reference.command) return '';\n\n switch (reference.command) {\n case 'NEXT_HEIR':\n return this.buildNextHeirWhere(reference);\n case 'SIBLING':\n return this.buildSiblingWhere(reference);\n case 'CHILDREN':\n return this.buildChildrenWhere(reference);\n default:\n return '';\n }\n }\n\n private buildNextHeirWhere(reference: PaginationConfig['reference']): string {\n if (!reference?.dimensions?.length || !reference.nextToken?.length) {\n return '';\n }\n\n if (reference.dimensions.length !== reference.nextToken.length) {\n throw new PaginationError(\n 'NEXT_HEIR',\n 'dimensions and nextToken arrays must have the same length',\n );\n }\n\n const conditions = reference.dimensions\n .map((dim, index) => {\n const tokenValue = reference.nextToken?.[index];\n if (!tokenValue) return null;\n\n const operator = this.getHierarchicalOperator(index, reference.dimensions!.length);\n return `${BaseUtilities.sanitizeIdentifierString(dim)} ${operator} '${tokenValue}'`;\n })\n .filter((condition): condition is string => Boolean(condition));\n\n if (conditions.length === 0) {\n throw new PaginationError(\n 'NEXT_HEIR',\n 'no valid conditions generated from dimensions and nextToken',\n );\n }\n\n const hierarchicalCondition = this.buildHierarchicalCondition(conditions);\n return hierarchicalCondition;\n }\n\n private buildSiblingWhere(reference: PaginationConfig['reference']): string {\n if (!reference?.dimensions?.length || !reference.instances?.length) {\n return '';\n }\n\n if (reference.dimensions.length === 0 || reference.instances.length === 0) {\n throw new PaginationError('SIBLING', 'dimensions and instances cannot be empty');\n }\n\n const parentConditions: string[] = [];\n const siblingConditions: string[] = [];\n\n reference.dimensions.forEach((dim, index) => {\n const instanceValue = reference.instances?.[index];\n if (instanceValue && index < reference.dimensions!.length - 1) {\n parentConditions.push(\n `${BaseUtilities.sanitizeIdentifierString(dim)} = '${instanceValue}'`,\n );\n } else if (instanceValue && index === reference.dimensions!.length - 1) {\n siblingConditions.push(\n `${BaseUtilities.sanitizeIdentifierString(dim)} != '${instanceValue}'`,\n );\n }\n });\n\n const allConditions = [...parentConditions, ...siblingConditions];\n\n if (allConditions.length === 0) {\n throw new PaginationError('SIBLING', 'no valid conditions generated');\n }\n\n return BaseUtilities.combineConditions(allConditions, 'AND');\n }\n\n private buildChildrenWhere(reference: PaginationConfig['reference']): string {\n if (!reference?.dimensions || !reference.instances) {\n return '';\n }\n\n const parentConditions = reference.dimensions\n .slice(0, -1)\n .map((dim, index) => {\n const instanceValue = reference.instances?.[index];\n return instanceValue ? `${dim} = '${instanceValue}'` : null;\n })\n .filter(Boolean);\n\n if (parentConditions.length === 0) {\n return '';\n }\n\n return parentConditions.join(' AND ');\n }\n\n buildPaginationCTE(): string {\n if (!this.options.pagination?.reference?.command) {\n return '';\n }\n\n const { reference } = this.options.pagination;\n\n if (!reference.dimensions) {\n return '';\n }\n\n return `pagination_context AS (\n SELECT ${reference.dimensions.join(', ')}\n FROM (VALUES ${this.buildPaginationValues(reference)}) AS context(${reference.dimensions.join(', ')})\n )`;\n }\n\n private buildPaginationValues(reference: { instances?: string[]; nextToken?: string[] }): string {\n if (!reference.instances || !reference.nextToken) {\n return \"('')\";\n }\n\n const instances = reference.instances.map((val: string) => `'${val}'`).join(', ');\n const tokens = reference.nextToken.map((val: string) => `'${val}'`).join(', ');\n\n return `(${instances}), (${tokens})`;\n }\n\n private getHierarchicalOperator(index: number, totalLevels: number): string {\n if (index < totalLevels - 1) {\n return '>=';\n }\n return '>';\n }\n\n private buildHierarchicalCondition(conditions: string[]): string {\n if (conditions.length === 1) {\n return conditions[0];\n }\n\n const primaryCondition = conditions[0];\n const secondaryConditions = conditions.slice(1);\n\n if (secondaryConditions.length === 0) {\n return primaryCondition;\n }\n\n return `(${primaryCondition} OR (${secondaryConditions.join(' OR ')}))`;\n }\n}\n","import {\n EpmQueryBuilderOptions,\n OrderByConfig,\n RowColumnConfig,\n} from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\n\n// orchestrates order by strategy: rollup, custom, or defaults\nexport abstract class BaseOrderBuilder {\n protected options: EpmQueryBuilderOptions;\n\n constructor(options: EpmQueryBuilderOptions) {\n this.options = options;\n }\n\n buildOrderByClause(): string {\n const orderByClauses = this.buildOrderByClauses();\n\n if (orderByClauses.length === 0) {\n return '';\n }\n\n return `ORDER BY ${orderByClauses.join(', ')}`;\n }\n\n // combines rollup, custom, and default clauses\n protected buildOrderByClauses(): string[] {\n const clauses: string[] = [];\n\n if (this.hasRollupOrdering()) {\n clauses.push(...this.buildRollupOrderClauses());\n }\n\n if (this.options.orderBy?.length) {\n clauses.push(...this.buildCustomOrderClauses());\n } else {\n clauses.push(...this.buildDefaultOrderClauses());\n }\n\n return clauses;\n }\n\n // uses explicit orderBy configs\n protected buildCustomOrderClauses(): string[] {\n if (!this.options.orderBy?.length) {\n return [];\n }\n\n return this.options.orderBy.map((orderBy) => {\n const column = this.resolveOrderByColumn(orderBy);\n return `${column} ${orderBy.type}`;\n });\n }\n\n // falls back to ordering by requested dimensions\n protected buildDefaultOrderClauses(): string[] {\n const clauses: string[] = [];\n\n if (this.options.rows?.length) {\n this.options.rows.forEach((row) => {\n const column = this.formatOrderByColumn(row);\n clauses.push(`${column} ASC`);\n });\n }\n\n if (this.options.columns?.length) {\n this.options.columns.forEach((col) => {\n const column = this.formatOrderByColumn(col);\n clauses.push(`${column} ASC`);\n });\n }\n\n return clauses;\n }\n\n // adds rollup-based ordering when rollup is generated\n protected buildRollupOrderClauses(): string[] {\n const clauses: string[] = [];\n\n if (this.options.rows?.length && !this.options.skipRollup) {\n clauses.push('\"IsRowGrandTotal\" DESC');\n }\n\n if (this.options.columns?.length && !this.options.skipRollup) {\n clauses.push('\"IsColumnGrandTotal\" DESC');\n }\n\n return clauses;\n }\n\n protected resolveOrderByColumn(orderBy: OrderByConfig): string {\n if (orderBy.isColumnPresentInOutput) {\n if (orderBy.aggregationType) {\n return `\"${orderBy.aggregationType}__${orderBy.tableName}[${orderBy.columnName}]\"`;\n }\n return `\"${orderBy.tableName}[${orderBy.columnName}]\"`;\n }\n\n const tableName = orderBy.tableName || '';\n return `${tableName}.${orderBy.columnName}`;\n }\n\n protected formatOrderByColumn(config: RowColumnConfig): string {\n if (config.orderByRef) {\n const tableName = config.tableName || '';\n return `${tableName}.${config.orderByRef}`;\n }\n\n const tableName = config.tableName || '';\n return `${tableName}.${config.columnName}`;\n }\n\n protected handleColumnPresentInOutput(orderBy: OrderByConfig): boolean {\n return Boolean(orderBy.isColumnPresentInOutput);\n }\n\n // ensures correct direction and reference when column is already in output\n protected buildOrderByWithOutput(orderBy: OrderByConfig): string {\n if (!this.handleColumnPresentInOutput(orderBy)) {\n return '';\n }\n\n if (orderBy.aggregationType) {\n const columnRef = `\"${orderBy.aggregationType}__${orderBy.tableName}[${orderBy.columnName}]\"`;\n return `${columnRef} ${this.mapSortDirection(orderBy.type)}`;\n }\n\n const tableName = orderBy.tableName || '';\n const columnRef = `${tableName}.${orderBy.columnName}`;\n const direction = this.mapSortDirection(orderBy.type);\n\n return `${columnRef} ${direction}`;\n }\n\n protected applyExpansionConfig(config: RowColumnConfig): string[] {\n const expansions: string[] = [];\n\n if (!config.expansionConfig) {\n return expansions;\n }\n\n const expansion = config.expansionConfig;\n const baseColumn = `${config.tableName}.${config.columnName}`;\n\n switch (expansion.expansionType?.toLowerCase()) {\n case 'hierarchy':\n if (expansion.hierarchies?.length) {\n expansion.hierarchies.forEach((hierarchy) => {\n expansions.push(`${baseColumn}_${hierarchy}`);\n });\n }\n break;\n case 'date_parts':\n if (expansion.items?.length) {\n expansion.items.forEach((part) => {\n expansions.push(\n `EXTRACT(${part.toUpperCase()} FROM ${baseColumn}) AS ${config.columnName}_${part}`,\n );\n });\n }\n break;\n case 'range':\n if (expansion.start && expansion.end && expansion.step) {\n const steps = Math.ceil(\n (Number(expansion.end) - Number(expansion.start)) / expansion.step,\n );\n for (let i = 0; i <= steps; i++) {\n const value = Number(expansion.start) + i * expansion.step;\n expansions.push(`${value} AS ${config.columnName}_${i}`);\n }\n }\n break;\n default:\n break;\n }\n\n return expansions;\n }\n\n protected mapSortDirection(direction?: string): 'ASC' | 'DESC' {\n return direction?.toUpperCase() === 'DESC' ? 'DESC' : 'ASC';\n }\n\n protected hasRollupOrdering(): boolean {\n return BaseUtilities.shouldGenerateRollupForOptions(this.options);\n }\n\n protected hasDimensions(): boolean {\n return BaseUtilities.hasDimensionsInOptions(this.options);\n }\n\n protected hasCustomOrderBy(): boolean {\n return Boolean(this.options.orderBy?.length);\n }\n}\n","import { BaseOrderBuilder } from '@epm-query-builder/base/BaseOrderBuilder';\nimport { OrderByConfig, RowColumnConfig } from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\n\nexport class DuckDbOrderBuilder extends BaseOrderBuilder {\n buildOrderByClause(): string {\n const orderByClauses = this.buildDuckDbOrderByClauses();\n\n if (orderByClauses.length === 0) {\n return '';\n }\n\n return `ORDER BY ${orderByClauses.join(', ')}`;\n }\n\n private buildDuckDbOrderByClauses(): string[] {\n const clauses: string[] = [];\n\n if (this.hasRollupOrdering()) {\n clauses.push(...this.buildDuckDbRollupOrderClauses());\n }\n\n if (this.options.orderBy?.length) {\n clauses.push(...this.buildDuckDbCustomOrderClauses());\n } else {\n clauses.push(...this.buildDuckDbDefaultOrderClauses());\n }\n\n return clauses;\n }\n\n private buildDuckDbCustomOrderClauses(): string[] {\n if (!this.options.orderBy?.length) {\n return [];\n }\n\n return this.options.orderBy.map((orderBy) => {\n const column = this.resolveDuckDbOrderByColumn(orderBy);\n const direction = this.mapSortDirection(orderBy.type);\n const nullsHandling = this.buildDuckDbNullsHandling(direction);\n\n const isMonth =\n (orderBy.columnName || '').toLowerCase().includes('month') ||\n (orderBy.id || '').toLowerCase().includes('month');\n const isQuarter =\n (orderBy.columnName || '').toLowerCase().includes('quarter') ||\n (orderBy.id || '').toLowerCase().includes('quarter');\n\n if (isMonth) {\n const monthOrder = BaseUtilities.buildMonthOrderKey(column);\n return `${monthOrder} ${direction}${nullsHandling}`;\n }\n if (isQuarter) {\n const quarterOrder = BaseUtilities.buildQuarterOrderKey(column);\n return `${quarterOrder} ${direction}${nullsHandling}`;\n }\n\n return `${column} ${direction}${nullsHandling}`;\n });\n }\n\n private buildDuckDbDefaultOrderClauses(): string[] {\n const clauses: string[] = [];\n\n if (this.options.rows?.length) {\n this.options.rows.forEach((row) => {\n const useDot = BaseUtilities.shouldUseDotNotation(this.options);\n const column = useDot\n ? this.formatDuckDbOrderByColumn(row)\n : `\"${BaseUtilities.extractColumnIdFromHierarchy(row.id)}\"`;\n const nullsHandling = this.buildDuckDbNullsHandling('ASC');\n const isMonth =\n (row.columnName || '').toLowerCase().includes('month') ||\n (row.label || '').toLowerCase().includes('month');\n const isQuarter =\n (row.columnName || '').toLowerCase().includes('quarter') ||\n (row.label || '').toLowerCase().includes('quarter');\n if (isMonth) {\n const monthOrder = BaseUtilities.buildMonthOrderKey(column);\n clauses.push(`${monthOrder} ASC${nullsHandling}`);\n } else if (isQuarter) {\n const quarterOrder = BaseUtilities.buildQuarterOrderKey(column);\n clauses.push(`${quarterOrder} ASC${nullsHandling}`);\n } else {\n clauses.push(`${column} ASC${nullsHandling}`);\n }\n });\n }\n\n if (this.options.columns?.length) {\n this.options.columns.forEach((col) => {\n const useDot = BaseUtilities.shouldUseDotNotation(this.options);\n const column = useDot\n ? this.formatDuckDbOrderByColumn(col)\n : `\"${BaseUtilities.extractColumnIdFromHierarchy(col.id)}\"`;\n const nullsHandling = this.buildDuckDbNullsHandling('ASC');\n const isMonth =\n (col.columnName || '').toLowerCase().includes('month') ||\n (col.label || '').toLowerCase().includes('month');\n const isQuarter =\n (col.columnName || '').toLowerCase().includes('quarter') ||\n (col.label || '').toLowerCase().includes('quarter');\n if (isMonth) {\n const monthOrder = BaseUtilities.buildMonthOrderKey(column);\n clauses.push(`${monthOrder} ASC${nullsHandling}`);\n } else if (isQuarter) {\n const quarterOrder = BaseUtilities.buildQuarterOrderKey(column);\n clauses.push(`${quarterOrder} ASC${nullsHandling}`);\n } else {\n clauses.push(`${column} ASC${nullsHandling}`);\n }\n });\n }\n\n return clauses;\n }\n\n private buildDuckDbRollupOrderClauses(): string[] {\n const clauses: string[] = [];\n\n if (this.options.rows?.length && !this.options.skipRollup) {\n clauses.push('\"[IsRowGrandTotal]\" DESC NULLS LAST');\n\n const rowCount = this.options.rows.length;\n for (let i = 1; i < rowCount; i++) {\n clauses.push(`\"[IsDM${i - 1}Total]\" DESC NULLS LAST`);\n }\n }\n\n if (this.options.columns?.length && !this.options.skipRollup) {\n clauses.push('\"[IsColumnGrandTotal]\" DESC NULLS LAST');\n\n const rowCount = this.options.rows?.length || 0;\n const columnCount = this.options.columns.length;\n for (let i = 1; i < columnCount; i++) {\n clauses.push(`\"[IsDM${rowCount + i - 1}Total]\" DESC NULLS LAST`);\n }\n }\n\n return clauses;\n }\n\n private getRollupColumnPosition(columnName: string): number {\n let position = 1;\n\n if (this.options.rows?.length) {\n position += this.options.rows.length;\n }\n\n if (this.options.columns?.length) {\n position += this.options.columns.length;\n }\n\n if (this.options.values?.length) {\n position += this.options.values.length;\n }\n\n position += 1;\n\n if (columnName.includes('IsRowGrandTotal')) {\n return position + 2;\n } else if (columnName.includes('IsColumnGrandTotal')) {\n return position + 3;\n } else {\n return position + 4;\n }\n }\n\n private resolveDuckDbOrderByColumn(orderBy: OrderByConfig): string {\n if (orderBy.isColumnPresentInOutput) {\n if (orderBy.aggregationType) {\n return `\"${orderBy.aggregationType}__${orderBy.tableName}[${orderBy.columnName}]\"`;\n }\n return `\"${orderBy.tableName}[${orderBy.columnName}]\"`;\n }\n\n const config: RowColumnConfig = {\n id: orderBy.id,\n columnName: orderBy.columnName,\n tableName: orderBy.tableName,\n label: orderBy.id,\n type: 'Column',\n };\n return BaseUtilities.formatColumnReferenceForDb(config, this.options);\n }\n\n private formatDuckDbOrderByColumn(config: RowColumnConfig): string {\n if (config.orderByRef) {\n return BaseUtilities.formatColumnReferenceForDb(config, this.options);\n }\n\n return BaseUtilities.formatColumnReferenceForDb(config, this.options);\n }\n\n private buildDuckDbNullsHandling(direction: 'ASC' | 'DESC'): string {\n return direction === 'DESC' ? ' NULLS LAST' : ' NULLS FIRST';\n }\n\n private isDateHierarchyColumn(config: RowColumnConfig): boolean {\n const dateColumns = ['Month', 'Quarter', 'Year'];\n return dateColumns.some((dateCol) =>\n config.columnName?.toLowerCase().includes(dateCol.toLowerCase()),\n );\n }\n\n private getDuckDbDateColumnName(columnName: string): string {\n const dateColumnMap: Record<string, string> = {\n Month: 'MonthNo',\n Quarter: 'QuarterNo',\n Year: 'Year',\n };\n\n for (const [key, value] of Object.entries(dateColumnMap)) {\n if (columnName.toLowerCase().includes(key.toLowerCase())) {\n return value;\n }\n }\n\n return columnName;\n }\n\n protected hasRollupOrdering(): boolean {\n return (\n BaseUtilities.shouldGenerateRollupForOptions(this.options) &&\n BaseUtilities.hasMeasuresInOptions(this.options)\n );\n }\n}\n","import { EpmQueryBuilderOptions } from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\nimport { BaseSuperFilterBuilder } from '@epm-query-builder/base/BaseSuperFilterBuilder';\nimport { QueryGenerationError } from '@epm-query-builder/errors/QueryBuilderErrors';\n\n// chooses count strategy based on presence of group by or measures\nexport class BaseCountQueryBuilder {\n constructor(protected options: EpmQueryBuilderOptions) {}\n\n // branches to grouped count when aggregation is involved\n generateCountQuery(mainQuery: string): string {\n try {\n if (this.hasGroupBy() || BaseUtilities.hasMeasuresInOptions(this.options)) {\n return this.generateGroupedCountQuery(mainQuery);\n }\n return this.generateSimpleCountQuery();\n } catch (error) {\n throw new QueryGenerationError(`Failed to generate count query: ${error}`, {\n hasGroupBy: this.hasGroupBy(),\n hasMeasures: BaseUtilities.hasMeasuresInOptions(this.options),\n });\n }\n }\n\n // counts distinct dims when dimensions exist, else total rows\n private generateSimpleCountQuery(): string {\n const dimensions = BaseUtilities.extractDimensionsFromOptions(this.options);\n const fromClause = this.buildFromClause();\n const whereClause = this.buildWhereClause();\n\n if (dimensions.length === 0) {\n return `\n SELECT COUNT(*) as total_count\n FROM ${fromClause}\n ${whereClause}\n `.trim();\n }\n\n return `\n SELECT COUNT(DISTINCT ${dimensions.join(', ')}) as distinct_count\n FROM ${fromClause}\n ${whereClause}\n `.trim();\n }\n\n // wraps main query to count rows after aggregation\n private generateGroupedCountQuery(mainQuery: string): string {\n return `\n SELECT COUNT(*) as total_count\n FROM (\n ${mainQuery}\n ) as main_result\n `.trim();\n }\n\n // beware: naive left join on id across tables; change keys if schema differs\n protected buildFromClause(): string {\n const tables = new Set<string>();\n\n [\n ...(this.options.rows || []),\n ...(this.options.columns || []),\n ...(this.options.values || []),\n ].forEach((item) => {\n if (item.tableName) {\n tables.add(item.tableName);\n }\n });\n\n if (tables.size === 0) {\n throw new QueryGenerationError('No tables found for count query');\n }\n\n if (tables.size === 1) {\n return Array.from(tables)[0];\n }\n\n const tableArray = Array.from(tables);\n const baseTable = tableArray[0];\n let fromClause = baseTable;\n\n for (let i = 1; i < tableArray.length; i++) {\n fromClause += ` LEFT JOIN ${tableArray[i]} ON ${baseTable}.id = ${tableArray[i]}.id`;\n }\n\n return fromClause;\n }\n\n protected buildWhereClause(): string {\n if (!this.options.superFilters) return '';\n const superFilterBuilder = new BaseSuperFilterBuilder(this.options);\n const where = superFilterBuilder.buildWhereClause();\n return where ? `WHERE ${where}` : '';\n }\n\n protected hasGroupBy(): boolean {\n const hasRows = (this.options.rows?.length || 0) > 0;\n const hasColumns = (this.options.columns?.length || 0) > 0;\n return hasRows || hasColumns;\n }\n\n protected hasMeasures(): boolean {\n return (this.options.values?.length || 0) > 0;\n }\n}\n","import { EpmQueryBuilderOptions } from '@epm-query-builder/types/query-builder-types';\nimport { InvalidConfigurationError } from '@epm-query-builder/errors/QueryBuilderErrors';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\n\nexport class QueryOptionsValidator {\n static validateBasicConfiguration(options: EpmQueryBuilderOptions): void {\n if (!options.databaseDetails) {\n throw new InvalidConfigurationError('databaseDetails is required');\n }\n\n const hasRows = options.rows?.length;\n const hasColumns = options.columns?.length;\n const hasValues = options.values?.length;\n const dbType = String(options.databaseDetails?.databaseType || '').toLowerCase();\n const hasSelectAll =\n dbType === 'duckdb' &&\n Array.isArray(options.selectedColumns) &&\n options.selectedColumns.some((c) => {\n const s = String(c || '').trim();\n return s === '*' || (/\\*$/i.test(s) && /\\./.test(s)) || /^table(name)?[:=]/i.test(s);\n });\n\n if (!hasRows && !hasColumns && !hasValues && !hasSelectAll) {\n throw new InvalidConfigurationError(\n 'At least one of rows, columns, or values must be specified',\n );\n }\n\n this.validateTableNames(options);\n this.validateMeasures(options);\n this.validatePagination(options);\n this.validateRelationships(options);\n }\n\n private static validateTableNames(options: EpmQueryBuilderOptions): void {\n const allItems = [\n ...(options.rows || []),\n ...(options.columns || []),\n ...(options.values || []),\n ];\n\n const missingTableNames = allItems.filter((item) => {\n const hasDirectTableName = Boolean(item.tableName);\n const hasExtractableTableName = Boolean(item.id && BaseUtilities.getTableNameFromId(item.id));\n return !hasDirectTableName && !hasExtractableTableName;\n });\n\n if (missingTableNames.length > 0) {\n throw new InvalidConfigurationError(\n 'All items must have a tableName specified or extractable from id',\n {\n itemsWithoutTableName: missingTableNames.length,\n },\n );\n }\n }\n\n private static validateMeasures(options: EpmQueryBuilderOptions): void {\n if (!options.values?.length) return;\n\n const validAggregationTypes = [\n 'EARLIEST',\n 'LATEST',\n 'SUM',\n 'COUNT',\n 'DISTINCT_COUNT',\n 'AVG',\n 'AVERAGE',\n 'MIN',\n 'MINIMUM',\n 'MAX',\n 'MAXIMUM',\n 'FIRST',\n 'FIRST_VALUE',\n 'LAST',\n 'LAST_VALUE',\n 'STANDARD_DEVIATION',\n 'VARIANCE',\n 'VAR_POP',\n 'COUNT_DISTINCT',\n 'COUNT_DISTINCT_VALUE',\n 'MEDIAN',\n 'MODE',\n 'MODE_VALUE',\n 'CONCATENATED',\n 'CONCATENATED_IDS',\n ];\n\n options.values.forEach((measure) => {\n if (!measure.columnName && !measure.id) {\n throw new InvalidConfigurationError('Measure must have either columnName or id', {\n measure: measure.label || 'unnamed',\n });\n }\n\n if (\n measure.aggregationType &&\n !validAggregationTypes.includes(measure.aggregationType.toUpperCase())\n ) {\n throw new InvalidConfigurationError(\n `Invalid aggregation type: ${measure.aggregationType}`,\n {\n measure: measure.label || measure.columnName,\n validTypes: validAggregationTypes,\n },\n );\n }\n });\n }\n\n private static validatePagination(options: EpmQueryBuilderOptions): void {\n if (!options.pagination) return;\n\n const { limit, take, reference } = options.pagination;\n\n if (!limit && !take) {\n throw new InvalidConfigurationError(\n 'Pagination requires either limit or take to be specified',\n );\n }\n\n if (reference) {\n const { command, dimensions, instances, nextToken } = reference;\n\n if (!command) {\n throw new InvalidConfigurationError('Pagination reference requires command');\n }\n\n if (!['NEXT_HEIR', 'SIBLING', 'CHILDREN'].includes(command)) {\n throw new InvalidConfigurationError(`Invalid pagination command: ${command}`, {\n validCommands: ['NEXT_HEIR', 'SIBLING', 'CHILDREN'],\n });\n }\n\n if (command === 'NEXT_HEIR' && (!dimensions?.length || !nextToken?.length)) {\n throw new InvalidConfigurationError(\n 'NEXT_HEIR pagination requires dimensions and nextToken',\n );\n }\n\n if (\n (command === 'SIBLING' || command === 'CHILDREN') &&\n (!dimensions?.length || !instances?.length)\n ) {\n throw new InvalidConfigurationError(\n `${command} pagination requires dimensions and instances`,\n );\n }\n }\n }\n\n private static validateRelationships(options: EpmQueryBuilderOptions): void {\n const rels = options.relationships || [];\n if (!rels.length) return;\n rels.forEach((r, idx) => {\n if (!r) {\n throw new InvalidConfigurationError(`Relationship at index ${idx} is empty`);\n }\n const required: [string, unknown][] = [\n ['fromTable', r.fromTable],\n ['fromColumn', r.fromColumn],\n ['toTable', r.toTable],\n ['toColumn', r.toColumn],\n ['fromColumnMultiplicity', r.fromColumnMultiplicity],\n ['toColumnMultiplicity', r.toColumnMultiplicity],\n ];\n required.forEach(([k, v]) => {\n if (typeof v !== 'string' || String(v).trim().length === 0) {\n throw new InvalidConfigurationError(\n `Relationship[${idx}] field '${k}' must be a non-empty string`,\n );\n }\n });\n const multOk = (m: string) => m === '*' || m === '0..1';\n if (!multOk(r.fromColumnMultiplicity) || !multOk(r.toColumnMultiplicity)) {\n throw new InvalidConfigurationError(\n `Relationship[${idx}] multiplicity must be '*' or '0..1'`,\n );\n }\n });\n }\n}\n","import { QueryGenerationError } from '@epm-query-builder/errors/QueryBuilderErrors';\n\nconst SELECT_PATTERN = /^\\s*(WITH\\s+.*\\s+)?SELECT\\s+/;\nconst SUSPICIOUS_PATTERNS: RegExp[] = [\n /;\\s*(DROP|DELETE|INSERT|UPDATE|ALTER|CREATE|EXEC|EXECUTE)\\s+/i,\n /--\\s*$/m,\n /\\/\\*.*?\\*\\//s,\n /'\\s*;\\s*--/i,\n /union\\s+select/i,\n /'\\s*or\\s*'.*'=/i,\n];\n\nexport class SqlQueryValidator {\n static validateQuery(query: string): void {\n if (!query || query.trim().length === 0) {\n throw new QueryGenerationError('Generated query is empty');\n }\n\n const trimmedQuery = query.trim();\n\n if (!this.hasValidSqlStructure(trimmedQuery)) {\n throw new QueryGenerationError('Generated query has invalid SQL structure', {\n query: trimmedQuery.substring(0, 200),\n });\n }\n\n this.validateBasicSyntax(trimmedQuery);\n this.validateSqlInjection(trimmedQuery);\n }\n\n private static hasValidSqlStructure(query: string): boolean {\n const upperQuery = query.toUpperCase();\n\n const hasSelect = SELECT_PATTERN.test(upperQuery);\n\n if (!hasSelect) {\n return false;\n }\n\n const hasFrom = upperQuery.includes('FROM');\n const isCountQuery = upperQuery.includes('COUNT(');\n\n return hasFrom || isCountQuery;\n }\n\n private static validateBasicSyntax(query: string): void {\n const issues: string[] = [];\n\n const parenthesesCount = this.countParentheses(query);\n if (parenthesesCount.open !== parenthesesCount.close) {\n issues.push(\n `Unbalanced parentheses: ${parenthesesCount.open} opening, ${parenthesesCount.close} closing`,\n );\n }\n\n const quoteCount = this.countQuotes(query);\n if (quoteCount.single % 2 !== 0) {\n issues.push('Unbalanced single quotes');\n }\n if (quoteCount.double % 2 !== 0) {\n issues.push('Unbalanced double quotes');\n }\n\n if (this.hasDanglingCommas(query)) {\n issues.push('Query contains dangling commas');\n }\n\n if (this.hasEmptySelectList(query)) {\n issues.push('SELECT statement has empty column list');\n }\n\n if (issues.length > 0) {\n throw new QueryGenerationError(`SQL syntax validation failed: ${issues.join(', ')}`, {\n issues,\n query: query.substring(0, 200),\n });\n }\n }\n\n private static validateSqlInjection(query: string): void {\n const foundPattern = SUSPICIOUS_PATTERNS.find((pattern) => pattern.test(query));\n if (foundPattern) {\n throw new QueryGenerationError('Query contains potentially dangerous SQL patterns', {\n pattern: foundPattern.toString(),\n query: query.substring(0, 100),\n });\n }\n }\n\n private static countParentheses(query: string): { open: number; close: number } {\n const open = (query.match(/\\(/g) || []).length;\n const close = (query.match(/\\)/g) || []).length;\n return { open, close };\n }\n\n private static countQuotes(query: string): { single: number; double: number } {\n const single = (query.match(/'/g) || []).length;\n const double = (query.match(/\"/g) || []).length;\n return { single, double };\n }\n\n private static hasDanglingCommas(query: string): boolean {\n const patterns = [\n /,\\s*FROM\\s+/i,\n /,\\s*WHERE\\s+/i,\n /,\\s*ORDER\\s+BY\\s+/i,\n /,\\s*GROUP\\s+BY\\s+/i,\n /,\\s*HAVING\\s+/i,\n /,\\s*LIMIT\\s+/i,\n /,\\s*\\)/,\n /SELECT\\s+,/i,\n ];\n\n return patterns.some((pattern) => pattern.test(query));\n }\n\n private static hasEmptySelectList(query: string): boolean {\n const selectPattern = /SELECT\\s+FROM\\s+/i;\n return selectPattern.test(query);\n }\n\n static validateCountQuery(query: string): void {\n this.validateQuery(query);\n\n const upperQuery = query.toUpperCase();\n if (!upperQuery.includes('COUNT(')) {\n throw new QueryGenerationError('Count query must contain COUNT() function');\n }\n }\n}\n","import { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\nimport { EpmQueryBuilderOptions, Relationship } from '@epm-query-builder/types/query-builder-types';\nimport { SOURCE_TYPES } from '@epm-query-builder/constants/Source';\n\ntype JoinType = 'LEFT' | 'INNER' | 'FULL OUTER';\n\nexport interface JoinStep {\n leftTable: string;\n leftColumn: string;\n rightTable: string;\n rightColumn: string;\n joinType: JoinType;\n dedupeRightOn?: string;\n}\n\nexport interface JoinPlan {\n baseTable: string;\n joins: JoinStep[];\n}\n\ninterface Edge {\n from: string;\n to: string;\n relation: Relationship;\n}\n\nfunction isActive(rel: Relationship, includeInactive: boolean): boolean {\n if (includeInactive) return true;\n return rel.isActive !== false;\n}\n\nfunction buildEdges(rels: Relationship[], includeInactive: boolean): Edge[] {\n const edges: Edge[] = [];\n for (const r of rels) {\n if (!isActive(r, includeInactive)) continue;\n const fromIsMany = r.fromColumnMultiplicity === '*';\n const toIsMany = r.toColumnMultiplicity === '*';\n\n if (fromIsMany && toIsMany) {\n edges.push({ from: r.fromTable, to: r.toTable, relation: r });\n edges.push({ from: r.toTable, to: r.fromTable, relation: r });\n } else if (!fromIsMany && toIsMany) {\n edges.push({ from: r.fromTable, to: r.toTable, relation: r });\n } else if (fromIsMany && !toIsMany) {\n edges.push({ from: r.toTable, to: r.fromTable, relation: r });\n } else {\n edges.push({ from: r.fromTable, to: r.toTable, relation: r });\n edges.push({ from: r.toTable, to: r.fromTable, relation: r });\n }\n }\n return edges;\n}\n\nfunction buildGraph(edges: Edge[]): Map<string, Edge[]> {\n const graph = new Map<string, Edge[]>();\n for (const e of edges) {\n if (!graph.has(e.from)) graph.set(e.from, []);\n graph.get(e.from)!.push(e);\n }\n return graph;\n}\n\nfunction bfsReachable(graph: Map<string, Edge[]>, start: string): Set<string> {\n const visited = new Set<string>();\n if (!start) return visited;\n const q: string[] = [start];\n visited.add(start);\n while (q.length) {\n const u = q.shift() as string;\n const outs = graph.get(u) || [];\n for (const e of outs) {\n if (!visited.has(e.to)) {\n visited.add(e.to);\n q.push(e.to);\n }\n }\n }\n return visited;\n}\n\nfunction findShortestPath(\n graph: Map<string, Edge[]>,\n start: string,\n target: string,\n): Edge[] | null {\n if (start === target) return [];\n const parent = new Map<string, Edge | null>();\n const q: string[] = [start];\n parent.set(start, null);\n\n while (q.length) {\n const u = q.shift() as string;\n const outs = graph.get(u) || [];\n for (const e of outs) {\n if (!parent.has(e.to)) {\n parent.set(e.to, e);\n if (e.to === target) {\n const path: Edge[] = [];\n let cur = target;\n while (cur !== start) {\n const pe = parent.get(cur);\n if (!pe) break;\n path.push(pe);\n cur = pe.from;\n }\n path.reverse();\n return path;\n }\n q.push(e.to);\n }\n }\n }\n return null;\n}\n\nfunction selectBaseTable(requiredTables: string[], edges: Edge[], fallbackBase: string): string {\n const graph = buildGraph(edges);\n if (fallbackBase) {\n const reach = bfsReachable(graph, fallbackBase);\n const allCovered = requiredTables.every((t) => reach.has(t) || t === fallbackBase);\n if (allCovered) return fallbackBase;\n }\n\n let best: { table: string; covered: number } = { table: fallbackBase, covered: -1 };\n for (const t of requiredTables) {\n const cover = bfsReachable(graph, t);\n const cnt = requiredTables.filter((x) => cover.has(x) || x === t).length;\n if (cnt > best.covered) {\n best = { table: t, covered: cnt };\n }\n }\n return best.table || fallbackBase;\n}\n\nfunction isManyToMany(r: Relationship): boolean {\n return r.fromColumnMultiplicity === '*' && r.toColumnMultiplicity === '*';\n}\n\nfunction edgeToJoin(leftTable: string, e: Edge, dimensionOnly: boolean): JoinStep {\n const r = e.relation;\n const mm = isManyToMany(r);\n const joinType: JoinType = dimensionOnly ? 'FULL OUTER' : 'LEFT';\n if (e.from === r.fromTable && e.to === r.toTable) {\n return {\n leftTable,\n leftColumn: r.fromColumn,\n rightTable: r.toTable,\n rightColumn: r.toColumn,\n joinType,\n dedupeRightOn: dimensionOnly && mm ? r.toColumn : undefined,\n };\n }\n return {\n leftTable,\n leftColumn: r.toColumn,\n rightTable: r.fromTable,\n rightColumn: r.fromColumn,\n joinType,\n dedupeRightOn: dimensionOnly && mm ? r.fromColumn : undefined,\n };\n}\n\nexport function resolveJoinPlan(options: EpmQueryBuilderOptions): JoinPlan {\n const relationships = options.relationships || [];\n if (relationships.length === 0) {\n return { baseTable: BaseUtilities.getDefaultTableName(options), joins: [] };\n }\n\n const requiredTables = BaseUtilities.extractUniqueTableNames(options);\n\n const dimensionOnly = !BaseUtilities.hasMeasuresInOptions(options);\n const source = BaseUtilities.getSource(options);\n const includeInactive = source === SOURCE_TYPES.XMLA && dimensionOnly;\n\n const edges = buildEdges(relationships, includeInactive);\n if (requiredTables.length <= 1 || edges.length === 0) {\n return { baseTable: BaseUtilities.getDefaultTableName(options), joins: [] };\n }\n\n const base = selectBaseTable(requiredTables, edges, BaseUtilities.getDefaultTableName(options));\n const graph = buildGraph(edges);\n\n const usedPairs = new Set<string>();\n const joins: JoinStep[] = [];\n\n for (const t of requiredTables) {\n if (t === base) continue;\n const path = findShortestPath(graph, base, t);\n if (!path) {\n throw new Error(`No relationship path found from ${base} to ${t}`);\n }\n let currentLeft = base;\n for (const edge of path) {\n const key = `${edge.from}->${edge.to}`;\n if (usedPairs.has(key)) {\n currentLeft = edge.to;\n continue;\n }\n const step = edgeToJoin(currentLeft, edge, dimensionOnly);\n joins.push(step);\n usedPairs.add(key);\n currentLeft = edge.to;\n }\n }\n\n return { baseTable: base, joins };\n}\n","import { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\nimport { JoinPlan, JoinStep } from '@epm-query-builder/base/RelationshipResolver';\nimport { SOURCE_TYPES } from '@epm-query-builder/constants/Source';\nimport { EpmQueryBuilderOptions } from '@epm-query-builder/types/query-builder-types';\n\nfunction quoteTable(tableName: string, databaseType?: string): string {\n return BaseUtilities.formatTableNameForDb(tableName, databaseType);\n}\n\nfunction quoteColumn(table: string, column: string): string {\n return BaseUtilities.formatTableColumnReference(table, column);\n}\n\nfunction buildXmlaColumnRef(table: string, column: string): string {\n const fullId = `${table}[${column}]`;\n return `\"${fullId}\"`;\n}\n\nfunction buildJoin(\n step: JoinStep,\n databaseType: string | undefined,\n options?: EpmQueryBuilderOptions,\n): string {\n const source = options ? BaseUtilities.getSource(options) : '';\n const isXmla = source === SOURCE_TYPES.XMLA;\n\n const leftExpr = isXmla\n ? buildXmlaColumnRef(step.leftTable, step.leftColumn)\n : quoteColumn(step.leftTable, step.leftColumn);\n const rightExpr = isXmla\n ? buildXmlaColumnRef(step.rightTable, step.rightColumn)\n : quoteColumn(step.rightTable, step.rightColumn);\n\n let rightSource = quoteTable(step.rightTable, databaseType);\n if (step.dedupeRightOn) {\n if (isXmla) {\n const keyRef = buildXmlaColumnRef(step.rightTable, step.dedupeRightOn);\n const fullId = `${step.rightTable}[${step.dedupeRightOn}]`;\n rightSource = `(\n SELECT DISTINCT ${keyRef} AS \"${fullId}\"\n FROM ${quoteTable(step.rightTable, databaseType)}\n ) ${quoteTable(step.rightTable, databaseType)}`;\n } else {\n const keyCol = quoteColumn(step.rightTable, step.dedupeRightOn);\n rightSource = `(\n SELECT DISTINCT ${keyCol} AS \"${step.dedupeRightOn}\"\n FROM ${quoteTable(step.rightTable, databaseType)}\n ) ${quoteTable(step.rightTable, databaseType)}`;\n }\n }\n\n const on = `${leftExpr} = ${rightExpr}`;\n return `${step.joinType} JOIN ${rightSource} ON ${on}`;\n}\n\nexport class DuckDbJoinBuilder {\n static buildJoinClauses(\n plan: JoinPlan,\n databaseType: string | undefined,\n options?: EpmQueryBuilderOptions,\n ): string[] {\n if (!plan.joins?.length) return [];\n return plan.joins.map((j) => buildJoin(j, databaseType, options));\n }\n}\n","// duckdb dialect: concrete builder for duckdb\nimport { BaseQueryBuilder } from '@epm-query-builder/base/BaseQueryBuilder';\nimport {\n SuperFilterChild,\n RowColumnConfig,\n RankingConfig,\n EpmQueryBuilderOptions,\n} from '@epm-query-builder/types/query-builder-types';\nimport { BaseUtilities } from '@epm-query-builder/base/BaseUtilities';\nimport { DuckDbSuperFilterBuilder } from './DuckDbSuperFilterBuilder';\nimport { DuckDbMeasureBuilder } from './DuckDbMeasureBuilder';\nimport { DuckDbRollupBuilder } from './DuckDbRollupBuilder';\nimport { DuckDbPaginationBuilder } from './DuckDbPaginationBuilder';\nimport { DuckDbOrderBuilder } from './DuckDbOrderBuilder';\nimport { BaseCountQueryBuilder } from '@epm-query-builder/base/BaseCountQueryBuilder';\nimport { QueryOptionsValidator } from '@epm-query-builder/validation/QueryOptionsValidator';\nimport { SqlQueryValidator } from '@epm-query-builder/validation/SqlQueryValidator';\nimport { QueryGenerationError } from '@epm-query-builder/errors/QueryBuilderErrors';\nimport { IDatabaseQueryBuilder } from '@epm-query-builder/interfaces';\nimport { resolveJoinPlan } from '@epm-query-builder/base/RelationshipResolver';\nimport { DuckDbJoinBuilder } from './DuckDbJoinBuilder';\nimport { SOURCE_TYPES } from '@epm-query-builder/constants/Source';\n\nexport class DuckDbQueryBuilder extends BaseQueryBuilder implements IDatabaseQueryBuilder {\n private superFilterBuilder: DuckDbSuperFilterBuilder;\n private measureBuilder: DuckDbMeasureBuilder;\n private rollupBuilder: DuckDbRollupBuilder;\n private paginationBuilder: DuckDbPaginationBuilder;\n private orderBuilder: DuckDbOrderBuilder;\n private countQueryBuilder: BaseCountQueryBuilder;\n\n constructor(options: EpmQueryBuilderOptions) {\n super(options);\n // order matters: these builders are used throughout generation\n this.superFilterBuilder = new DuckDbSuperFilterBuilder(options);\n this.measureBuilder = new DuckDbMeasureBuilder(options);\n this.rollupBuilder = new DuckDbRollupBuilder(options);\n this.paginationBuilder = new DuckDbPaginationBuilder(options);\n this.orderBuilder = new DuckDbOrderBuilder(options);\n this.countQueryBuilder = new BaseCountQueryBuilder(options);\n }\n\n // orchestrates decision between analytical and simple queries\n generateQuery(): string {\n try {\n QueryOptionsValidator.validateBasicConfiguration(this.options);\n\n const hasMultipleTables = this.containsDifferentTables();\n const hasMeasureInValues = this.hasMeasureInValues();\n\n // multi-table without measures uses ctes path\n if (hasMultipleTables && !hasMeasureInValues) {\n const multiTableQuery = this.generateMultiTableQuery();\n SqlQueryValidator.validateQuery(multiTableQuery);\n return multiTableQuery;\n }\n\n let query: string;\n if (this.shouldGenerateAnalyticalQuery()) {\n query = this.generateAnalyticalQuery();\n } else {\n query = this.generateSimpleQuery();\n }\n\n SqlQueryValidator.validateQuery(query);\n return query;\n } catch (error) {\n if (error instanceof Error && error.name.includes('Error')) {\n throw error;\n }\n\n throw new QueryGenerationError(`Failed to generate query: ${error}`, {\n originalError: error,\n hasRows: Boolean(this.options.rows?.length),\n hasColumns: Boolean(this.options.columns?.length),\n hasValues: Boolean(this.options.values?.length),\n });\n }\n }\n\n generateCountQuery(): string {\n const mainQuery = this.generateQuery();\n const countQuery = this.countQueryBuilder.generateCountQuery(mainQuery);\n\n SqlQueryValidator.validateCountQuery(countQuery);\n return countQuery;\n }\n\n // builds query for multi-table scenarios using ctes\n private generateMultiTableQuery(): string {\n const dimensions = BaseUtilities.extractDimensionsFromOptions(this.options);\n const measures = this.extractMeasures();\n const cteQueries = this.buildCTEs();\n const source = BaseUtilities.getSource(this.options);\n const isXmla = source === SOURCE_TYPES.XMLA;\n\n const selectParts: string[] = [];\n\n if (dimensions.length > 0) {\n if (this.options.rows?.length) {\n this.options.rows.forEach((row) => {\n const column = BaseUtilities.formatColumnReferenceForDb(row, this.options);\n selectParts.push(`${column} AS \"${row.id}\"`);\n });\n }\n if (this.options.columns?.length) {\n this.options.columns.forEach((col) => {\n const column = BaseUtilities.formatColumnReferenceForDb(col, this.options);\n selectParts.push(`${column} AS \"${col.id}\"`);\n });\n }\n }\n\n if (measures.length > 0) {\n const measureSelects = this.measureBuilder.buildMeasureSelects();\n selectParts.push(...measureSelects);\n }\n\n const fromClause = this.buildFromWithJoins();\n const whereConditions = [\n this.superFilterBuilder.buildWhereClause(),\n this.superFilterBuilder.buildOrGroupExistsClause?.()\n ? this.superFilterBuilder.buildOrGroupExistsClause()\n : '',\n ].filter(Boolean);\n\n const hasMeasures = measures.length > 0;\n const shouldGroupBy = dimensions.length > 0 && (!isXmla || hasMeasures);\n\n const selectClause =\n isXmla && !hasMeasures\n ? `SELECT DISTINCT ${selectParts.join(', ')}`\n : this.buildSelectClause(selectParts);\n\n return this.buildCompleteQuery({\n cte: cteQueries,\n select: selectClause,\n from: fromClause,\n where: this.buildWhereClause(whereConditions),\n groupBy: shouldGroupBy ? this.buildGroupByClause(dimensions) : undefined,\n orderBy: this.orderBuilder.buildOrderByClause(),\n limit: this.paginationBuilder.buildLimitClause(),\n });\n }\n\n // analytical path: generates ctes then main\n private generateAnalyticalQuery(): string {\n const cteQueries = this.buildCTEs();\n const mainQuery = this.buildMainQuery();\n\n if (cteQueries) {\n return `${cteQueries}\\n${mainQuery}`;\n }\n return mainQuery;\n }\n\n // simple path: handles select all, distinct, or aggregate\n private generateSimpleQuery(): string {\n const tableName = this.getDefaultTableName();\n const dimensions = BaseUtilities.extractDimensionsFromOptions(this.options);\n const whereClause = this.superFilterBuilder.buildWhereClause();\n\n if (this.isSelectAllRequested() && !this.hasMeasures() && !this.hasRankingFilters()) {\n return this.buildSelectAllQuery(tableName, whereClause);\n }\n\n if (!this.hasMeasures()) {\n if (this.hasRankingFilters()) {\n return this.buildTopNRankingQuery(tableName, dimensions);\n }\n return this.buildDistinctQuery(tableName, dimensions, whereClause);\n }\n return this.buildSimpleAggregateQuery(tableName, dimensions, whereClause);\n }\n\n // collects ctes for filters and pre-processing\n private buildCTEs(): string {\n const ctes: string[] = [];\n\n if (this.hasComplexFilters()) {\n const filterCTE = this.superFilterBuilder.buildFilterCTE();\n if (filterCTE) {\n ctes.push(filterCTE);\n }\n }\n\n const measureFilterCTEs = this.measureBuilder.buildMeasureFilterCTE();\n if (measureFilterCTEs) {\n ctes.push(measureFilterCTEs);\n }\n\n const rankingCTE = this.buildRankingKeysCTE();\n if (rankingCTE) {\n ctes.push(rankingCTE);\n }\n\n return ctes.length > 0 ? `WITH ${ctes.join(',\\n')}` : '';\n }\n\n // assembles main query parts respecting ranking overrides\n private buildMainQuery(): string {\n const selectItems = this.buildSelectItems();\n const whereConditions = [\n this.superFilterBuilder.buildWhereClause(),\n this.measureBuilder.buildMeasureFilterWhereClause(),\n ].filter(Boolean);\n const groupByColumns = this.buildGroupByColumns();\n const havingConditions = [this.measureBuilder.buildHavingClause()].filter(Boolean);\n\n const hasRanking = Boolean(this.options.isRankingFilterIncluded) || this.hasRankingFilters();\n\n if (this.shouldGenerateRollup() && hasRanking) {\n const nullFilterConditions = this.rollupBuilder.buildNullFilterConditions();\n whereConditions.push(...nullFilterConditions);\n }\n\n let orderByClause = this.orderBuilder.buildOrderByClause();\n let limitClause = this.paginationBuilder.buildLimitClause();\n\n const ranking = this.findFirstRankingConfig(this.options.superFilters?.children || []);\n if (ranking) {\n const rankingOrder = this.buildRankingOrderClause(ranking);\n const dimsForHaving = BaseUtilities.extractDimensionsFromOptions(this.options);\n const hasRollup = this.shouldGenerateRollup();\n\n if (rankingOrder) {\n orderByClause = hasRollup\n ? `ORDER BY \"[IsRowGrandTotal]\" DESC NULLS LAST, ${rankingOrder}`\n : `ORDER BY ${rankingOrder}`;\n }\n\n // do not LIMIT the main result for ranking; restrict row keys via CTE join instead\n limitClause = '';\n\n if (dimsForHaving.length > 0) {\n const rowDims = BaseUtilities.buildDimensionReference(this.options.rows, this.options);\n if (rowDims.length > 0) {\n const isLeafAllDims = dimsForHaving.map((d) => `GROUPING(${d}) = 0`).join(' AND ');\n const isRowGrand = rowDims.map((d) => `GROUPING(${d}) = 1`).join(' AND ');\n const allowLeafOrRowGrand = `(${isLeafAllDims}) OR (${isRowGrand})`;\n havingConditions.push(allowLeafOrRowGrand);\n }\n }\n\n const rankingWhere = this.buildRankingKeysWhereClause();\n if (rankingWhere) {\n whereConditions.push(rankingWhere);\n }\n }\n\n return this.buildCompleteQuery({\n select: this.buildSelectClause(selectItems),\n from: this.buildFromWithJoins(),\n where: this.buildWhereClause(\n [this.paginationBuilder.buildAdditionalWhere(), ...whereConditions].filter(Boolean),\n ),\n groupBy: groupByColumns.length > 0 ? this.buildGroupByClause(groupByColumns) : undefined,\n having: this.buildHavingClause(havingConditions),\n orderBy: orderByClause,\n limit: limitClause,\n });\n }\n\n // builds select items based on dims, rollup, and measures\n private buildSelectItems(): string[] {\n const selectItems: string[] = [];\n\n if (this.hasDimensions()) {\n selectItems.push(...this.buildDimensionSelects());\n }\n\n if (this.shouldGenerateRollup()) {\n selectItems.push(...this.rollupBuilder.buildRollupSelects());\n }\n\n if (this.hasMeasures()) {\n selectItems.push(...this.measureBuilder.buildMeasureSelects());\n }\n\n return selectItems;\n }\n\n // prepares dimension projections respecting dot-notation mode\n private buildDimensionSelects(): string[] {\n const dimensions: string[] = [];\n\n if (this.options.rows?.length) {\n this.options.rows.forEach((row) => {\n const column = BaseUtilities.formatColumnReferenceForDb(row, this.options);\n dimensions.push(`${column} AS \"${row.id}\"`);\n });\n }\n\n if (this.options.columns?.length) {\n this.options.columns.forEach((col) => {\n const column = BaseUtilities.formatColumnReferenceForDb(col, this.options);\n dimensions.push(`${column} AS \"${col.id}\"`);\n });\n }\n\n return dimensions;\n }\n\n // decides group by list based on rollup and measures\n private buildGroupByColumns(): string[] {\n if (!this.hasMeasures() && !this.shouldGenerateRollup()) {\n return [];\n }\n\n if (this.shouldGenerateRollup()) {\n return this.rollupBuilder.buildGroupByClause().replace('GROUP BY ', '').split(', ');\n }\n\n return BaseUtilities.extractDimensionsFromOptions(this.options);\n }\n\n // checks if dims, cols, filters span multiple tables\n private containsDifferentTables(): boolean {\n const tables = new Set<string>();\n const originalParentTables = new Set<string>();\n\n [...(this.options.rows || []), ...(this.options.columns || [])].forEach((item) => {\n if (!item) return;\n\n const directTableName = item.tableName;\n const inferredTableName =\n !directTableName && item.id ? BaseUtilities.getTableNameFromId(item.id) : null;\n const effectiveTableName = directTableName || inferredTableName;\n\n if (effectiveTableName) {\n tables.add(effectiveTableName);\n\n if (item.type === 'Resolved' && item.orderByRef) {\n originalParentTables.add(item.orderByRef);\n }\n }\n });\n\n (this.options.values || []).forEach((measure) => {\n if (!measure) return;\n\n const directTableName = measure.tableName;\n const inferredTableName =\n !directTableName && measure.id ? BaseUtilities.getTableNameFromId(measure.id) : null;\n const effectiveTableName = directTableName || inferredTableName;\n\n if (effectiveTableName) {\n tables.add(effectiveTableName);\n }\n });\n\n if (this.options.superFilters?.children) {\n this.extractFilterTables(this.options.superFilters.children, tables);\n }\n\n const totalUniqueTables = new Set([...tables, ...originalParentTables]);\n return totalUniqueTables.size > 1;\n }\n\n // traverses filter tree collecting table names\n private extractFilterTables(children: SuperFilterChild[], tables: Set<string>): void {\n children.forEach((child) => {\n if (child.filters?.tableNames) {\n child.filters.tableNames.forEach((tableName: string) => {\n if (tableName) tables.add(tableName);\n });\n }\n if (child.children) {\n this.extractFilterTables(child.children, tables);\n }\n });\n }\n\n private hasMeasureInValues(): boolean {\n return (this.options.values || []).some((measure) => measure.type?.toUpperCase() === 'MEASURE');\n }\n\n private hasFiltersForTable(tableName: string): boolean {\n if (!this.options.superFilters?.children) return false;\n\n return this.checkFiltersForTable(this.options.superFilters.children, tableName);\n }\n\n private checkFiltersForTable(children: SuperFilterChild[], tableName: string): boolean {\n return children.some((child) => {\n if (child.filters?.tableNames?.includes(tableName)) {\n return true;\n }\n if (child.children) {\n return this.checkFiltersForTable(child.children, tableName);\n }\n return false;\n });\n }\n\n private hasMeasuresForTable(tableName: string): boolean {\n return (this.options.values || []).some((measure) => measure.tableName === tableName);\n }\n\n // builds distinct projection for dims path\n private buildDistinctQuery(tableName: string, dimensions: string[], whereClause: string): string {\n const fromClause = this.buildFromWithJoins();\n\n if (dimensions.length === 0) {\n return `SELECT COUNT(*) ${fromClause}`;\n }\n\n const selectDims = this.buildDimensionSelects();\n let query = `SELECT DISTINCT ${selectDims.join(', ')} ${fromClause}`;\n\n if (whereClause) {\n query += ` WHERE ${whereClause}`;\n }\n\n const orderByClause = this.orderBuilder.buildOrderByClause();\n if (orderByClause) {\n query += ` ${orderByClause}`;\n } else if (dimensions.length > 0) {\n query += ` ORDER BY ${dimensions[0]} ASC`;\n }\n\n return query;\n }\n\n private hasRankingFilters(): boolean {\n if (!this.options.superFilters?.children) return false;\n return this.findFirstRankingConfig(this.options.superFilters.children) !== null;\n }\n\n // finds the first ranking config to override order and limit\n private findFirstRankingConfig(children: SuperFilterChild[]): RankingConfig | null {\n for (const child of children) {\n const filters = child.filters as unknown as {\n rankingFilter?: RankingConfig[];\n filterType?: string;\n };\n if (\n filters &&\n filters.filterType === 'RANKING' &&\n Array.isArray(filters.rankingFilter) &&\n filters.rankingFilter.length > 0\n ) {\n return filters.rankingFilter[0];\n }\n if (child.children) {\n const found = this.findFirstRankingConfig(child.children);\n if (found) return found;\n }\n }\n return null;\n }\n\n // generates union/intersect queries for top/bottom selection across rules\n private buildTopNRankingQuery(tableName: string, dimensions: string[]): string {\n const rankings = this.findAllRankingConfigs(this.options.superFilters?.children || []);\n if (rankings.length === 0) {\n return this.buildDistinctQuery(tableName, dimensions, '');\n }\n\n const formattedTableName = BaseUtilities.formatTableNameForDb(\n tableName,\n this.options.databaseDetails?.databaseType as string,\n );\n // if no dimensions, rank rows by the measure column value directly\n if (dimensions.length === 0) {\n const rk = rankings[0];\n const direction = rk.type === 'BOTTOM' ? 'ASC' : 'DESC';\n\n const actualId = BaseUtilities.extractColumnIdFromHierarchy(\n rk.rankByColumnId || `${rk.rankByTableName || ''}[${rk.rankByColumnName || ''}]`,\n );\n\n const isBlend = BaseUtilities.getSource(this.options) === SOURCE_TYPES.BLEND;\n const tableNameForRef = tableName;\n const aggTypeUpper = (rk.rankByAggregationType || 'SUM').toUpperCase();\n const aggPrefix = aggTypeUpper;\n\n const blendMeasureRef = BaseUtilities.formatTableColumnReference(\n tableNameForRef,\n `${aggPrefix}__${actualId}`,\n );\n\n let rkRef: string;\n if (isBlend) {\n rkRef = blendMeasureRef;\n } else if (this.options.databaseDetails?.databaseType === 'duckdb') {\n rkRef = `\"${actualId}\"`;\n } else {\n const tableRef = rk.rankByTableName || BaseUtilities.getDefaultTableName(this.options);\n rkRef = `${tableRef}.${rk.rankByColumnName}`;\n }\n\n if (rk.isPercentage) {\n const percentile = Math.max(0, Math.min(100, rk.value)) / 100;\n return [\n 'SELECT * FROM (',\n `SELECT *, PERCENT_RANK() OVER (ORDER BY ${rkRef} ${direction}) AS __pr`,\n `FROM ${formattedTableName}`,\n `) __ranked WHERE __pr <= ${percentile}`,\n ].join('\\n');\n }\n\n const limit = Math.max(1, Math.floor(rk.value));\n return `SELECT * FROM ${formattedTableName} ORDER BY ${rkRef} ${direction} LIMIT ${limit}`;\n }\n\n const fromClause = `FROM ${formattedTableName}`;\n const groupByClause = `GROUP BY ${dimensions.join(', ')}`;\n\n const subqueries: string[] = [];\n rankings.forEach((rk) => {\n const agg = BaseUtilities.mapAggregationType(rk.rankByAggregationType || 'SUM');\n const isBlend = BaseUtilities.getSource(this.options) === SOURCE_TYPES.BLEND;\n const actualId = BaseUtilities.extractColumnIdFromHierarchy(\n rk.rankByColumnId || `${rk.rankByTableName || ''}[${rk.rankByColumnName || ''}]`,\n );\n let rkRef: string;\n let selectClause: string;\n\n if (isBlend) {\n const aggTypeUpper = (rk.rankByAggregationType || 'SUM').toUpperCase();\n const aggPrefix = aggTypeUpper; // For BLEND, alias prefix must match input aggregation type\n const measureAlias = `${aggPrefix}__${actualId}`;\n const measureRef = BaseUtilities.formatTableColumnReference(tableName, measureAlias);\n rkRef = measureRef;\n selectClause = `SELECT ${dimensions.join(', ')}, ${agg}(\"${measureAlias}\") AS \"${measureAlias}\", COUNT(*) OVER () AS \"[TotalRowsCountForResult]\"`;\n } else if (this.options.databaseDetails?.databaseType === 'duckdb') {\n rkRef = `\"${actualId}\"`;\n selectClause = `SELECT ${dimensions.join(', ')}, ${agg}(${rkRef}), COUNT(*) OVER () AS \"[TotalRowsCountForResult]\"`;\n } else {\n const tableRef = rk.rankByTableName || BaseUtilities.getDefaultTableName(this.options);\n rkRef = `${tableRef}.${rk.rankByColumnName}`;\n selectClause = `SELECT ${dimensions.join(', ')}, ${agg}(${rkRef}), COUNT(*) OVER () AS \"[TotalRowsCountForResult]\"`;\n }\n\n if (rk.type === 'BOTH') {\n const topN = Math.ceil(rk.value);\n const bottomN = Math.floor(rk.value);\n subqueries.push(\n [\n selectClause,\n fromClause,\n groupByClause,\n `ORDER BY ${agg}(${rkRef}) DESC`,\n `LIMIT ${topN}`,\n ].join('\\n'),\n );\n subqueries.push(\n [\n selectClause,\n fromClause,\n groupByClause,\n `ORDER BY ${agg}(${rkRef}) ASC`,\n `LIMIT ${bottomN}`,\n ].join('\\n'),\n );\n } else {\n const dir = rk.type === 'TOP' ? 'DESC' : 'ASC';\n subqueries.push(\n [\n selectClause,\n fromClause,\n groupByClause,\n isBlend\n ? `ORDER BY \"${(rk.rankByAggregationType || 'SUM').toUpperCase()}__${actualId}\" ${dir}`\n : `ORDER BY ${agg}(${rkRef}) ${dir}`,\n `LIMIT ${rk.value}`,\n ].join('\\n'),\n );\n }\n });\n\n const logicalOp = this.extractRankingLogicalOperator(this.options.superFilters?.children || []);\n if (logicalOp === 'INTERSECT') {\n return subqueries.join(' INTERSECT ');\n }\n return subqueries.join(' UNION ');\n }\n\n private buildRankingOrderClause(ranking: RankingConfig): string {\n const direction = ranking.type === 'BOTTOM' ? 'ASC' : 'DESC';\n const agg = BaseUtilities.mapAggregationType(ranking.rankByAggregationType || 'SUM');\n const isBlend = BaseUtilities.getSource(this.options) === SOURCE_TYPES.BLEND;\n\n if (isBlend) {\n const actualId = BaseUtilities.extractColumnIdFromHierarchy(\n ranking.rankByColumnId ||\n `${ranking.rankByTableName || ''}[${ranking.rankByColumnName || ''}]`,\n );\n const aggTypeUpper = (ranking.rankByAggregationType || 'SUM').toUpperCase();\n const aggPrefix = aggTypeUpper; // For BLEND, alias prefix must match input aggregation type\n const aliasName = `${aggPrefix}__${actualId}`;\n return `\"${aliasName}\" ${direction}`;\n }\n\n let measureRef: string;\n if (this.options.databaseDetails?.databaseType === 'duckdb') {\n const actualId = BaseUtilities.extractColumnIdFromHierarchy(\n ranking.rankByColumnId ||\n `${ranking.rankByTableName || ''}[${ranking.rankByColumnName || ''}]`,\n );\n measureRef = `\"${actualId}\"`;\n } else {\n const tableRef = ranking.rankByTableName || BaseUtilities.getDefaultTableName(this.options);\n measureRef = `${tableRef}.${ranking.rankByColumnName}`;\n }\n return `${agg}(${measureRef}) ${direction}`;\n }\n\n private calculateRankingLimit(ranking: RankingConfig): number {\n const distinctCount = ranking.isPercentage ? this.estimateDistinctCountForRanking() : 0;\n if (ranking.isPercentage && distinctCount > 0) {\n return Math.max(1, Math.floor((ranking.value * distinctCount) / 100));\n }\n return ranking.value;\n }\n\n private estimateDistinctCountForRanking(): number {\n const dims = BaseUtilities.extractDimensionsFromOptions(this.options);\n return Math.max(0, dims.length > 0 ? 1000000 : 0);\n }\n\n private findAllRankingConfigs(children: SuperFilterChild[]): RankingConfig[] {\n const result: RankingConfig[] = [];\n for (const child of children) {\n if (child.filters?.rankingFilter && Array.isArray(child.filters.rankingFilter)) {\n result.push(...child.filters.rankingFilter);\n }\n if (child.children) {\n result.push(...this.findAllRankingConfigs(child.children));\n }\n }\n return result;\n }\n\n private extractRankingLogicalOperator(children: SuperFilterChild[]): string {\n for (const child of children) {\n if (child.filters?.logicalOperator) {\n return child.filters.logicalOperator.toUpperCase();\n }\n if (child.children) {\n const v = this.extractRankingLogicalOperator(child.children);\n if (v) return v;\n }\n }\n return 'UNION';\n }\n\n private buildSimpleAggregateQuery(\n tableName: string,\n dimensions: string[],\n whereClause: string,\n ): string {\n const measures = this.extractMeasures();\n const selectParts = [...this.buildDimensionSelects()];\n\n measures.forEach((measure) => {\n if (measure.type?.toLowerCase() === 'measure') {\n selectParts.push(`\"${measure.id}\" AS \"${measure.label}\"`);\n } else {\n const aggregationType = BaseUtilities.mapAggregationType(measure.aggregationType || 'SUM');\n selectParts.push(`${aggregationType}(\"${measure.id}\") AS \"${measure.label}\"`);\n }\n });\n\n const fromClause = this.buildFromWithJoins();\n let query = `SELECT ${selectParts.join(', ')} ${fromClause}`;\n\n if (whereClause) {\n query += ` WHERE ${whereClause}`;\n }\n\n if (dimensions.length > 0) {\n query += ` GROUP BY ${dimensions.join(', ')}`;\n query += ` ORDER BY ${dimensions.map((_, index) => `${index + 1}`).join(', ')}`;\n }\n\n return query;\n }\n\n private isSelectAllRequested(): boolean {\n const sc = this.options.selectedColumns || [];\n if (Array.isArray(sc) && sc.some((c) => c === '*')) return true;\n if (this.options.rows?.length === 1 && this.options.rows[0].columnName === '*') return true;\n return false;\n }\n\n private buildSelectAllQuery(tableName: string, whereClause: string): string {\n const fromClause = this.buildFromWithJoins();\n\n const selectKeyword = this.options.distinct ? 'SELECT DISTINCT' : 'SELECT';\n let query = `${selectKeyword} * ${fromClause}`;\n if (whereClause) {\n query += ` WHERE ${whereClause}`;\n }\n\n const orderByClause = this.orderBuilder.buildOrderByClause();\n if (orderByClause) {\n query += ` ${orderByClause}`;\n }\n\n const limitClause = this.paginationBuilder.buildLimitClause();\n if (limitClause) {\n query += ` ${limitClause}`;\n }\n\n return query;\n }\n\n private hasMeasureFilters(): boolean {\n return Boolean(\n this.options.superFilters?.children?.some(\n (child) =>\n child.filters &&\n (child.filters.filterType === 'MEASURE' ||\n child.filters.columnType?.some((type) => type?.toUpperCase() === 'MEASURE')),\n ),\n );\n }\n\n protected formatColumnReference(config: RowColumnConfig): string {\n if (this.options.databaseDetails?.databaseType === 'duckdb') {\n const actualColumnId = BaseUtilities.extractColumnIdFromHierarchy(config.id);\n return `\"${actualColumnId}\"`;\n }\n return super.formatColumnReference(config);\n }\n\n protected buildFromClause(tableName: string, joins?: string[]): string {\n const formattedTableName = BaseUtilities.formatTableNameForDb(\n tableName,\n this.options.databaseDetails?.databaseType as string,\n );\n let fromClause = `FROM ${formattedTableName}`;\n\n if (joins?.length) {\n fromClause += ` ${joins.join(' ')}`;\n }\n\n return fromClause;\n }\n\n private buildFromWithJoins(): string {\n const plan = resolveJoinPlan(this.options);\n const joins = DuckDbJoinBuilder.buildJoinClauses(\n plan,\n this.options.databaseDetails?.databaseType as string,\n this.options,\n );\n return this.buildFromClause(plan.baseTable || this.getDefaultTableName(), joins);\n }\n\n private buildRankingKeysCTE(): string {\n const ranking = this.findFirstRankingConfig(this.options.superFilters?.children || []);\n if (!ranking) return '';\n const targetDims = this.getRankingTargetDimensions();\n if (targetDims.length === 0) return '';\n\n const isBlend = BaseUtilities.getSource(this.options) === SOURCE_TYPES.BLEND;\n const tableName = this.getDefaultTableName();\n const formattedTableName = BaseUtilities.formatTableNameForDb(\n tableName,\n this.options.databaseDetails?.databaseType as string,\n );\n const direction = ranking.type === 'BOTTOM' ? 'ASC' : 'DESC';\n const agg = BaseUtilities.mapAggregationType(ranking.rankByAggregationType || 'SUM');\n\n let measureExpr: string;\n if (isBlend) {\n const actualId = BaseUtilities.extractColumnIdFromHierarchy(\n ranking.rankByColumnId ||\n `${ranking.rankByTableName || ''}[${ranking.rankByColumnName || ''}]`,\n );\n const aggTypeUpper = (ranking.rankByAggregationType || 'SUM').toUpperCase();\n const aliasName = `${aggTypeUpper}__${actualId}`;\n measureExpr = `${agg}(\"${aliasName}\")`;\n } else if (this.options.databaseDetails?.databaseType === 'duckdb') {\n const actualId = BaseUtilities.extractColumnIdFromHierarchy(\n ranking.rankByColumnId ||\n `${ranking.rankByTableName || ''}[${ranking.rankByColumnName || ''}]`,\n );\n measureExpr = `${agg}(\"${actualId}\")`;\n } else {\n const tableRef = ranking.rankByTableName || BaseUtilities.getDefaultTableName(this.options);\n measureExpr = `${agg}(${tableRef}.${ranking.rankByColumnName})`;\n }\n\n const dimAliases = targetDims.map((_, idx) => `__rk_dim${idx + 1}`);\n const selectDims = targetDims.map((d, idx) => `${d} AS ${dimAliases[idx]}`).join(', ');\n const groupByDims = targetDims.join(', ');\n\n return [\n `__ranking_keys AS (`,\n ` SELECT ${selectDims}, ${measureExpr} AS __rk_value`,\n ` FROM ${formattedTableName}`,\n ` GROUP BY ${groupByDims}`,\n ` ORDER BY __rk_value ${direction}`,\n ` LIMIT ${this.calculateRankingLimit(ranking)}`,\n `)`,\n ].join('\\n');\n }\n\n private buildRankingKeysWhereClause(): string {\n const targetDims = this.getRankingTargetDimensions();\n if (targetDims.length === 0) return '';\n const comparisons = targetDims.map((d, idx) => `${d} = rk.__rk_dim${idx + 1}`).join(' AND ');\n return `EXISTS (SELECT 1 FROM __ranking_keys rk WHERE ${comparisons})`;\n }\n\n private getRankingTargetDimensions(): string[] {\n const ids = this.findFirstRankingTargetColumnIds(this.options.superFilters?.children || []);\n if (ids.length === 0) {\n const rowDims = BaseUtilities.buildDimensionReference(this.options.rows, this.options);\n if (rowDims.length > 0) return rowDims;\n return BaseUtilities.buildDimensionReference(this.options.columns, this.options);\n }\n\n const refs: string[] = [];\n const findConfigById = (id: string) => {\n const inRows = (this.options.rows || []).find((r) => r.id === id);\n if (inRows) return inRows;\n const inCols = (this.options.columns || []).find((c) => c.id === id);\n if (inCols) return inCols;\n return {\n id,\n tableName: BaseUtilities.getDefaultTableNameFromOptions(this.options),\n } as unknown as RowColumnConfig;\n };\n ids.forEach((id) => {\n const cfg = findConfigById(id);\n refs.push(BaseUtilities.formatColumnReferenceForDb(cfg, this.options));\n });\n return refs;\n }\n\n private findFirstRankingTargetColumnIds(children: SuperFilterChild[]): string[] {\n for (const child of children) {\n const filters = child.filters as unknown as {\n filterType?: string;\n columnIds?: string[];\n rankingFilter?: RankingConfig[];\n };\n if (filters && filters.filterType === 'RANKING' && Array.isArray(filters.rankingFilter)) {\n return (filters.columnIds || []).filter(Boolean) as string[];\n }\n if (child.children) {\n const found = this.findFirstRankingTargetColumnIds(child.children);\n if (found.length > 0) return found;\n }\n }\n return [];\n }\n}\n","// list of supported databases for epm query builder\nexport const DATABASE_TYPES = {\n DUCKDB: 'duckdb',\n} as const;\n\nexport type DatabaseType = (typeof DATABASE_TYPES)[keyof typeof DATABASE_TYPES];\n","// entry point: routes options to the correct dialect builder\nimport { DuckDbQueryBuilder } from '@epm-query-builder/dialects/duckdb/DuckDbQueryBuilder';\nimport { DATABASE_TYPES } from '@epm-query-builder/constants/Database';\nimport { IDatabaseQueryBuilder } from '@epm-query-builder/interfaces';\nimport { EpmQueryBuilderOptions } from '@epm-query-builder/types/query-builder-types';\n\nexport class EpmQueryBuilder {\n private readonly impl: IDatabaseQueryBuilder;\n\n constructor(options: EpmQueryBuilderOptions) {\n const databaseType = options.databaseDetails?.databaseType as string;\n\n switch (databaseType?.toLowerCase()) {\n // add other database types here\n case DATABASE_TYPES.DUCKDB:\n this.impl = new DuckDbQueryBuilder(options);\n break;\n default:\n throw new Error(`Unsupported database type: ${databaseType}`);\n }\n }\n\n build(): string {\n // delegates to dialect implementation; keep method name stable for public api\n return this.impl.generateQuery();\n }\n}\n"],"mappings":"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"}