@finos/legend-data-cube 0.0.43 → 0.0.44

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 (348) hide show
  1. package/docs/column-configuration.kind.md +2 -0
  2. package/lib/__lib__/DataCubeSetting.d.ts +1 -0
  3. package/lib/__lib__/DataCubeSetting.d.ts.map +1 -1
  4. package/lib/__lib__/DataCubeSetting.js +1 -0
  5. package/lib/__lib__/DataCubeSetting.js.map +1 -1
  6. package/lib/components/view/editor/DataCubeEditorColumnPropertiesPanel.d.ts.map +1 -1
  7. package/lib/components/view/editor/DataCubeEditorColumnPropertiesPanel.js +12 -6
  8. package/lib/components/view/editor/DataCubeEditorColumnPropertiesPanel.js.map +1 -1
  9. package/lib/components/view/editor/DataCubeEditorColumnSelector.d.ts +7 -1
  10. package/lib/components/view/editor/DataCubeEditorColumnSelector.d.ts.map +1 -1
  11. package/lib/components/view/editor/DataCubeEditorColumnSelector.js +23 -1
  12. package/lib/components/view/editor/DataCubeEditorColumnSelector.js.map +1 -1
  13. package/lib/components/view/editor/DataCubeEditorColumnsPanel.d.ts.map +1 -1
  14. package/lib/components/view/editor/DataCubeEditorColumnsPanel.js +2 -1
  15. package/lib/components/view/editor/DataCubeEditorColumnsPanel.js.map +1 -1
  16. package/lib/components/view/editor/DataCubeEditorHorizontalPivotsPanel.d.ts.map +1 -1
  17. package/lib/components/view/editor/DataCubeEditorHorizontalPivotsPanel.js +2 -4
  18. package/lib/components/view/editor/DataCubeEditorHorizontalPivotsPanel.js.map +1 -1
  19. package/lib/components/view/editor/DataCubeEditorSortsPanel.d.ts.map +1 -1
  20. package/lib/components/view/editor/DataCubeEditorSortsPanel.js +4 -25
  21. package/lib/components/view/editor/DataCubeEditorSortsPanel.js.map +1 -1
  22. package/lib/components/view/filter/DataCubeFilterEditor.d.ts.map +1 -1
  23. package/lib/components/view/filter/DataCubeFilterEditor.js +2 -1
  24. package/lib/components/view/filter/DataCubeFilterEditor.js.map +1 -1
  25. package/lib/index.css +2 -2
  26. package/lib/index.css.map +1 -1
  27. package/lib/package.json +5 -5
  28. package/lib/stores/core/DataCubeConfigurationBuilder.d.ts +4 -3
  29. package/lib/stores/core/DataCubeConfigurationBuilder.d.ts.map +1 -1
  30. package/lib/stores/core/DataCubeConfigurationBuilder.js +59 -3
  31. package/lib/stores/core/DataCubeConfigurationBuilder.js.map +1 -1
  32. package/lib/stores/core/DataCubeEngine.d.ts +2 -0
  33. package/lib/stores/core/DataCubeEngine.d.ts.map +1 -1
  34. package/lib/stores/core/DataCubeEngine.js +1 -2
  35. package/lib/stores/core/DataCubeEngine.js.map +1 -1
  36. package/lib/stores/core/DataCubeQueryBuilder.d.ts.map +1 -1
  37. package/lib/stores/core/DataCubeQueryBuilder.js +12 -22
  38. package/lib/stores/core/DataCubeQueryBuilder.js.map +1 -1
  39. package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts +6 -5
  40. package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts.map +1 -1
  41. package/lib/stores/core/DataCubeQueryBuilderUtils.js +59 -30
  42. package/lib/stores/core/DataCubeQueryBuilderUtils.js.map +1 -1
  43. package/lib/stores/core/DataCubeQueryEngine.d.ts +14 -7
  44. package/lib/stores/core/DataCubeQueryEngine.d.ts.map +1 -1
  45. package/lib/stores/core/DataCubeQueryEngine.js +76 -45
  46. package/lib/stores/core/DataCubeQueryEngine.js.map +1 -1
  47. package/lib/stores/core/DataCubeQuerySnapshot.d.ts +11 -0
  48. package/lib/stores/core/DataCubeQuerySnapshot.d.ts.map +1 -1
  49. package/lib/stores/core/DataCubeQuerySnapshot.js.map +1 -1
  50. package/lib/stores/core/DataCubeQuerySnapshotBuilder.d.ts +2 -3
  51. package/lib/stores/core/DataCubeQuerySnapshotBuilder.d.ts.map +1 -1
  52. package/lib/stores/core/DataCubeQuerySnapshotBuilder.js +226 -128
  53. package/lib/stores/core/DataCubeQuerySnapshotBuilder.js.map +1 -1
  54. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.d.ts +36 -7
  55. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.d.ts.map +1 -1
  56. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.js +359 -126
  57. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.js.map +1 -1
  58. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation.d.ts +10 -2
  59. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation.d.ts.map +1 -1
  60. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation.js +15 -6
  61. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation.js.map +1 -1
  62. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Average.d.ts +6 -2
  63. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Average.d.ts.map +1 -1
  64. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Average.js +13 -3
  65. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Average.js.map +1 -1
  66. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Count.d.ts +6 -2
  67. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Count.d.ts.map +1 -1
  68. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Count.js +13 -3
  69. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Count.js.map +1 -1
  70. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__First.d.ts +6 -2
  71. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__First.d.ts.map +1 -1
  72. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__First.js +13 -3
  73. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__First.js.map +1 -1
  74. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__JoinStrings.d.ts +6 -2
  75. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__JoinStrings.d.ts.map +1 -1
  76. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__JoinStrings.js +23 -10
  77. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__JoinStrings.js.map +1 -1
  78. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Last.d.ts +6 -2
  79. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Last.d.ts.map +1 -1
  80. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Last.js +13 -3
  81. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Last.js.map +1 -1
  82. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Max.d.ts +6 -2
  83. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Max.d.ts.map +1 -1
  84. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Max.js +13 -3
  85. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Max.js.map +1 -1
  86. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Min.d.ts +6 -2
  87. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Min.d.ts.map +1 -1
  88. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Min.js +13 -3
  89. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Min.js.map +1 -1
  90. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__StdDevPopulation.d.ts +6 -2
  91. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__StdDevPopulation.d.ts.map +1 -1
  92. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__StdDevPopulation.js +13 -3
  93. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__StdDevPopulation.js.map +1 -1
  94. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__StdDevSample.d.ts +6 -2
  95. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__StdDevSample.d.ts.map +1 -1
  96. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__StdDevSample.js +13 -3
  97. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__StdDevSample.js.map +1 -1
  98. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Sum.d.ts +6 -2
  99. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Sum.d.ts.map +1 -1
  100. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Sum.js +14 -3
  101. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__Sum.js.map +1 -1
  102. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__UniqueValue.d.ts +6 -2
  103. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__UniqueValue.d.ts.map +1 -1
  104. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__UniqueValue.js +13 -3
  105. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__UniqueValue.js.map +1 -1
  106. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__VariancePopulation.d.ts +6 -2
  107. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__VariancePopulation.d.ts.map +1 -1
  108. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__VariancePopulation.js +13 -3
  109. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__VariancePopulation.js.map +1 -1
  110. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__VarianceSample.d.ts +6 -2
  111. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__VarianceSample.d.ts.map +1 -1
  112. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__VarianceSample.js +13 -3
  113. package/lib/stores/core/aggregation/DataCubeQueryAggregateOperation__VarianceSample.js.map +1 -1
  114. package/lib/stores/core/filter/DataCubeQueryFilterOperation.d.ts +0 -2
  115. package/lib/stores/core/filter/DataCubeQueryFilterOperation.d.ts.map +1 -1
  116. package/lib/stores/core/filter/DataCubeQueryFilterOperation.js +1 -30
  117. package/lib/stores/core/filter/DataCubeQueryFilterOperation.js.map +1 -1
  118. package/lib/stores/core/filter/DataCubeQueryFilterOperation__Contain.d.ts.map +1 -1
  119. package/lib/stores/core/filter/DataCubeQueryFilterOperation__Contain.js +8 -7
  120. package/lib/stores/core/filter/DataCubeQueryFilterOperation__Contain.js.map +1 -1
  121. package/lib/stores/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.d.ts.map +1 -1
  122. package/lib/stores/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.js +10 -10
  123. package/lib/stores/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.js.map +1 -1
  124. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EndWith.d.ts.map +1 -1
  125. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EndWith.js +8 -7
  126. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EndWith.js.map +1 -1
  127. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.d.ts.map +1 -1
  128. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.js +10 -10
  129. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.js.map +1 -1
  130. package/lib/stores/core/filter/DataCubeQueryFilterOperation__Equal.d.ts.map +1 -1
  131. package/lib/stores/core/filter/DataCubeQueryFilterOperation__Equal.js +5 -6
  132. package/lib/stores/core/filter/DataCubeQueryFilterOperation__Equal.js.map +1 -1
  133. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.d.ts.map +1 -1
  134. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.js +10 -10
  135. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.js.map +1 -1
  136. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.d.ts.map +1 -1
  137. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.js +6 -7
  138. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.js.map +1 -1
  139. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EqualColumn.d.ts.map +1 -1
  140. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EqualColumn.js +6 -7
  141. package/lib/stores/core/filter/DataCubeQueryFilterOperation__EqualColumn.js.map +1 -1
  142. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThan.d.ts.map +1 -1
  143. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThan.js +5 -6
  144. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThan.js.map +1 -1
  145. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.d.ts.map +1 -1
  146. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.js +6 -7
  147. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.js.map +1 -1
  148. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.d.ts.map +1 -1
  149. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.js +5 -6
  150. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.js.map +1 -1
  151. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.d.ts.map +1 -1
  152. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.js +6 -7
  153. package/lib/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.js.map +1 -1
  154. package/lib/stores/core/filter/DataCubeQueryFilterOperation__IsNotNull.d.ts.map +1 -1
  155. package/lib/stores/core/filter/DataCubeQueryFilterOperation__IsNotNull.js +2 -6
  156. package/lib/stores/core/filter/DataCubeQueryFilterOperation__IsNotNull.js.map +1 -1
  157. package/lib/stores/core/filter/DataCubeQueryFilterOperation__IsNull.d.ts.map +1 -1
  158. package/lib/stores/core/filter/DataCubeQueryFilterOperation__IsNull.js +2 -2
  159. package/lib/stores/core/filter/DataCubeQueryFilterOperation__IsNull.js.map +1 -1
  160. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThan.d.ts.map +1 -1
  161. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThan.js +5 -6
  162. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThan.js.map +1 -1
  163. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThanColumn.d.ts.map +1 -1
  164. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThanColumn.js +6 -7
  165. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThanColumn.js.map +1 -1
  166. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.d.ts.map +1 -1
  167. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.js +5 -6
  168. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.js.map +1 -1
  169. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.d.ts.map +1 -1
  170. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.js +6 -7
  171. package/lib/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.js.map +1 -1
  172. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotContain.d.ts.map +1 -1
  173. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotContain.js +8 -11
  174. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotContain.js.map +1 -1
  175. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEndWith.d.ts.map +1 -1
  176. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEndWith.js +8 -11
  177. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEndWith.js.map +1 -1
  178. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqual.d.ts.map +1 -1
  179. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqual.js +6 -10
  180. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqual.js.map +1 -1
  181. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.d.ts.map +1 -1
  182. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.js +10 -14
  183. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.js.map +1 -1
  184. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.d.ts.map +1 -1
  185. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.js +6 -11
  186. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.js.map +1 -1
  187. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.d.ts.map +1 -1
  188. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.js +6 -11
  189. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.js.map +1 -1
  190. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotStartWith.d.ts.map +1 -1
  191. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotStartWith.js +8 -11
  192. package/lib/stores/core/filter/DataCubeQueryFilterOperation__NotStartWith.js.map +1 -1
  193. package/lib/stores/core/filter/DataCubeQueryFilterOperation__StartWith.d.ts.map +1 -1
  194. package/lib/stores/core/filter/DataCubeQueryFilterOperation__StartWith.js +8 -7
  195. package/lib/stores/core/filter/DataCubeQueryFilterOperation__StartWith.js.map +1 -1
  196. package/lib/stores/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.d.ts.map +1 -1
  197. package/lib/stores/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.js +10 -10
  198. package/lib/stores/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.js.map +1 -1
  199. package/lib/stores/core/model/DataCubeColumn.d.ts +1 -1
  200. package/lib/stores/core/model/DataCubeColumn.d.ts.map +1 -1
  201. package/lib/stores/core/model/DataCubeColumn.js.map +1 -1
  202. package/lib/stores/core/model/DataCubeConfiguration.d.ts +4 -3
  203. package/lib/stores/core/model/DataCubeConfiguration.d.ts.map +1 -1
  204. package/lib/stores/core/model/DataCubeConfiguration.js +4 -0
  205. package/lib/stores/core/model/DataCubeConfiguration.js.map +1 -1
  206. package/lib/stores/services/DataCubeQuerySnapshotService.d.ts.map +1 -1
  207. package/lib/stores/services/DataCubeQuerySnapshotService.js +2 -2
  208. package/lib/stores/services/DataCubeQuerySnapshotService.js.map +1 -1
  209. package/lib/stores/services/DataCubeSettingService.d.ts.map +1 -1
  210. package/lib/stores/services/DataCubeSettingService.js +8 -0
  211. package/lib/stores/services/DataCubeSettingService.js.map +1 -1
  212. package/lib/stores/view/DataCubeViewState.d.ts.map +1 -1
  213. package/lib/stores/view/DataCubeViewState.js +1 -1
  214. package/lib/stores/view/DataCubeViewState.js.map +1 -1
  215. package/lib/stores/view/editor/DataCubeEditorColumnPropertiesPanelState.d.ts.map +1 -1
  216. package/lib/stores/view/editor/DataCubeEditorColumnPropertiesPanelState.js +3 -2
  217. package/lib/stores/view/editor/DataCubeEditorColumnPropertiesPanelState.js.map +1 -1
  218. package/lib/stores/view/editor/DataCubeEditorColumnSelectorState.d.ts +7 -0
  219. package/lib/stores/view/editor/DataCubeEditorColumnSelectorState.d.ts.map +1 -1
  220. package/lib/stores/view/editor/DataCubeEditorColumnSelectorState.js +20 -3
  221. package/lib/stores/view/editor/DataCubeEditorColumnSelectorState.js.map +1 -1
  222. package/lib/stores/view/editor/DataCubeEditorColumnsPanelState.d.ts.map +1 -1
  223. package/lib/stores/view/editor/DataCubeEditorColumnsPanelState.js +2 -2
  224. package/lib/stores/view/editor/DataCubeEditorColumnsPanelState.js.map +1 -1
  225. package/lib/stores/view/editor/DataCubeEditorHorizontalPivotsPanelState.d.ts +4 -4
  226. package/lib/stores/view/editor/DataCubeEditorHorizontalPivotsPanelState.d.ts.map +1 -1
  227. package/lib/stores/view/editor/DataCubeEditorHorizontalPivotsPanelState.js +14 -8
  228. package/lib/stores/view/editor/DataCubeEditorHorizontalPivotsPanelState.js.map +1 -1
  229. package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.d.ts +1 -5
  230. package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.d.ts.map +1 -1
  231. package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.js +2 -6
  232. package/lib/stores/view/editor/DataCubeEditorMutableConfiguration.js.map +1 -1
  233. package/lib/stores/view/editor/DataCubeEditorSortsPanelState.d.ts +1 -7
  234. package/lib/stores/view/editor/DataCubeEditorSortsPanelState.d.ts.map +1 -1
  235. package/lib/stores/view/editor/DataCubeEditorSortsPanelState.js +4 -19
  236. package/lib/stores/view/editor/DataCubeEditorSortsPanelState.js.map +1 -1
  237. package/lib/stores/view/editor/DataCubeEditorState.d.ts.map +1 -1
  238. package/lib/stores/view/editor/DataCubeEditorState.js +2 -2
  239. package/lib/stores/view/editor/DataCubeEditorState.js.map +1 -1
  240. package/lib/stores/view/editor/DataCubeEditorVerticalPivotsPanelState.d.ts.map +1 -1
  241. package/lib/stores/view/editor/DataCubeEditorVerticalPivotsPanelState.js +4 -4
  242. package/lib/stores/view/editor/DataCubeEditorVerticalPivotsPanelState.js.map +1 -1
  243. package/lib/stores/view/extend/DataCubeColumnEditorState.d.ts.map +1 -1
  244. package/lib/stores/view/extend/DataCubeColumnEditorState.js +2 -1
  245. package/lib/stores/view/extend/DataCubeColumnEditorState.js.map +1 -1
  246. package/lib/stores/view/extend/DataCubeExtendManagerState.d.ts.map +1 -1
  247. package/lib/stores/view/extend/DataCubeExtendManagerState.js +12 -12
  248. package/lib/stores/view/extend/DataCubeExtendManagerState.js.map +1 -1
  249. package/lib/stores/view/filter/DataCubeFilterEditorState.d.ts.map +1 -1
  250. package/lib/stores/view/filter/DataCubeFilterEditorState.js +2 -1
  251. package/lib/stores/view/filter/DataCubeFilterEditorState.js.map +1 -1
  252. package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts.map +1 -1
  253. package/lib/stores/view/grid/DataCubeGridClientEngine.js +11 -14
  254. package/lib/stores/view/grid/DataCubeGridClientEngine.js.map +1 -1
  255. package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.d.ts.map +1 -1
  256. package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js +48 -12
  257. package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js.map +1 -1
  258. package/lib/stores/view/grid/DataCubeGridControllerState.d.ts +1 -1
  259. package/lib/stores/view/grid/DataCubeGridControllerState.d.ts.map +1 -1
  260. package/lib/stores/view/grid/DataCubeGridControllerState.js +20 -20
  261. package/lib/stores/view/grid/DataCubeGridControllerState.js.map +1 -1
  262. package/lib/stores/view/grid/DataCubeGridMenuBuilder.d.ts.map +1 -1
  263. package/lib/stores/view/grid/DataCubeGridMenuBuilder.js +8 -12
  264. package/lib/stores/view/grid/DataCubeGridMenuBuilder.js.map +1 -1
  265. package/lib/stores/view/grid/DataCubeGridQueryBuilder.js +1 -1
  266. package/lib/stores/view/grid/DataCubeGridQueryBuilder.js.map +1 -1
  267. package/lib/stores/view/grid/DataCubeGridQuerySnapshotBuilder.js +1 -1
  268. package/lib/stores/view/grid/DataCubeGridQuerySnapshotBuilder.js.map +1 -1
  269. package/package.json +8 -8
  270. package/src/__lib__/DataCubeSetting.ts +1 -0
  271. package/src/components/view/editor/DataCubeEditorColumnPropertiesPanel.tsx +40 -17
  272. package/src/components/view/editor/DataCubeEditorColumnSelector.tsx +75 -1
  273. package/src/components/view/editor/DataCubeEditorColumnsPanel.tsx +3 -6
  274. package/src/components/view/editor/DataCubeEditorHorizontalPivotsPanel.tsx +5 -12
  275. package/src/components/view/editor/DataCubeEditorSortsPanel.tsx +12 -80
  276. package/src/components/view/filter/DataCubeFilterEditor.tsx +2 -3
  277. package/src/stores/core/DataCubeConfigurationBuilder.ts +80 -5
  278. package/src/stores/core/DataCubeEngine.tsx +10 -2
  279. package/src/stores/core/DataCubeQueryBuilder.ts +36 -37
  280. package/src/stores/core/DataCubeQueryBuilderUtils.ts +74 -41
  281. package/src/stores/core/DataCubeQueryEngine.ts +120 -60
  282. package/src/stores/core/DataCubeQuerySnapshot.ts +13 -0
  283. package/src/stores/core/DataCubeQuerySnapshotBuilder.ts +379 -157
  284. package/src/stores/core/DataCubeQuerySnapshotBuilderUtils.ts +597 -157
  285. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation.ts +39 -16
  286. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__Average.tsx +26 -4
  287. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__Count.tsx +26 -4
  288. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__First.tsx +26 -4
  289. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__JoinStrings.tsx +41 -26
  290. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__Last.tsx +26 -4
  291. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__Max.tsx +26 -4
  292. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__Min.tsx +26 -4
  293. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__StdDevPopulation.tsx +29 -6
  294. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__StdDevSample.tsx +30 -4
  295. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__Sum.tsx +26 -4
  296. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__UniqueValue.tsx +26 -4
  297. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__VariancePopulation.tsx +26 -4
  298. package/src/stores/core/aggregation/DataCubeQueryAggregateOperation__VarianceSample.tsx +26 -4
  299. package/src/stores/core/filter/DataCubeQueryFilterOperation.ts +1 -52
  300. package/src/stores/core/filter/DataCubeQueryFilterOperation__Contain.tsx +12 -9
  301. package/src/stores/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.tsx +10 -13
  302. package/src/stores/core/filter/DataCubeQueryFilterOperation__EndWith.tsx +9 -10
  303. package/src/stores/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.tsx +10 -13
  304. package/src/stores/core/filter/DataCubeQueryFilterOperation__Equal.tsx +5 -8
  305. package/src/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.tsx +10 -13
  306. package/src/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.tsx +6 -8
  307. package/src/stores/core/filter/DataCubeQueryFilterOperation__EqualColumn.tsx +5 -7
  308. package/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThan.tsx +6 -9
  309. package/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.tsx +6 -8
  310. package/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.tsx +6 -9
  311. package/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.tsx +6 -8
  312. package/src/stores/core/filter/DataCubeQueryFilterOperation__IsNotNull.tsx +6 -8
  313. package/src/stores/core/filter/DataCubeQueryFilterOperation__IsNull.tsx +6 -2
  314. package/src/stores/core/filter/DataCubeQueryFilterOperation__LessThan.tsx +6 -9
  315. package/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanColumn.tsx +6 -8
  316. package/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.tsx +6 -9
  317. package/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.tsx +6 -8
  318. package/src/stores/core/filter/DataCubeQueryFilterOperation__NotContain.tsx +12 -15
  319. package/src/stores/core/filter/DataCubeQueryFilterOperation__NotEndWith.tsx +12 -15
  320. package/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqual.tsx +10 -14
  321. package/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.tsx +11 -20
  322. package/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.tsx +7 -19
  323. package/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.tsx +9 -17
  324. package/src/stores/core/filter/DataCubeQueryFilterOperation__NotStartWith.tsx +10 -17
  325. package/src/stores/core/filter/DataCubeQueryFilterOperation__StartWith.tsx +9 -10
  326. package/src/stores/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.tsx +10 -13
  327. package/src/stores/core/model/DataCubeColumn.ts +1 -1
  328. package/src/stores/core/model/DataCubeConfiguration.ts +7 -1
  329. package/src/stores/services/DataCubeQuerySnapshotService.ts +2 -1
  330. package/src/stores/services/DataCubeSettingService.tsx +8 -0
  331. package/src/stores/view/DataCubeViewState.ts +2 -3
  332. package/src/stores/view/editor/DataCubeEditorColumnPropertiesPanelState.ts +3 -2
  333. package/src/stores/view/editor/DataCubeEditorColumnSelectorState.ts +31 -6
  334. package/src/stores/view/editor/DataCubeEditorColumnsPanelState.ts +2 -7
  335. package/src/stores/view/editor/DataCubeEditorHorizontalPivotsPanelState.ts +33 -10
  336. package/src/stores/view/editor/DataCubeEditorMutableConfiguration.ts +4 -20
  337. package/src/stores/view/editor/DataCubeEditorSortsPanelState.ts +6 -29
  338. package/src/stores/view/editor/DataCubeEditorState.tsx +2 -3
  339. package/src/stores/view/editor/DataCubeEditorVerticalPivotsPanelState.ts +6 -7
  340. package/src/stores/view/extend/DataCubeColumnEditorState.tsx +2 -3
  341. package/src/stores/view/extend/DataCubeExtendManagerState.tsx +14 -13
  342. package/src/stores/view/filter/DataCubeFilterEditorState.tsx +2 -4
  343. package/src/stores/view/grid/DataCubeGridClientEngine.ts +21 -20
  344. package/src/stores/view/grid/DataCubeGridConfigurationBuilder.tsx +64 -15
  345. package/src/stores/view/grid/DataCubeGridControllerState.ts +35 -34
  346. package/src/stores/view/grid/DataCubeGridMenuBuilder.tsx +17 -23
  347. package/src/stores/view/grid/DataCubeGridQueryBuilder.ts +1 -1
  348. package/src/stores/view/grid/DataCubeGridQuerySnapshotBuilder.ts +1 -1
@@ -25,44 +25,81 @@
25
25
  import {
26
26
  V1_AppliedFunction,
27
27
  V1_CInteger,
28
- V1_Collection,
29
28
  extractElementNameFromPath as _name,
30
29
  matchFunctionName,
31
30
  type V1_ValueSpecification,
32
31
  V1_Lambda,
33
32
  } from '@finos/legend-graph';
34
33
  import type { DataCubeQuery } from './model/DataCubeQuery.js';
35
- import { DataCubeQuerySnapshot } from './DataCubeQuerySnapshot.js';
36
- import { _toCol, type DataCubeColumn } from './model/DataCubeColumn.js';
37
- import { assertTrue, at, guaranteeNonNullable } from '@finos/legend-shared';
38
34
  import {
39
- DataCubeQuerySortDirection,
35
+ DataCubeQuerySnapshot,
36
+ type DataCubeQuerySnapshotAggregateColumn,
37
+ type DataCubeQuerySnapshotProcessingContext,
38
+ type DataCubeQuerySnapshotSortColumn,
39
+ } from './DataCubeQuerySnapshot.js';
40
+ import {
41
+ _findCol,
42
+ _toCol,
43
+ type DataCubeColumn,
44
+ } from './model/DataCubeColumn.js';
45
+ import {
46
+ assertTrue,
47
+ at,
48
+ guaranteeNonNullable,
49
+ isNonNullable,
50
+ } from '@finos/legend-shared';
51
+ import {
40
52
  DataCubeFunction,
41
53
  type DataCubeQueryFunctionMap,
42
54
  } from './DataCubeQueryEngine.js';
43
- import { buildDefaultConfiguration } from './DataCubeConfigurationBuilder.js';
55
+ import { newConfiguration } from './DataCubeConfigurationBuilder.js';
44
56
  import {
45
57
  _colSpecArrayParam,
46
- _colSpecParam,
47
- _funcMatch,
48
58
  _param,
49
59
  _extractExtendedColumns,
50
60
  _filter,
51
61
  _relationType,
52
62
  _genericTypeParam,
53
63
  _packageableType,
64
+ _aggCol,
65
+ _sort,
66
+ _unwrapLambda,
67
+ _pivotSort,
68
+ _groupBySort,
69
+ _validatePivot,
70
+ _checkDuplicateColumns,
71
+ _validateGroupBy,
54
72
  } from './DataCubeQuerySnapshotBuilderUtils.js';
55
73
  import type { DataCubeSource } from './model/DataCubeSource.js';
56
- import type { DataCubeQueryFilterOperation } from './filter/DataCubeQueryFilterOperation.js';
57
- import type { DataCubeQueryAggregateOperation } from './aggregation/DataCubeQueryAggregateOperation.js';
74
+ import type { DataCubeEngine } from './DataCubeEngine.js';
75
+ import {
76
+ _deserializeValueSpecification,
77
+ _serializeValueSpecification,
78
+ } from './DataCubeQueryBuilderUtils.js';
58
79
 
59
80
  // --------------------------------- BUILDING BLOCKS ---------------------------------
60
81
 
61
82
  const _SUPPORTED_TOP_LEVEL_FUNCTIONS: {
62
83
  func: string;
84
+ /**
85
+ * If there are multiple signature to a function, such as extend(), this indicates
86
+ * the minimum number of parameters. And a stopping condition needs to be provided.
87
+ *
88
+ * Note that this is a naive mechanism to process simple functions, by no means, it's
89
+ * meant to mimic generic function matcher.
90
+ */
63
91
  parameters: number;
92
+ stopCondition?: ((_func: V1_AppliedFunction) => boolean) | undefined;
64
93
  }[] = [
65
- { func: DataCubeFunction.EXTEND, parameters: 2 }, // TODO: support both signatures of extend()
94
+ {
95
+ func: DataCubeFunction.EXTEND,
96
+ parameters: 1,
97
+ // handle OLAP form where first parameter is over() expression used to construct the window
98
+ stopCondition: (_func) =>
99
+ matchFunctionName(_func.function, DataCubeFunction.EXTEND) &&
100
+ _func.parameters[0] instanceof V1_AppliedFunction &&
101
+ matchFunctionName(_func.parameters[0].function, DataCubeFunction.OVER),
102
+ },
66
103
  { func: DataCubeFunction.FILTER, parameters: 1 },
67
104
  { func: DataCubeFunction.SELECT, parameters: 1 },
68
105
  { func: DataCubeFunction.GROUP_BY, parameters: 2 },
@@ -102,14 +139,6 @@ enum _FUNCTION_SEQUENCE_COMPOSITION_PART {
102
139
  LIMIT = 'limit',
103
140
  }
104
141
 
105
- // function isFunctionInValidSequence(
106
- // value: string,
107
- // ): value is _FUNCTION_SEQUENCE_COMPOSITION_PART {
108
- // return Object.values(_FUNCTION_SEQUENCE_COMPOSITION_PART).includes(
109
- // value as _FUNCTION_SEQUENCE_COMPOSITION_PART,
110
- // );
111
- // }
112
-
113
142
  // This corresponds to the function sequence that we currently support:
114
143
  //
115
144
  // ->extend()*
@@ -199,10 +228,10 @@ const _FUNCTION_SEQUENCE_COMPOSITION_PATTERN_REGEXP = new RegExp(
199
228
  ? `(${node.funcs
200
229
  .map(
201
230
  (childNode) =>
202
- `(?<${childNode.name}><${_name(childNode.func)}>____\\d+)${childNode.repeat ? '*' : !childNode.required ? '?' : ''}`,
231
+ `(?<${childNode.name}>${childNode.repeat ? `(?:<${_name(childNode.func)}>____\\d+)*` : `<${_name(childNode.func)}>____\\d+`})${childNode.repeat ? '' : !childNode.required ? '?' : ''}`,
203
232
  )
204
233
  .join('')})${node.repeat ? '*' : !node.required ? '?' : ''}`
205
- : `(?<${node.name}><${_name(node.func)}>____\\d+)${node.repeat ? '*' : !node.required ? '?' : ''}`,
234
+ : `(?<${node.name}>${node.repeat ? `(?:<${_name(node.func)}>____\\d+)*` : `<${_name(node.func)}>____\\d+`})${node.repeat ? '' : !node.required ? '?' : ''}`,
206
235
  )
207
236
  .join('')}$`,
208
237
  );
@@ -216,7 +245,7 @@ function extractFunctionMap(
216
245
  ): DataCubeQueryFunctionMap {
217
246
  // Make sure this is a sequence of function calls
218
247
  if (!(query instanceof V1_AppliedFunction)) {
219
- throw new Error(`Can't process expression: Expected a function expression`);
248
+ throw new Error(`Can't process expression: expected a function expression`);
220
249
  }
221
250
  const sequence: V1_AppliedFunction[] = [];
222
251
  let currentFunc = query;
@@ -229,7 +258,7 @@ function extractFunctionMap(
229
258
  // Check that all functions in sequence are supported (matching name and number of parameters)
230
259
  if (!supportedFunc) {
231
260
  throw new Error(
232
- `Can't process expression: Found unsupported function ${currentFunc.function}()`,
261
+ `Can't process expression: found unsupported function ${currentFunc.function}()`,
233
262
  );
234
263
  }
235
264
 
@@ -238,16 +267,22 @@ function extractFunctionMap(
238
267
  // t(...)->z()->y()->x() and simultaneously, remove the first parameter from each function for
239
268
  // simplicity, except for the innermost function
240
269
  if (currentFunc.parameters.length > supportedFunc.parameters) {
270
+ // if stop condition is fulfilled, no more function sequence drilling is needed
271
+ if (supportedFunc.stopCondition?.(currentFunc)) {
272
+ sequence.unshift(currentFunc);
273
+ break;
274
+ }
275
+
241
276
  // assert that the supported function has the expected number of parameters
242
277
  assertTrue(
243
278
  currentFunc.parameters.length === supportedFunc.parameters + 1,
244
- `Can't process ${_name(currentFunc.function)}() expression: Expected at most ${supportedFunc.parameters + 1} parameters provided, got ${currentFunc.parameters.length}`,
279
+ `Can't process ${_name(currentFunc.function)}() expression: expected at most ${supportedFunc.parameters + 1} parameters provided, got ${currentFunc.parameters.length}`,
245
280
  );
246
281
  const func = _param(
247
282
  currentFunc,
248
283
  0,
249
284
  V1_AppliedFunction,
250
- `Can't process expression: Expected a sequence of function calls (e.g. x()->y()->z())`,
285
+ `Can't process expression: expected a sequence of function calls (e.g. x()->y()->z())`,
251
286
  );
252
287
  currentFunc.parameters = currentFunc.parameters.slice(1);
253
288
  sequence.unshift(currentFunc);
@@ -267,35 +302,46 @@ function extractFunctionMap(
267
302
  );
268
303
  if (!matchResult) {
269
304
  throw new Error(
270
- `Can't process expression: Unsupported function composition ${sequence.map((fn) => `${_name(fn.function)}()`).join('->')} (supported composition: ${_FUNCTION_SEQUENCE_COMPOSITION_PATTERN.map((node) => `${'funcs' in node ? `[${node.funcs.map((childNode) => `${_name(childNode.func)}()`).join('->')}]` : `${_name(node.func)}()`}`).join('->')})`,
305
+ `Can't process expression: unsupported function composition ${sequence.map((fn) => `${_name(fn.function)}()`).join('->')} (supported composition: ${_FUNCTION_SEQUENCE_COMPOSITION_PATTERN.map((node) => `${'funcs' in node ? `[${node.funcs.map((childNode) => `${_name(childNode.func)}()`).join('->')}]` : `${_name(node.func)}()`}`).join('->')})`,
271
306
  );
272
307
  }
273
308
 
274
- const _process = (key: string): V1_AppliedFunction | undefined => {
309
+ const _process = (key: string): V1_AppliedFunction[] | undefined => {
275
310
  const match = matchResult.groups?.[key];
276
- if (!match || match.indexOf('____') === -1) {
311
+ if (!match) {
277
312
  return undefined;
278
313
  }
279
- const idx = Number(match.split('____')[1]);
280
- if (isNaN(idx) || idx >= sequence.length) {
314
+ const funcMatches = match.match(/\<.*?\>____\d+/g);
315
+ if (!funcMatches?.length) {
281
316
  return undefined;
282
317
  }
283
- const func = at(sequence, idx);
284
- return func;
318
+
319
+ return funcMatches
320
+ .map((funcMatch) => {
321
+ const idx = Number(funcMatch.split('____')[1]);
322
+ if (isNaN(idx) || idx >= sequence.length) {
323
+ return undefined;
324
+ }
325
+ const func = at(sequence, idx);
326
+ return func;
327
+ })
328
+ .filter(isNonNullable);
285
329
  };
286
330
 
287
331
  return {
288
332
  leafExtend: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.LEAF_EXTEND),
289
- select: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.SELECT),
290
- filter: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.FILTER),
291
- pivotSort: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_SORT),
292
- pivot: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT),
293
- pivotCast: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_CAST),
294
- groupBy: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_BY),
295
- groupBySort: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_BY_SORT),
333
+ select: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.SELECT)?.[0],
334
+ filter: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.FILTER)?.[0],
335
+ pivotSort: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_SORT)?.[0],
336
+ pivot: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT)?.[0],
337
+ pivotCast: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_CAST)?.[0],
338
+ groupBy: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_BY)?.[0],
339
+ groupBySort: _process(
340
+ _FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_BY_SORT,
341
+ )?.[0],
296
342
  groupExtend: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_EXTEND),
297
- sort: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.SORT),
298
- limit: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.LIMIT),
343
+ sort: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.SORT)?.[0],
344
+ limit: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.LIMIT)?.[0],
299
345
  };
300
346
  }
301
347
 
@@ -307,31 +353,34 @@ function extractFunctionMap(
307
353
  * Implementation-wise, this extracts the function call sequence, then walk the
308
354
  * sequence in order to fill in the information for the snapshot.
309
355
  */
310
- export function validateAndBuildQuerySnapshot(
356
+ export async function validateAndBuildQuerySnapshot(
311
357
  partialQuery: V1_ValueSpecification,
312
358
  source: DataCubeSource,
313
359
  baseQuery: DataCubeQuery,
314
- filterOperations: DataCubeQueryFilterOperation[],
315
- aggregateOperations: DataCubeQueryAggregateOperation[],
360
+ engine: DataCubeEngine,
316
361
  ) {
317
362
  // --------------------------------- BASE ---------------------------------
318
363
  // Build the function call sequence and the function map to make the
319
364
  // analysis more ergonomic
320
365
 
321
- const funcMap = extractFunctionMap(partialQuery);
366
+ // Clone the query since we will mutate it during the process
367
+ const query = _deserializeValueSpecification(
368
+ _serializeValueSpecification(partialQuery),
369
+ );
370
+ const funcMap = extractFunctionMap(query);
322
371
  const snapshot = DataCubeQuerySnapshot.create({});
323
372
  const data = snapshot.data;
324
- const columnNames = new Set<string>();
373
+ const registeredColumns = new Map<string, DataCubeColumn>();
325
374
  /**
326
375
  * We want to make sure all columns, either from source or created, e.g. extended columns,
327
376
  * have unique names. This is to simplify the logic within DataCube so different components
328
377
  * can easily refer to columns by name without having to worry about conflicts.
329
378
  */
330
379
  const _checkColName = (col: DataCubeColumn, message: string) => {
331
- if (columnNames.has(col.name)) {
380
+ if (registeredColumns.has(col.name)) {
332
381
  throw new Error(message);
333
382
  }
334
- columnNames.add(col.name);
383
+ registeredColumns.set(col.name, col);
335
384
  };
336
385
  const colsMap = new Map<string, DataCubeColumn>();
337
386
  const _getCol = (colName: string) => {
@@ -342,53 +391,66 @@ export function validateAndBuildQuerySnapshot(
342
391
  return _toCol(column);
343
392
  };
344
393
  const _setCol = (col: DataCubeColumn) => colsMap.set(col.name, col);
345
- // const _unsetCol = (col: DataCubeColumn) => colsMap.delete(col.name);
346
394
 
347
395
  // -------------------------------- SOURCE --------------------------------
348
396
 
349
397
  data.sourceColumns = source.columns;
350
- data.sourceColumns.forEach((col) => _setCol(col));
398
+
399
+ // validate
400
+ _checkDuplicateColumns(
401
+ data.sourceColumns,
402
+ (colName) =>
403
+ `Can't process source: found duplicate source columns '${colName}'`,
404
+ );
351
405
  data.sourceColumns.forEach((col) =>
352
406
  _checkColName(
353
407
  col,
354
- `Can't process source column '${col.name}': another column with the same name is already registered`,
408
+ `Can't process source: another column with name '${col.name}' is already registered`,
355
409
  ),
356
410
  );
357
411
 
412
+ data.sourceColumns.forEach((col) => _setCol(col));
413
+
358
414
  // --------------------------- LEAF-LEVEL EXTEND ---------------------------
359
415
 
360
- if (funcMap.leafExtend) {
361
- // TODO: get column types (call engine to get the type)
362
- data.leafExtendedColumns = _extractExtendedColumns(funcMap.leafExtend);
363
- // TODO: populate the column types
364
- data.leafExtendedColumns.forEach((col) => _setCol(col));
416
+ if (funcMap.leafExtend?.length) {
417
+ data.leafExtendedColumns = await _extractExtendedColumns(
418
+ funcMap.leafExtend,
419
+ Array.from(colsMap.values()),
420
+ engine,
421
+ );
422
+
423
+ // validate
424
+ // NOTE: these duplication checks might not be necessary since compiler would catch these
425
+ // issues anyway, but we leave them here to be defensive
426
+ _checkDuplicateColumns(
427
+ data.leafExtendedColumns,
428
+ (colName) =>
429
+ `Can't process extend() expression: found duplicate extended columns '${colName}'`,
430
+ );
365
431
  data.leafExtendedColumns.forEach((col) =>
366
432
  _checkColName(
367
433
  col,
368
- `Can't process leaf-level extended column '${col.name}': another column with the same name is already registered`,
434
+ `Can't process extend() expression: another column with name '${col.name}' is already registered`,
369
435
  ),
370
436
  );
437
+
438
+ data.leafExtendedColumns.forEach((col) => _setCol(col));
371
439
  }
372
440
 
373
441
  // --------------------------------- FILTER ---------------------------------
374
442
 
375
443
  if (funcMap.filter) {
376
- // TODO: verify column presence
377
- // TODO: verify column types
378
444
  const lambda = _param(
379
445
  funcMap.filter,
380
446
  0,
381
447
  V1_Lambda,
382
- `Can't process filter() expression: Expected parameter at index 0 to be a lambda expression`,
383
- );
384
- assertTrue(
385
- lambda.body.length === 1,
386
- `Can't process filter() expression: Expected lambda body to have exactly 1 expression`,
448
+ `Can't process filter() expression: expected parameter at index 0 to be a lambda expression`,
387
449
  );
388
450
  data.filter = _filter(
389
- guaranteeNonNullable(lambda.body[0]),
451
+ _unwrapLambda(lambda, `Can't process filter() expression`),
390
452
  _getCol,
391
- filterOperations,
453
+ engine.filterOperations,
392
454
  );
393
455
  }
394
456
 
@@ -398,119 +460,156 @@ export function validateAndBuildQuerySnapshot(
398
460
  data.selectColumns = _colSpecArrayParam(funcMap.select, 0).colSpecs.map(
399
461
  (colSpec) => _getCol(colSpec.name),
400
462
  );
401
- // TODO: remove columns that are not selected from colsMap
463
+
464
+ // validate
465
+ _checkDuplicateColumns(
466
+ data.selectColumns,
467
+ (colName) =>
468
+ `Can't process select() expression: found duplicate select columns '${colName}'`,
469
+ );
470
+
471
+ // restrict the set of available columns to only selected columns
472
+ colsMap.clear();
473
+ data.selectColumns.forEach((col) => _setCol(col));
474
+ } else {
475
+ // mandate that if select() expression is not present, we consider this
476
+ // as no-column is selected
477
+ colsMap.clear();
402
478
  }
403
479
 
404
480
  // --------------------------------- PIVOT ---------------------------------
405
481
 
406
- if (funcMap.pivot && funcMap.pivotCast) {
407
- // TODO: verify column presence
408
- // TODO: verify column types
482
+ let pivotAggColumns: DataCubeQuerySnapshotAggregateColumn[] = [];
483
+ let pivotSortColumns: DataCubeQuerySnapshotSortColumn[] = [];
484
+ if (funcMap.pivot && funcMap.pivotCast && funcMap.pivotSort) {
485
+ const pivotColumns = _colSpecArrayParam(funcMap.pivot, 0).colSpecs.map(
486
+ (colSpec) => _getCol(colSpec.name),
487
+ );
488
+ const castColumns = _relationType(
489
+ _genericTypeParam(funcMap.pivotCast, 0).genericType,
490
+ ).columns.map((column) => ({
491
+ name: column.name,
492
+ type: _packageableType(column.genericType).fullPath,
493
+ }));
409
494
  data.pivot = {
410
- columns: _colSpecArrayParam(funcMap.pivot, 0).colSpecs.map((colSpec) =>
411
- _getCol(colSpec.name),
412
- ),
413
- castColumns: _relationType(
414
- _genericTypeParam(funcMap.pivotCast, 0).genericType,
415
- ).columns.map((column) => ({
416
- name: column.name,
417
- type: _packageableType(column.genericType).fullPath,
418
- })),
495
+ columns: pivotColumns,
496
+ castColumns: castColumns,
419
497
  };
498
+
499
+ // process aggregate columns
500
+ pivotAggColumns = _colSpecArrayParam(funcMap.pivot, 1).colSpecs.map(
501
+ (colSpec) => _aggCol(colSpec, _getCol, engine.aggregateOperations),
502
+ );
503
+ // process sort columns
504
+ pivotSortColumns = _pivotSort(funcMap.pivotSort, pivotColumns, _getCol);
505
+
506
+ // validate
507
+ _validatePivot(data.pivot, pivotAggColumns, Array.from(colsMap.values()));
508
+
509
+ // restrict the set of available columns to only casted columns
510
+ colsMap.clear();
511
+ castColumns.forEach((col) => _setCol(col));
420
512
  }
421
- // TODO: verify groupBy agg columns, pivot agg columns and configuration agree
422
513
 
423
514
  // --------------------------------- GROUP BY ---------------------------------
424
515
 
425
- if (funcMap.groupBy) {
426
- // TODO: verify column presence
427
- // TODO: verify column types
516
+ let groupByAggColumns: DataCubeQuerySnapshotAggregateColumn[] = [];
517
+ let groupBySortColumns: DataCubeQuerySnapshotSortColumn[] = [];
518
+ if (funcMap.groupBy && funcMap.groupBySort) {
519
+ const groupByColumns = _colSpecArrayParam(funcMap.groupBy, 0).colSpecs.map(
520
+ (colSpec) => _getCol(colSpec.name),
521
+ );
428
522
  data.groupBy = {
429
- columns: _colSpecArrayParam(funcMap.groupBy, 0).colSpecs.map((colSpec) =>
430
- _getCol(colSpec.name),
431
- ),
523
+ columns: groupByColumns,
432
524
  };
433
- // TODO: verify groupBy agg columns, pivot agg columns and configuration agree
434
- // TODO: verify sort columns
435
- // TODO: use configuration information present in the baseQuery configuration?
525
+
526
+ // process aggregate columns
527
+ groupByAggColumns = _colSpecArrayParam(funcMap.groupBy, 1).colSpecs.map(
528
+ (colSpec) => _aggCol(colSpec, _getCol, engine.aggregateOperations),
529
+ );
530
+ // process sort columns
531
+ groupBySortColumns = _groupBySort(
532
+ funcMap.groupBySort,
533
+ groupByColumns,
534
+ _getCol,
535
+ );
536
+
537
+ // validate
538
+ _validateGroupBy(
539
+ data.groupBy,
540
+ groupByAggColumns,
541
+ data.pivot,
542
+ pivotAggColumns,
543
+ Array.from(colsMap.values()),
544
+ );
436
545
  }
437
546
 
438
547
  // --------------------------- GROUP-LEVEL EXTEND ---------------------------
439
548
 
440
- if (funcMap.groupExtend) {
441
- // TODO: get column types (call engine to get the type)
442
- data.groupExtendedColumns = _extractExtendedColumns(funcMap.groupExtend);
443
- // TODO: populate the column types
444
- data.groupExtendedColumns.forEach((col) => _setCol(col));
549
+ if (funcMap.groupExtend?.length) {
550
+ data.groupExtendedColumns = await _extractExtendedColumns(
551
+ funcMap.groupExtend,
552
+ Array.from(colsMap.values()),
553
+ engine,
554
+ );
555
+
556
+ // validate
557
+ // NOTE: these duplication checks might not be necessary since compiler would catch these
558
+ // issues anyway, but we leave them here to be defensive
559
+ _checkDuplicateColumns(
560
+ data.groupExtendedColumns,
561
+ (colName) =>
562
+ `Can't process extend() expression: found duplicate extended columns '${colName}'`,
563
+ );
445
564
  data.groupExtendedColumns.forEach((col) =>
446
565
  _checkColName(
447
566
  col,
448
- `Can't process group-level extended column '${col.name}': another column with the same name is already registered`,
567
+ `Can't process extend() expression: another column with name '${col.name}' is already registered`,
449
568
  ),
450
569
  );
570
+
571
+ data.groupExtendedColumns.forEach((col) => _setCol(col));
451
572
  }
452
573
 
453
574
  // --------------------------------- SORT ---------------------------------
454
575
 
455
576
  if (funcMap.sort) {
456
- data.sortColumns = _param(funcMap.sort, 0, V1_Collection).values.map(
457
- (value) => {
458
- const sortColFunc = _funcMatch(value, [
459
- DataCubeFunction.ASCENDING,
460
- DataCubeFunction.DESCENDING,
461
- ]);
462
- return {
463
- ..._getCol(_colSpecParam(sortColFunc, 0).name),
464
- direction: matchFunctionName(
465
- sortColFunc.function,
466
- DataCubeFunction.ASCENDING,
467
- )
468
- ? DataCubeQuerySortDirection.ASCENDING
469
- : DataCubeQuerySortDirection.DESCENDING,
470
- };
471
- },
577
+ data.sortColumns = _sort(funcMap.sort, _getCol);
578
+
579
+ // validate
580
+ _checkDuplicateColumns(
581
+ data.sortColumns,
582
+ (colName) =>
583
+ `Can't process sort() expression: found duplicate sort columns '${colName}'`,
472
584
  );
473
585
  }
474
586
 
475
587
  // --------------------------------- LIMIT ---------------------------------
476
588
 
477
589
  if (funcMap.limit) {
590
+ // NOTE: negative number -10 is parsed as minus(10) so this check will also
591
+ // reject negative number
478
592
  const value = _param(
479
593
  funcMap.limit,
480
594
  0,
481
595
  V1_CInteger,
482
- `Can't process limit() expression: Expected parameter at index 0 to be an integer instance value`,
596
+ `Can't process limit() expression: expected limit to be a non-negative integer value`,
483
597
  );
484
598
  data.limit = value.value;
485
599
  }
486
600
 
487
601
  // --------------------------------- CONFIGURATION ---------------------------------
488
- //
489
- // A data-cube conceptually consists of a data query, in form of a Pure query, instead
490
- // of a particular specification object format, and this configuration, that holds mostly
491
- // layout and styling customization. But there are overlaps, i.e. certain "meta" query
492
- // configuration are stored in this configuration, e.g. column aggregation type, because
493
- // a column aggregation's preference needs to be specified even when there's no aggregation
494
- // specified over that column in the data query.
495
- //
496
- // But in the example above, if the column is part of an aggregation, we have to ensure
497
- // the configuration is consistent with the query. Conflicts can happen, for example:
498
- // - column kind and type conflict with aggregation
499
- // - column kind and type conflict with the column configuration
500
- //
501
- // In those cases, we need to reconcile to make sure the query and the configuration to agree.
502
- // The query will take precedence when conflicts happen, and if the conflict cannot be resolved
503
- // somehow, we will throw a validation error. We decide so because in certain cases, configuration
504
- // needs to be generated from default presets, such as for use cases where the query comes from a
505
- // different source, such as Studio or Query, or another part of Engine, where the layout
506
- // configuration is not specified.
507
- //
508
- // ----------------------------------------------------------------------------------
509
602
 
510
603
  const configuration = validateAndBuildConfiguration(
511
- snapshot,
512
- funcMap,
604
+ {
605
+ snapshot,
606
+ groupByAggColumns,
607
+ groupBySortColumns,
608
+ pivotAggColumns,
609
+ pivotSortColumns,
610
+ },
513
611
  baseQuery,
612
+ engine,
514
613
  );
515
614
  data.configuration = configuration.serialize();
516
615
 
@@ -518,32 +617,155 @@ export function validateAndBuildQuerySnapshot(
518
617
  }
519
618
 
520
619
  /**
521
- * TODO: @datacube roundtrip - implement the logic to reconcile the configuration with the query
522
- * - [ ] columns (missing/extra columns - remove or generate default column configuration)
523
- * - [ ] base off the type and kind, check the settings to see if it's compatible
524
- * - [ ] verify groupBy agg columns, pivot agg columns and configuration agree
525
- * - [ ] verify groupBy sort columns and tree column sort direction configuration agree
620
+ * Builds and/or validates the configuration.
621
+ *
622
+ * TL;DR;
623
+ * If not provided, generate a default configuration based off the metadata extracted
624
+ * when processing the query in previous steps.
625
+ * If provided, check if the configuration aggree with the query processing metadata.
626
+ *
627
+ * CONTEXT:
628
+ * A data-cube conceptually consists of a data query, in form of a Pure query, instead
629
+ * of a particular specification object format, and this configuration, that holds mostly
630
+ * layout and styling customization. But there are overlaps, i.e. certain _meta_ query
631
+ * configuration are stored in this configuration, e.g. column aggregation type, because
632
+ * a column aggregation's preference needs to be specified even when there's no aggregation
633
+ * specified over that column in the data query.
634
+ *
635
+ * But in the example above, if the column is part of an aggregation, we have to ensure
636
+ * the configuration is consistent with the query. Conflicts can happen, for example:
637
+ * - column kind and type conflict with aggregation
638
+ * - column kind and type conflict with the column configuration
639
+ *
640
+ * In those cases, we need to make sure the query and the configuration to agree.
641
+ * If a config is provided, we will need to validate that config. If none is provided,
642
+ * we will generate a config from the query processing metadata, in which case, no
643
+ * validation is needed. The latter case comes up quite often where the query comes from a
644
+ * different source, such as Studio or Query, or another part of Engine, and the layout
645
+ * configuration is not specified.
526
646
  */
527
647
  function validateAndBuildConfiguration(
528
- snapshot: DataCubeQuerySnapshot,
529
- funcMap: DataCubeQueryFunctionMap,
648
+ context: DataCubeQuerySnapshotProcessingContext,
530
649
  baseQuery: DataCubeQuery,
650
+ engine: DataCubeEngine,
531
651
  ) {
532
- const data = snapshot.data;
533
- const configuration =
534
- baseQuery.configuration?.clone() ??
535
- buildDefaultConfiguration([
536
- ...data.sourceColumns,
537
- ...data.leafExtendedColumns,
538
- ...data.groupExtendedColumns,
539
- ]);
540
-
541
- // column selection
542
- configuration.columns.forEach((column) => {
543
- column.isSelected = Boolean(
544
- data.groupExtendedColumns.find((col) => col.name === column.name) ??
545
- data.selectColumns.find((col) => col.name === column.name),
652
+ const data = context.snapshot.data;
653
+ const config = baseQuery.configuration;
654
+ // generate a default configuration anyway to be used to compare with the
655
+ // provided configuration for validation purpose
656
+ const _config = newConfiguration(context);
657
+
658
+ if (!config) {
659
+ return _config;
660
+ }
661
+
662
+ // check tree column sort direction (only relevant if groupBy is present)
663
+ if (data.groupBy) {
664
+ assertTrue(
665
+ config.treeColumnSortDirection === _config.treeColumnSortDirection,
666
+ `Can't process configuration: tree column sort direction mismatch (expected: '${_config.treeColumnSortDirection.toLowerCase()}', found: '${config.treeColumnSortDirection.toLowerCase()}')`,
667
+ );
668
+ }
669
+
670
+ // check columns
671
+ const columns = config.columns;
672
+ const _columns = _config.columns;
673
+ const columnNames = new Set<string>();
674
+
675
+ // check for duplicate columns
676
+ columns.forEach((col) => {
677
+ if (columnNames.has(col.name)) {
678
+ throw new Error(
679
+ `Can't process configuration: found duplicate columns '${col.name}'`,
680
+ );
681
+ } else {
682
+ columnNames.add(col.name);
683
+ }
684
+ });
685
+
686
+ // check for extra columns
687
+ columns.forEach((col) => {
688
+ if (!_findCol(_columns, col.name)) {
689
+ throw new Error(
690
+ `Can't process configuration: found extra column '${col.name}'`,
691
+ );
692
+ }
693
+ });
694
+
695
+ // check for missing columns
696
+ _columns.forEach((col) => {
697
+ if (!_findCol(columns, col.name)) {
698
+ throw new Error(
699
+ `Can't process configuration: missing column '${col.name}'`,
700
+ );
701
+ }
702
+ });
703
+
704
+ // check for columns ordering
705
+ const columnsOrdering = [
706
+ ...data.selectColumns,
707
+ ...data.groupExtendedColumns,
708
+ ...[...data.sourceColumns, ...data.leafExtendedColumns].filter(
709
+ (col) => !_findCol(data.selectColumns, col.name),
710
+ ),
711
+ ];
712
+ columnsOrdering.forEach((_col, idx) => {
713
+ const col = at(columns, idx);
714
+ assertTrue(
715
+ _col.name === col.name,
716
+ `Can't process configuration: column ordering mismatch at index ${idx} (expected: '${_col.name}', found: '${col.name})', expected ordering: ${columnsOrdering.map((c) => c.name).join(', ')}`,
717
+ );
718
+ });
719
+
720
+ columns.forEach((column) => {
721
+ const _column = guaranteeNonNullable(_findCol(_columns, column.name));
722
+
723
+ // check type
724
+ assertTrue(
725
+ column.type === _column.type,
726
+ `Can't process configuration: type mismatch for column '${column.name}' (expected: '${_column.type}', found: '${column.type}')`,
727
+ );
728
+
729
+ // check selection
730
+ assertTrue(
731
+ column.isSelected === _column.isSelected,
732
+ `Can't process configuration: selection mismatch for column '${column.name}' (expected: '${_column.isSelected}', found: '${column.isSelected}')`,
546
733
  );
734
+
735
+ // check kind (only relevant if aggregation is present)
736
+ if (data.pivot ?? data.groupBy) {
737
+ assertTrue(
738
+ column.kind === _column.kind,
739
+ `Can't process configuration: kind mismatch for column '${column.name}' (expected: '${_column.kind.toLowerCase()}', found: '${column.kind.toLowerCase()}')`,
740
+ );
741
+ }
742
+
743
+ // check aggregation (only relevant if aggregation is present)
744
+ if (data.pivot ?? data.groupBy) {
745
+ assertTrue(
746
+ column.aggregateOperator === _column.aggregateOperator,
747
+ `Can't process configuration: aggregation operator mismatch for column '${column.name}' (expected: '${_column.aggregateOperator}', found: '${column.aggregateOperator}')`,
748
+ );
749
+ assertTrue(
750
+ engine
751
+ .getAggregateOperation(column.aggregateOperator)
752
+ .isCompatibleWithParameterValues(column.aggregationParameters),
753
+ `Can't process configuration: incompatible aggregation parameter values for column '${column.name}' (operator: '${column.aggregateOperator}')`,
754
+ );
755
+ }
756
+
757
+ // check pivot sort direction and exclusion (only relevant if pivot is present)
758
+ if (data.pivot) {
759
+ assertTrue(
760
+ column.excludedFromPivot === _column.excludedFromPivot,
761
+ `Can't process configuration: pivot exclusion mismatch for column '${column.name}' (expected: '${_column.excludedFromPivot}', found: '${column.excludedFromPivot}')`,
762
+ );
763
+ assertTrue(
764
+ column.pivotSortDirection === _column.pivotSortDirection,
765
+ `Can't process configuration: pivot sort direction mismatch for column '${column.name}' (expected: '${_column.pivotSortDirection?.toLowerCase() ?? 'none'}', found: '${column.pivotSortDirection?.toLowerCase() ?? 'none'}')`,
766
+ );
767
+ }
547
768
  });
548
- return configuration;
769
+
770
+ return config;
549
771
  }