@hypequery/datasets 0.18.0 → 0.20.0

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 (202) hide show
  1. package/dist/agent-catalog.d.ts +11 -1
  2. package/dist/agent-catalog.d.ts.map +1 -1
  3. package/dist/aggregations.d.ts +2 -0
  4. package/dist/aggregations.d.ts.map +1 -1
  5. package/dist/aggregations.js +4 -0
  6. package/dist/api.type-test.js +57 -0
  7. package/dist/cache/definition-identity.d.ts +26 -0
  8. package/dist/cache/definition-identity.d.ts.map +1 -0
  9. package/dist/cache/definition-identity.js +164 -0
  10. package/dist/cache/protocol-cache-keys.d.ts +38 -0
  11. package/dist/cache/protocol-cache-keys.d.ts.map +1 -0
  12. package/dist/cache/protocol-cache-keys.js +191 -0
  13. package/dist/cache/query-signature.d.ts +6 -0
  14. package/dist/cache/query-signature.d.ts.map +1 -1
  15. package/dist/cache/query-signature.js +27 -13
  16. package/dist/cache/semantic-query-cache.d.ts +23 -0
  17. package/dist/cache/semantic-query-cache.d.ts.map +1 -1
  18. package/dist/catalog.d.ts +14 -2
  19. package/dist/catalog.d.ts.map +1 -1
  20. package/dist/catalog.js +37 -10
  21. package/dist/constants.d.ts.map +1 -1
  22. package/dist/constants.js +2 -0
  23. package/dist/contract.d.ts +7 -2
  24. package/dist/contract.d.ts.map +1 -1
  25. package/dist/contract.js +9 -0
  26. package/dist/dataset-query.d.ts.map +1 -1
  27. package/dist/dataset-query.js +27 -5
  28. package/dist/dataset.d.ts +2 -2
  29. package/dist/dataset.d.ts.map +1 -1
  30. package/dist/dataset.js +12 -4
  31. package/dist/executor.d.ts +7 -1
  32. package/dist/executor.d.ts.map +1 -1
  33. package/dist/executor.js +75 -22
  34. package/dist/in-memory-backend.d.ts.map +1 -1
  35. package/dist/in-memory-backend.js +34 -7
  36. package/dist/index.d.ts +8 -6
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +3 -2
  39. package/dist/measure.d.ts +17 -2
  40. package/dist/measure.d.ts.map +1 -1
  41. package/dist/measure.js +16 -1
  42. package/dist/portable-execution-errors.d.ts +4 -0
  43. package/dist/portable-execution-errors.d.ts.map +1 -1
  44. package/dist/portable-execution-errors.js +4 -1
  45. package/dist/portable-executor.d.ts.map +1 -1
  46. package/dist/portable-executor.js +6 -3
  47. package/dist/protocol-adapter.d.ts.map +1 -1
  48. package/dist/protocol-adapter.js +25 -8
  49. package/dist/protocol-deployment-adapter.d.ts.map +1 -1
  50. package/dist/protocol-deployment-adapter.js +2 -1
  51. package/dist/protocol-rehydrate.d.ts +5 -1
  52. package/dist/protocol-rehydrate.d.ts.map +1 -1
  53. package/dist/protocol-rehydrate.js +20 -10
  54. package/dist/query-builder-protocol.d.ts +7 -3
  55. package/dist/query-builder-protocol.d.ts.map +1 -1
  56. package/dist/query-planner.d.ts +1 -1
  57. package/dist/query-planner.d.ts.map +1 -1
  58. package/dist/query-planner.js +10 -17
  59. package/dist/relationship-check.d.ts +47 -0
  60. package/dist/relationship-check.d.ts.map +1 -0
  61. package/dist/relationship-check.js +59 -0
  62. package/dist/relationships.d.ts +10 -10
  63. package/dist/relationships.js +10 -10
  64. package/dist/semantic-plan.d.ts +0 -1
  65. package/dist/semantic-plan.d.ts.map +1 -1
  66. package/dist/semantic-planner.d.ts.map +1 -1
  67. package/dist/semantic-planner.js +15 -4
  68. package/dist/semantic-query-schema.d.ts.map +1 -1
  69. package/dist/semantic-query-schema.js +7 -0
  70. package/dist/types.d.ts +99 -18
  71. package/dist/types.d.ts.map +1 -1
  72. package/dist/utils/agent-catalog-projection.d.ts +9 -2
  73. package/dist/utils/agent-catalog-projection.d.ts.map +1 -1
  74. package/dist/utils/agent-catalog-projection.js +6 -10
  75. package/dist/utils/approximate-measures.d.ts +10 -0
  76. package/dist/utils/approximate-measures.d.ts.map +1 -0
  77. package/dist/utils/approximate-measures.js +12 -0
  78. package/dist/utils/dataset-contract.d.ts.map +1 -1
  79. package/dist/utils/dataset-contract.js +4 -3
  80. package/dist/utils/dataset-definition-validation.d.ts.map +1 -1
  81. package/dist/utils/dataset-definition-validation.js +6 -24
  82. package/dist/utils/dataset-derived-query.d.ts.map +1 -1
  83. package/dist/utils/dataset-derived-query.js +7 -50
  84. package/dist/utils/dataset-measures.d.ts +13 -6
  85. package/dist/utils/dataset-measures.d.ts.map +1 -1
  86. package/dist/utils/dataset-measures.js +25 -4
  87. package/dist/utils/dataset-metric-ref.d.ts +2 -2
  88. package/dist/utils/dataset-metric-ref.d.ts.map +1 -1
  89. package/dist/utils/dataset-metric-ref.js +5 -0
  90. package/dist/utils/dataset-query-result.d.ts.map +1 -1
  91. package/dist/utils/dataset-query-result.js +2 -1
  92. package/dist/utils/dataset-query-validation.d.ts.map +1 -1
  93. package/dist/utils/dataset-query-validation.js +13 -6
  94. package/dist/utils/dataset-time-grains.d.ts +15 -0
  95. package/dist/utils/dataset-time-grains.d.ts.map +1 -0
  96. package/dist/utils/dataset-time-grains.js +17 -0
  97. package/dist/utils/derived-measure-sql.d.ts +3 -0
  98. package/dist/utils/derived-measure-sql.d.ts.map +1 -0
  99. package/dist/utils/derived-measure-sql.js +46 -0
  100. package/dist/utils/derived-measure-validation.d.ts.map +1 -1
  101. package/dist/utils/derived-measure-validation.js +6 -5
  102. package/dist/utils/filtered-aggregation-sql.d.ts.map +1 -1
  103. package/dist/utils/filtered-aggregation-sql.js +1 -0
  104. package/dist/utils/measure-time-grains.d.ts +4 -0
  105. package/dist/utils/measure-time-grains.d.ts.map +1 -0
  106. package/dist/utils/measure-time-grains.js +16 -0
  107. package/dist/utils/portable-aggregations.d.ts +14 -0
  108. package/dist/utils/portable-aggregations.d.ts.map +1 -0
  109. package/dist/utils/portable-aggregations.js +15 -0
  110. package/dist/utils/portable-grains.d.ts +22 -0
  111. package/dist/utils/portable-grains.d.ts.map +1 -0
  112. package/dist/utils/portable-grains.js +35 -0
  113. package/dist/utils/portable-semantic-query.d.ts.map +1 -1
  114. package/dist/utils/portable-semantic-query.js +2 -1
  115. package/dist/utils/protocol-metric-expressions.d.ts.map +1 -1
  116. package/dist/utils/protocol-metric-expressions.js +2 -1
  117. package/dist/utils/query-timezone.d.ts +9 -0
  118. package/dist/utils/query-timezone.d.ts.map +1 -0
  119. package/dist/utils/query-timezone.js +35 -0
  120. package/dist/utils/relationship-builder-plan.d.ts +6 -3
  121. package/dist/utils/relationship-builder-plan.d.ts.map +1 -1
  122. package/dist/utils/relationship-builder-plan.js +13 -5
  123. package/dist/utils/relationship-key-check.d.ts +43 -0
  124. package/dist/utils/relationship-key-check.d.ts.map +1 -0
  125. package/dist/utils/relationship-key-check.js +72 -0
  126. package/dist/utils/segments.d.ts +31 -0
  127. package/dist/utils/segments.d.ts.map +1 -0
  128. package/dist/utils/segments.js +91 -0
  129. package/dist/utils/semantic-metadata-validation.d.ts.map +1 -1
  130. package/dist/utils/semantic-metadata-validation.js +23 -2
  131. package/dist/utils/semantic-metadata.d.ts.map +1 -1
  132. package/dist/utils/semantic-metadata.js +3 -1
  133. package/dist/utils/shift-measure-definition.d.ts +4 -0
  134. package/dist/utils/shift-measure-definition.d.ts.map +1 -0
  135. package/dist/utils/shift-measure-definition.js +9 -0
  136. package/dist/utils/shift-measure-sql.d.ts +18 -0
  137. package/dist/utils/shift-measure-sql.d.ts.map +1 -0
  138. package/dist/utils/shift-measure-sql.js +46 -0
  139. package/dist/utils/shift-measure-validation.d.ts +3 -0
  140. package/dist/utils/shift-measure-validation.d.ts.map +1 -0
  141. package/dist/utils/shift-measure-validation.js +20 -0
  142. package/dist/utils/sql-under-joins.d.ts +10 -0
  143. package/dist/utils/sql-under-joins.d.ts.map +1 -0
  144. package/dist/utils/sql-under-joins.js +15 -0
  145. package/dist/utils/time-arithmetic-sql.d.ts +4 -0
  146. package/dist/utils/time-arithmetic-sql.d.ts.map +1 -0
  147. package/dist/utils/time-arithmetic-sql.js +9 -0
  148. package/dist/utils/time-axis-bounds.d.ts +24 -0
  149. package/dist/utils/time-axis-bounds.d.ts.map +1 -0
  150. package/dist/utils/time-axis-bounds.js +71 -0
  151. package/dist/utils/time-axis-calendar-guard.d.ts +9 -0
  152. package/dist/utils/time-axis-calendar-guard.d.ts.map +1 -0
  153. package/dist/utils/time-axis-calendar-guard.js +17 -0
  154. package/dist/utils/time-axis-intervals.d.ts +13 -0
  155. package/dist/utils/time-axis-intervals.d.ts.map +1 -0
  156. package/dist/utils/time-axis-intervals.js +81 -0
  157. package/dist/utils/time-measure-axis-sql.d.ts +12 -0
  158. package/dist/utils/time-measure-axis-sql.d.ts.map +1 -0
  159. package/dist/utils/time-measure-axis-sql.js +47 -0
  160. package/dist/utils/time-measure-axis.d.ts +19 -0
  161. package/dist/utils/time-measure-axis.d.ts.map +1 -0
  162. package/dist/utils/time-measure-axis.js +45 -0
  163. package/dist/utils/time-measure-dataset-sql.d.ts +9 -0
  164. package/dist/utils/time-measure-dataset-sql.d.ts.map +1 -0
  165. package/dist/utils/time-measure-dataset-sql.js +63 -0
  166. package/dist/utils/time-measure-result-sql.d.ts +6 -0
  167. package/dist/utils/time-measure-result-sql.d.ts.map +1 -0
  168. package/dist/utils/time-measure-result-sql.js +30 -0
  169. package/dist/utils/time-measure-source-sql.d.ts +22 -0
  170. package/dist/utils/time-measure-source-sql.d.ts.map +1 -0
  171. package/dist/utils/time-measure-source-sql.js +75 -0
  172. package/dist/utils/time-measure-values-sql.d.ts +20 -0
  173. package/dist/utils/time-measure-values-sql.d.ts.map +1 -0
  174. package/dist/utils/time-measure-values-sql.js +87 -0
  175. package/dist/utils/time-query-measures.d.ts +6 -0
  176. package/dist/utils/time-query-measures.d.ts.map +1 -0
  177. package/dist/utils/time-query-measures.js +28 -0
  178. package/dist/utils/unsupported-contract-reasons.d.ts +32 -0
  179. package/dist/utils/unsupported-contract-reasons.d.ts.map +1 -0
  180. package/dist/utils/unsupported-contract-reasons.js +30 -0
  181. package/dist/utils/window-aggregation-sql.d.ts +5 -0
  182. package/dist/utils/window-aggregation-sql.d.ts.map +1 -0
  183. package/dist/utils/window-aggregation-sql.js +17 -0
  184. package/dist/utils/window-catalog-metadata.d.ts +14 -0
  185. package/dist/utils/window-catalog-metadata.d.ts.map +1 -0
  186. package/dist/utils/window-catalog-metadata.js +17 -0
  187. package/dist/utils/window-measure-definition.d.ts +4 -0
  188. package/dist/utils/window-measure-definition.d.ts.map +1 -0
  189. package/dist/utils/window-measure-definition.js +11 -0
  190. package/dist/utils/window-measure-dependencies.d.ts +4 -0
  191. package/dist/utils/window-measure-dependencies.d.ts.map +1 -0
  192. package/dist/utils/window-measure-dependencies.js +5 -0
  193. package/dist/utils/window-measure-validation.d.ts +3 -0
  194. package/dist/utils/window-measure-validation.d.ts.map +1 -0
  195. package/dist/utils/window-measure-validation.js +49 -0
  196. package/dist/utils/window-query-measures.d.ts +4 -0
  197. package/dist/utils/window-query-measures.d.ts.map +1 -0
  198. package/dist/utils/window-query-measures.js +17 -0
  199. package/dist/utils/window-query-signature.d.ts +4 -0
  200. package/dist/utils/window-query-signature.d.ts.map +1 -0
  201. package/dist/utils/window-query-signature.js +25 -0
  202. package/package.json +3 -3
@@ -1,7 +1,11 @@
1
+ import { splitDatasetMeasures } from './utils/dataset-measures.js';
1
2
  import { filterExpression, metricExpression, metricDerivation } from './utils/protocol-metric-expressions.js';
2
3
  import { parseProtocolIdentifier, parseProtocolQualifiedIdentifier, validateProtocolDatasetContract, } from '@hypequery/protocol';
3
4
  import { SEMANTIC_FILTER_OPERATORS } from './constants.js';
4
5
  import { toProtocolSemanticMetadata } from './utils/protocol-semantic-metadata.js';
6
+ import { assertPublishableTimeGrains, isPortableTimeGrain, requirePortableTimeGrain } from './utils/portable-grains.js';
7
+ import { requirePortableAggregation } from './utils/portable-aggregations.js';
8
+ import { assertNoPublishedSegments } from './utils/segments.js';
5
9
  function byName(left, right) {
6
10
  return left.name.localeCompare(right.name);
7
11
  }
@@ -18,13 +22,13 @@ function fieldSchema(type) {
18
22
  return { kind: 'any' };
19
23
  }
20
24
  }
21
- function unwrapMetric(metric) {
25
+ function unwrapMetric(metric, exposedName) {
22
26
  return metric.__type === 'grained_metric_ref'
23
- ? { ref: metric.metric, grain: metric.grain }
27
+ ? { ref: metric.metric, grain: requirePortableTimeGrain(metric.grain, `Metric "${exposedName}"`) }
24
28
  : { ref: metric };
25
29
  }
26
30
  function metricContract(exposedName, metric, endpoint) {
27
- const { ref, grain } = unwrapMetric(metric);
31
+ const { ref, grain } = unwrapMetric(metric, exposedName);
28
32
  const contract = metric.contract();
29
33
  const result = {
30
34
  name: parseProtocolIdentifier(exposedName),
@@ -39,7 +43,8 @@ function metricContract(exposedName, metric, endpoint) {
39
43
  : {}),
40
44
  dimensions: [...contract.dimensions].sort().map(parseProtocolQualifiedIdentifier),
41
45
  filters: [...contract.filters].sort().map(parseProtocolIdentifier),
42
- grains: [...contract.grains].sort(),
46
+ // Only grains the published contract can carry are advertised there.
47
+ grains: contract.grains.filter(isPortableTimeGrain).sort(),
43
48
  ...(grain !== undefined ? { grain } : {}),
44
49
  ...(ref.label !== undefined ? { label: ref.label } : {}),
45
50
  ...(ref.description !== undefined ? { description: ref.description } : {}),
@@ -68,8 +73,18 @@ function requiredSqlDependencies(kind, name, dependencies) {
68
73
  * Deployment assembly selects the fields supported by the deployment contract.
69
74
  */
70
75
  export function buildProtocolDatasetContract(dataset, options = {}) {
76
+ const { base: baseMeasures, windows, shifts } = splitDatasetMeasures(dataset.measures);
77
+ const shiftMeasureNames = Object.keys(shifts);
78
+ if (shiftMeasureNames.length)
79
+ throw new Error(`Dataset "${dataset.name}" shift measures (${shiftMeasureNames.join(', ')}) need deployment contract 3 (RFC 0015).`);
80
+ const windowMeasureNames = Object.keys(windows);
81
+ if (windowMeasureNames.length > 0) {
82
+ throw new Error(`Dataset "${dataset.name}" window measures (${windowMeasureNames.join(', ')}) need deployment contract 3 (RFC 0015).`);
83
+ }
84
+ assertNoPublishedSegments(dataset);
85
+ assertPublishableTimeGrains(dataset);
71
86
  const metrics = Object.entries(options.metrics ?? {})
72
- .filter(([, metric]) => unwrapMetric(metric).ref.datasetName === dataset.name)
87
+ .filter(([, metric]) => (metric.__type === 'grained_metric_ref' ? metric.metric : metric).datasetName === dataset.name)
73
88
  .map(([name, metric]) => {
74
89
  const endpoint = options.metricEndpoints?.[name];
75
90
  if (!endpoint) {
@@ -92,7 +107,9 @@ export function buildProtocolDatasetContract(dataset, options = {}) {
92
107
  ? { dimensions: [...dataset.defaults.dimensions].map(parseProtocolIdentifier) }
93
108
  : {}),
94
109
  ...(dataset.defaults.timeGrain !== undefined
95
- ? { timeGrain: dataset.defaults.timeGrain }
110
+ ? {
111
+ timeGrain: requirePortableTimeGrain(dataset.defaults.timeGrain, `Dataset "${dataset.name}" defaults.timeGrain`),
112
+ }
96
113
  : {}),
97
114
  },
98
115
  }
@@ -113,9 +130,9 @@ export function buildProtocolDatasetContract(dataset, options = {}) {
113
130
  ...(dimension.description !== undefined ? { description: dimension.description } : {}),
114
131
  ...toProtocolSemanticMetadata(dimension),
115
132
  })).sort(byName),
116
- measures: Object.entries(dataset.measures).map(([name, measure]) => ({
133
+ measures: Object.entries(baseMeasures).map(([name, measure]) => ({
117
134
  name,
118
- aggregation: measure.aggregation,
135
+ aggregation: requirePortableAggregation(measure.aggregation, `Measure "${dataset.name}.${name}"`),
119
136
  field: measure.field,
120
137
  ...(measure.argField !== undefined ? { argField: measure.argField } : {}),
121
138
  ...(measure.level !== undefined ? { level: measure.level } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"protocol-deployment-adapter.d.ts","sourceRoot":"","sources":["../src/protocol-deployment-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,0BAA0B,EAE/B,KAAK,sBAAsB,EAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAKrD,MAAM,WAAW,sCAAsC;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC;CACvE;AAED,oEAAoE;AACpE,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,SAAS,kBAAkB,EAAE,EACvC,OAAO,GAAE,sCAA2C,GACnD,0BAA0B,CAyB5B"}
1
+ {"version":3,"file":"protocol-deployment-adapter.d.ts","sourceRoot":"","sources":["../src/protocol-deployment-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,0BAA0B,EAE/B,KAAK,sBAAsB,EAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAKrD,MAAM,WAAW,sCAAsC;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC;CACvE;AAED,oEAAoE;AACpE,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,SAAS,kBAAkB,EAAE,EACvC,OAAO,GAAE,sCAA2C,GACnD,0BAA0B,CAyB5B"}
@@ -1,3 +1,4 @@
1
+ import { splitDatasetMeasures } from './utils/dataset-measures.js';
1
2
  import { parseProtocolIdentifier, validateProtocolDeploymentContract, } from '@hypequery/protocol';
2
3
  import { buildProtocolDatasetContract } from './protocol-adapter.js';
3
4
  import { derivedMeasureExpression } from './utils/protocol-metric-expressions.js';
@@ -9,7 +10,7 @@ export function buildProtocolDeploymentContract(datasets, options = {}) {
9
10
  endpoint: options.endpoints?.[dataset.name],
10
11
  });
11
12
  const { metrics: _metrics, ...base } = contract;
12
- const derived = Object.entries(dataset.derivedMeasures ?? {}).map(([name, definition]) => ({
13
+ const derived = Object.entries(splitDatasetMeasures(dataset.measures).derived).map(([name, definition]) => ({
13
14
  kind: 'derived',
14
15
  name: parseProtocolIdentifier(name),
15
16
  uses: Object.entries(definition.uses).map(([alias, measure]) => ({
@@ -13,6 +13,8 @@
13
13
  */
14
14
  import type { ProtocolDatasetContract, ProtocolDeploymentDataset } from '@hypequery/protocol';
15
15
  import type { AnyDatasetInstance, DatasetCachePolicy, MetricHandle } from './types.js';
16
+ import { type UnsupportedContractReason } from './utils/unsupported-contract-reasons.js';
17
+ export { UNSUPPORTED_CONTRACT_REASONS, type UnsupportedContractReason, } from './utils/unsupported-contract-reasons.js';
16
18
  /** A rebuilt dataset in the registry shape Serve, MCP, and the planner accept. */
17
19
  export type RehydratedDataset = AnyDatasetInstance & {
18
20
  readonly metrics: Readonly<Record<string, MetricHandle>>;
@@ -43,7 +45,9 @@ export interface RehydrateProtocolDatasetsOptions {
43
45
  export declare class UnsupportedContractFeatureError extends Error {
44
46
  readonly dataset: string;
45
47
  readonly feature: string;
46
- constructor(datasetName: string, feature: string, detail: string);
48
+ /** Which excluded surface this is; see `UNSUPPORTED_CONTRACT_REASONS`. */
49
+ readonly reason: UnsupportedContractReason | undefined;
50
+ constructor(datasetName: string, feature: string, detail: string, reason?: UnsupportedContractReason);
47
51
  }
48
52
  /**
49
53
  * Rebuild every dataset in a validated deployment contract.
@@ -1 +1 @@
1
- {"version":3,"file":"protocol-rehydrate.d.ts","sourceRoot":"","sources":["../src/protocol-rehydrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,uBAAuB,EAEvB,yBAAyB,EAM1B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EAMlB,YAAY,EAIb,MAAM,YAAY,CAAC;AAMpB,kFAAkF;AAClF,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,GAAG;IACnD,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;CAC1D,CAAC;AAEF,MAAM,WAAW,gCAAgC;IAC/C;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,kBAAkB,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACjD;AAED;;;;;GAKG;AACH,qBAAa,+BAAgC,SAAQ,KAAK;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAMjE;AAyPD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,SAAS,CAAC,uBAAuB,GAAG,yBAAyB,CAAC,EAAE,EAC3E,OAAO,GAAE,gCAAqC,GAC7C,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAmF7C;AAED,gFAAgF;AAChF,wBAAgB,mCAAmC,CACjD,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,gCAAqC,GAC7C,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAG7C"}
1
+ {"version":3,"file":"protocol-rehydrate.d.ts","sourceRoot":"","sources":["../src/protocol-rehydrate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,uBAAuB,EAEvB,yBAAyB,EAM1B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EAMlB,YAAY,EAIb,MAAM,YAAY,CAAC;AAMpB,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,yCAAyC,CAAC;AAEjD,OAAO,EACL,4BAA4B,EAC5B,KAAK,yBAAyB,GAC/B,MAAM,yCAAyC,CAAC;AAEjD,kFAAkF;AAClF,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,GAAG;IACnD,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;CAC1D,CAAC;AAEF,MAAM,WAAW,gCAAgC;IAC/C;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,kBAAkB,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CACjD;AAED;;;;;GAKG;AACH,qBAAa,+BAAgC,SAAQ,KAAK;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC;gBAGrD,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,yBAAyB;CAQrC;AAoQD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,SAAS,CAAC,uBAAuB,GAAG,yBAAyB,CAAC,EAAE,EAC3E,OAAO,GAAE,gCAAqC,GAC7C,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAwF7C;AAED,gFAAgF;AAChF,wBAAgB,mCAAmC,CACjD,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,gCAAqC,GAC7C,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAG7C"}
@@ -17,6 +17,9 @@ import { snapshotSemanticMetadata } from './utils/semantic-metadata.js';
17
17
  import { withContractCapabilities } from './utils/protocol-metric-capabilities.js';
18
18
  import { rehydrateDerivedFormula } from './utils/protocol-rehydrate-derivation.js';
19
19
  import { rehydrateMeasureFilter } from './utils/protocol-rehydrate-filters.js';
20
+ import { PORTABLE_TIME_GRAINS } from './utils/portable-grains.js';
21
+ import { UNSUPPORTED_CONTRACT_REASONS, } from './utils/unsupported-contract-reasons.js';
22
+ export { UNSUPPORTED_CONTRACT_REASONS, } from './utils/unsupported-contract-reasons.js';
20
23
  /**
21
24
  * Thrown when a contract describes something portable execution cannot rebuild.
22
25
  *
@@ -26,11 +29,14 @@ import { rehydrateMeasureFilter } from './utils/protocol-rehydrate-filters.js';
26
29
  export class UnsupportedContractFeatureError extends Error {
27
30
  dataset;
28
31
  feature;
29
- constructor(datasetName, feature, detail) {
32
+ /** Which excluded surface this is; see `UNSUPPORTED_CONTRACT_REASONS`. */
33
+ reason;
34
+ constructor(datasetName, feature, detail, reason) {
30
35
  super(`Cannot rebuild ${feature} on dataset "${datasetName}": ${detail}`);
31
36
  this.name = 'UnsupportedContractFeatureError';
32
37
  this.dataset = datasetName;
33
38
  this.feature = feature;
39
+ this.reason = reason;
34
40
  }
35
41
  }
36
42
  function rehydrateDimensions(contract) {
@@ -57,7 +63,7 @@ function rehydrateDimensions(contract) {
57
63
  return dimensions;
58
64
  }
59
65
  function rehydrateMeasure(datasetName, measure) {
60
- const filters = measure.filters.map((expression, index) => rehydrateMeasureFilter(expression, () => new UnsupportedContractFeatureError(datasetName, `measure "${String(measure.name)}"`, `fixed filter ${index} is not a field/operator/value comparison`)));
66
+ const filters = measure.filters.map((expression, index) => rehydrateMeasureFilter(expression, () => new UnsupportedContractFeatureError(datasetName, `measure "${String(measure.name)}"`, `fixed filter ${index} is not a field/operator/value comparison`, UNSUPPORTED_CONTRACT_REASONS.measureFilterNotComparison)));
61
67
  return {
62
68
  __type: 'measure_definition',
63
69
  ...snapshotSemanticMetadata(measure),
@@ -78,7 +84,7 @@ function rehydrateDerivedMeasure(datasetName, measure) {
78
84
  __type: 'derived_measure_definition',
79
85
  ...snapshotSemanticMetadata(measure),
80
86
  uses: Object.fromEntries(measure.uses.map(input => [String(input.alias), String(input.measure)])),
81
- formula: rehydrateDerivedFormula({ inputs: [], expression: measure.expression }, reason => new UnsupportedContractFeatureError(datasetName, `measure "${measure.name}"`, reason)),
87
+ formula: rehydrateDerivedFormula({ inputs: [], expression: measure.expression }, reason => new UnsupportedContractFeatureError(datasetName, `measure "${measure.name}"`, reason, UNSUPPORTED_CONTRACT_REASONS.unsupportedFormula)),
82
88
  ...(measure.label !== undefined ? { label: measure.label } : {}),
83
89
  ...(measure.description !== undefined ? { description: measure.description } : {}),
84
90
  };
@@ -139,12 +145,12 @@ function aggregationKey(value) {
139
145
  */
140
146
  function measureForAggregate(instance, contract, subject, expression) {
141
147
  if (expression.kind !== 'aggregate') {
142
- throw new UnsupportedContractFeatureError(instance.name, subject, `expected an aggregate expression, received "${expression.kind}"`);
148
+ throw new UnsupportedContractFeatureError(instance.name, subject, `expected an aggregate expression, received "${expression.kind}"`, UNSUPPORTED_CONTRACT_REASONS.expressionNotAggregate);
143
149
  }
144
150
  const field = String(expression.field);
145
151
  const candidates = contract.measures.filter(measure => (aggregationKey(measure) === aggregationKey(expression)));
146
152
  if (candidates.length === 0) {
147
- throw new UnsupportedContractFeatureError(instance.name, subject, `no declared measure matches ${expression.aggregation}(${field})`);
153
+ throw new UnsupportedContractFeatureError(instance.name, subject, `no declared measure matches ${expression.aggregation}(${field})`, UNSUPPORTED_CONTRACT_REASONS.noMatchingMeasure);
148
154
  }
149
155
  // A metric expression carries no raw SQL, so two measures that share an
150
156
  // aggregation identity but override SQL differently are indistinguishable in
@@ -153,7 +159,7 @@ function measureForAggregate(instance, contract, subject, expression) {
153
159
  if (distinctSql.size > 1) {
154
160
  throw new UnsupportedContractFeatureError(instance.name, subject, `${candidates.map(measure => `"${String(measure.name)}"`).join(' and ')} share `
155
161
  + `${expression.aggregation}(${field}) but emit different SQL, so the contract cannot `
156
- + 'say which one this metric was built from');
162
+ + 'say which one this metric was built from', UNSUPPORTED_CONTRACT_REASONS.ambiguousMeasureSql);
157
163
  }
158
164
  return String(candidates[0].name);
159
165
  }
@@ -164,7 +170,7 @@ function measureForAggregate(instance, contract, subject, expression) {
164
170
  * what both plan builders emit as the column of the intermediate aggregate.
165
171
  */
166
172
  function derivedMetricConfig(instance, contract, subject, derivation) {
167
- const unsupported = (reason) => new UnsupportedContractFeatureError(instance.name, subject, reason);
173
+ const unsupported = (reason) => new UnsupportedContractFeatureError(instance.name, subject, reason, UNSUPPORTED_CONTRACT_REASONS.unsupportedFormula);
168
174
  const uses = Object.fromEntries(derivation.inputs.map(input => {
169
175
  const alias = String(input.alias);
170
176
  return [
@@ -184,7 +190,7 @@ function rehydrateMetric(instance, contract, metric) {
184
190
  // The inlined expression states what a derived metric means but drops the
185
191
  // aliases its SQL is written in terms of. Without them a rebuild computes
186
192
  // the same number through different SQL, which decision 0005 excludes.
187
- throw new UnsupportedContractFeatureError(instance.name, subject, 'a derived metric requires its authored formula, which this contract does not carry');
193
+ throw new UnsupportedContractFeatureError(instance.name, subject, 'a derived metric requires its authored formula, which this contract does not carry', UNSUPPORTED_CONTRACT_REASONS.derivedMetricWithoutFormula);
188
194
  }
189
195
  const metadata = {
190
196
  ...snapshotSemanticMetadata(metric),
@@ -234,7 +240,7 @@ export function rehydrateProtocolDatasets(contracts, options = {}) {
234
240
  if (!instance) {
235
241
  // The deployment validator already rejects a dangling relationship, so
236
242
  // reaching this means the caller passed a partial contract.
237
- throw new UnsupportedContractFeatureError(target, 'relationship target', `dataset "${target}" is not part of the supplied contract`);
243
+ throw new UnsupportedContractFeatureError(target, 'relationship target', `dataset "${target}" is not part of the supplied contract`, UNSUPPORTED_CONTRACT_REASONS.relationshipTargetMissing);
238
244
  }
239
245
  return instance;
240
246
  };
@@ -251,7 +257,11 @@ export function rehydrateProtocolDatasets(contracts, options = {}) {
251
257
  ...(contract.defaults.dimensions !== undefined ? { dimensions: [...contract.defaults.dimensions] } : {}),
252
258
  } } : {}),
253
259
  ...(contract.tenant.kind === 'required' ? { tenantKey: contract.tenant.field } : {}),
254
- ...(contract.timeField !== undefined ? { timeKey: String(contract.timeField) } : {}),
260
+ // A published dataset supports only the grains its contract can carry,
261
+ // so its catalog never advertises a grain the portable path would refuse.
262
+ ...(contract.timeField !== undefined
263
+ ? { timeKey: String(contract.timeField), timeGrains: PORTABLE_TIME_GRAINS }
264
+ : {}),
255
265
  dimensions: rehydrateDimensions(contract),
256
266
  measures: Object.fromEntries([
257
267
  ...contract.measures.map(measure => [
@@ -27,12 +27,16 @@ export interface QueryBuilderLike {
27
27
  stddev?(column: string, alias?: string): QueryBuilderLike;
28
28
  /** Sample variance of `column`. */
29
29
  variance?(column: string, alias?: string): QueryBuilderLike;
30
+ /** Estimated number of distinct non-NULL values of `column`. */
31
+ approxCountDistinct?(column: string, alias?: string): QueryBuilderLike;
30
32
  where(column: string, operator: string, value: unknown): QueryBuilderLike;
31
33
  leftJoin(table: string, leftColumn: string, rightColumn: string, alias?: string, on?: QueryBuilderJoinCondition | QueryBuilderJoinCondition[]): QueryBuilderLike;
32
34
  /**
33
- * Optional single-match LEFT JOIN (ClickHouse `LEFT ANY JOIN`). When a
34
- * builder provides it, relationship joins use it so duplicate target join
35
- * keys cannot fan out aggregates; otherwise `leftJoin` is used.
35
+ * Single-match LEFT JOIN (ClickHouse `LEFT ANY JOIN`). Required to query
36
+ * relationship-qualified fields: duplicate target join keys cannot fan out
37
+ * aggregates. A builder without it can still run every query that does not
38
+ * traverse a relationship; one that does is rejected with a clear error
39
+ * instead of falling back to `leftJoin`.
36
40
  */
37
41
  leftAnyJoin?(table: string, leftColumn: string, rightColumn: string, alias?: string, on?: QueryBuilderJoinCondition | QueryBuilderJoinCondition[]): QueryBuilderLike;
38
42
  groupBy(columns: string | string[]): QueryBuilderLike;
@@ -1 +1 @@
1
- {"version":3,"file":"query-builder-protocol.d.ts","sourceRoot":"","sources":["../src/query-builder-protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query-builder-protocol.d.ts","sourceRoot":"","sources":["../src/query-builder-protocol.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import { type RelationshipBuilderContext } from './utils/relationship-builder-pl
4
4
  type DatasetShape = AnyDatasetInstance;
5
5
  export declare function resolveDimensionExpression(ds: DatasetShape, dimensionName: string, joinCtx?: RelationshipBuilderContext): string;
6
6
  export declare function resolveFilterField(ds: DatasetShape, filterField: string, joinCtx?: RelationshipBuilderContext): string;
7
- export declare function buildDimensionSelectionPlan(ds: DatasetShape, dimensions: string[], grain: TimeGrain | undefined, joinCtx?: RelationshipBuilderContext): {
7
+ export declare function buildDimensionSelectionPlan(ds: DatasetShape, dimensions: string[], grain: TimeGrain | undefined, joinCtx?: RelationshipBuilderContext, timezone?: string): {
8
8
  selectParts: string[];
9
9
  groupByParts: string[];
10
10
  };
@@ -1 +1 @@
1
- {"version":3,"file":"query-planner.d.ts","sourceRoot":"","sources":["../src/query-planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAMpE,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,sCAAsC,CAAC;AAI9C,KAAK,YAAY,GAAG,kBAAkB,CAAC;AA6BvC,wBAAgB,0BAA0B,CACxC,EAAE,EAAE,YAAY,EAChB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,0BAA0B,GACnC,MAAM,CAUR;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,YAAY,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,0BAA0B,GACnC,MAAM,CAMR;AAED,wBAAgB,2BAA2B,CACzC,EAAE,EAAE,YAAY,EAChB,UAAU,EAAE,MAAM,EAAE,EACpB,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,OAAO,CAAC,EAAE,0BAA0B,GACnC;IAAE,WAAW,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAkCnD;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,gBAAgB,EACpB,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,0BAA0B,GACnC,gBAAgB,CAgElB;AAED,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,gBAAgB,EACpB,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,iBAAiB,EAC7B,OAAO,CAAC,EAAE,0BAA0B,GACnC,gBAAgB,CAElB;AAED,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,gBAAgB,EACpB,OAAO,EAAE,aAAa,EAAE,GAAG,SAAS,EACpC,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,0BAA0B,GACnC,gBAAgB,CAoBlB;AAED,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,YAAY,EAChB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,GAAG,SAAS,CAMpB"}
1
+ {"version":3,"file":"query-planner.d.ts","sourceRoot":"","sources":["../src/query-planner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAMpE,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,sCAAsC,CAAC;AAI9C,KAAK,YAAY,GAAG,kBAAkB,CAAC;AAMvC,wBAAgB,0BAA0B,CACxC,EAAE,EAAE,YAAY,EAChB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,0BAA0B,GACnC,MAAM,CAUR;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,YAAY,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,0BAA0B,GACnC,MAAM,CAMR;AAED,wBAAgB,2BAA2B,CACzC,EAAE,EAAE,YAAY,EAChB,UAAU,EAAE,MAAM,EAAE,EACpB,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,OAAO,CAAC,EAAE,0BAA0B,EACpC,QAAQ,CAAC,EAAE,MAAM,GAChB;IAAE,WAAW,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAmCnD;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,gBAAgB,EACpB,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,0BAA0B,GACnC,gBAAgB,CAqElB;AAED,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,gBAAgB,EACpB,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,iBAAiB,EAC7B,OAAO,CAAC,EAAE,0BAA0B,GACnC,gBAAgB,CAElB;AAED,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,gBAAgB,EACpB,OAAO,EAAE,aAAa,EAAE,GAAG,SAAS,EACpC,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,0BAA0B,GACnC,gBAAgB,CAoBlB;AAED,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,YAAY,EAChB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,GAAG,SAAS,CAMpB"}
@@ -1,3 +1,5 @@
1
+ import { queryTimeSql } from './utils/query-timezone.js';
2
+ import { assertNoRawSqlUnderJoins } from './utils/sql-under-joins.js';
1
3
  import { GRAIN_FUNCTIONS } from "./constants.js";
2
4
  import { applyFilteredAggregationExpression } from './utils/filtered-aggregation-sql.js';
3
5
  import { getRuntimeTenantPredicate } from './utils/tenant-runtime.js';
@@ -9,21 +11,6 @@ import { validatePercentileLevel } from './measure.js';
9
11
  function toOrderDirection(direction) {
10
12
  return direction === 'asc' ? 'ASC' : 'DESC';
11
13
  }
12
- /**
13
- * Raw SQL expressions on the base dataset are emitted verbatim, so their column
14
- * references are not table-qualified. When relationship joins are active a bare
15
- * `price` in such an expression is ambiguous if the joined table also has a
16
- * `price` column. Until the builder rewrites identifiers inside expressions,
17
- * reject the combination rather than emit ambiguous SQL.
18
- */
19
- function assertNoRawSqlUnderJoins(kind, name, sql, joinCtx) {
20
- if (!joinCtx) {
21
- return;
22
- }
23
- throw new Error(`SQL-backed ${kind} "${name}" cannot be combined with relationship joins: its expression ` +
24
- `("${sql}") is not table-qualified and may collide with joined columns. Query it without ` +
25
- `relationship-qualified fields, or redeclare it as a plain column.`);
26
- }
27
14
  export function resolveDimensionExpression(ds, dimensionName, joinCtx) {
28
15
  if (joinCtx && isQualifiedField(dimensionName)) {
29
16
  return resolveQualifiedColumn(ds, dimensionName);
@@ -42,7 +29,7 @@ export function resolveFilterField(ds, filterField, joinCtx) {
42
29
  const resolvedField = ds.filters[filterField]?.field ?? filterField;
43
30
  return resolveDimensionExpression(ds, resolvedField, joinCtx);
44
31
  }
45
- export function buildDimensionSelectionPlan(ds, dimensions, grain, joinCtx) {
32
+ export function buildDimensionSelectionPlan(ds, dimensions, grain, joinCtx, timezone) {
46
33
  const selectParts = [];
47
34
  const groupByParts = new Set();
48
35
  if (grain) {
@@ -50,7 +37,8 @@ export function buildDimensionSelectionPlan(ds, dimensions, grain, joinCtx) {
50
37
  if (!fn) {
51
38
  throw new Error(`Unsupported time grain "${grain}".`);
52
39
  }
53
- selectParts.push(`${fn}(${qualifyBaseColumn(joinCtx, String(ds.timeKey))}) AS period`);
40
+ const time = resolveDimensionExpression(ds, String(ds.timeKey), joinCtx);
41
+ selectParts.push(`${fn}(${queryTimeSql(time, timezone)}) AS period`);
54
42
  groupByParts.add("period");
55
43
  }
56
44
  for (const dimensionName of dimensions) {
@@ -120,6 +108,11 @@ export function applyAggregationSpec(qb, ds, spec, alias, joinCtx) {
120
108
  }
121
109
  return qb.quantile(fieldOrExpr, spec.level, alias);
122
110
  }
111
+ case "approxCountDistinct":
112
+ if (!qb.approxCountDistinct) {
113
+ throw new Error('Query builder does not support approxCountDistinct aggregations.');
114
+ }
115
+ return qb.approxCountDistinct(fieldOrExpr, alias);
123
116
  case "stddev":
124
117
  if (!qb.stddev) {
125
118
  throw new Error('Query builder does not support stddev aggregations.');
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Verifies declared to-one relationships against the data.
3
+ *
4
+ * `belongsTo` and `hasOne` are declarations: nothing at query time proves the
5
+ * target join column is unique. Relationship joins are single-match, so a
6
+ * duplicate key cannot inflate an aggregate, but the join then takes an
7
+ * arbitrary one of the matching rows and grouped values drift without any
8
+ * error. `checkRelationships` counts rows and distinct keys on each target so a
9
+ * mis-declaration is caught in CI or at deploy time rather than in a report.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * const result = await checkRelationships(Orders, { queryBuilder: db });
14
+ * if (!result.ok) {
15
+ * throw new Error(result.issues.map((issue) => issue.message).join('\n'));
16
+ * }
17
+ * ```
18
+ */
19
+ import type { AnyDatasetInstance, ExecutionContext } from './types.js';
20
+ import { type QueryBuilderFactoryInput } from './query-builder-protocol.js';
21
+ import { type RelationshipKeyIssue } from './utils/relationship-key-check.js';
22
+ export type { RelationshipKeyIssue } from './utils/relationship-key-check.js';
23
+ export interface CheckRelationshipsOptions {
24
+ /** Query builder factory used to count target keys. */
25
+ queryBuilder: QueryBuilderFactoryInput;
26
+ /**
27
+ * Runtime context. A tenant-scoped target is checked within the runtime
28
+ * tenant, the same scope its join uses, so it requires tenant runtime.
29
+ */
30
+ context?: ExecutionContext;
31
+ /** Restrict the check to these to-one relationship names. */
32
+ relationships?: readonly string[];
33
+ }
34
+ export interface CheckRelationshipsResult {
35
+ /** True when every checked relationship has a unique target key. */
36
+ ok: boolean;
37
+ /** Relationship names that were checked. */
38
+ checked: string[];
39
+ issues: RelationshipKeyIssue[];
40
+ }
41
+ /**
42
+ * Checks that the target join column of each `belongsTo` and `hasOne`
43
+ * relationship on `ds` is unique. NULL keys are ignored because they never
44
+ * match a join. `hasMany` relationships are skipped.
45
+ */
46
+ export declare function checkRelationships(ds: AnyDatasetInstance, options: CheckRelationshipsOptions): Promise<CheckRelationshipsResult>;
47
+ //# sourceMappingURL=relationship-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationship-check.d.ts","sourceRoot":"","sources":["../src/relationship-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAyB,KAAK,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAEnG,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,mCAAmC,CAAC;AAE3C,YAAY,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAE9E,MAAM,WAAW,yBAAyB;IACxC,uDAAuD;IACvD,YAAY,EAAE,wBAAwB,CAAC;IACvC;;;OAGG;IACH,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,6DAA6D;IAC7D,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,wBAAwB;IACvC,oEAAoE;IACpE,EAAE,EAAE,OAAO,CAAC;IACZ,4CAA4C;IAC5C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,oBAAoB,EAAE,CAAC;CAChC;AAKD;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,kBAAkB,EACtB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,wBAAwB,CAAC,CAkCnC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Verifies declared to-one relationships against the data.
3
+ *
4
+ * `belongsTo` and `hasOne` are declarations: nothing at query time proves the
5
+ * target join column is unique. Relationship joins are single-match, so a
6
+ * duplicate key cannot inflate an aggregate, but the join then takes an
7
+ * arbitrary one of the matching rows and grouped values drift without any
8
+ * error. `checkRelationships` counts rows and distinct keys on each target so a
9
+ * mis-declaration is caught in CI or at deploy time rather than in a report.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * const result = await checkRelationships(Orders, { queryBuilder: db });
14
+ * if (!result.ok) {
15
+ * throw new Error(result.issues.map((issue) => issue.message).join('\n'));
16
+ * }
17
+ * ```
18
+ */
19
+ import { toQueryBuilderFactory } from './query-builder-protocol.js';
20
+ import { getRuntimeTenantPredicate, validateTenantRuntime } from './utils/tenant-runtime.js';
21
+ import { listToOneRelationships, readCount, relationshipKeyIssue, } from './utils/relationship-key-check.js';
22
+ const ROWS_ALIAS = '__hq_rows';
23
+ const KEYS_ALIAS = '__hq_keys';
24
+ /**
25
+ * Checks that the target join column of each `belongsTo` and `hasOne`
26
+ * relationship on `ds` is unique. NULL keys are ignored because they never
27
+ * match a join. `hasMany` relationships are skipped.
28
+ */
29
+ export async function checkRelationships(ds, options) {
30
+ const factory = toQueryBuilderFactory(options.queryBuilder);
31
+ const tenantPredicate = getRuntimeTenantPredicate(options.context);
32
+ const entries = listToOneRelationships(ds, options.relationships);
33
+ const issues = [];
34
+ for (const entry of entries) {
35
+ const tenantError = validateTenantRuntime(entry.target, options.context);
36
+ if (tenantError) {
37
+ throw new Error(`Cannot check relationship "${entry.relationship}": ${tenantError}`);
38
+ }
39
+ let qb = factory
40
+ .table(entry.target.source)
41
+ .count(entry.column, ROWS_ALIAS)
42
+ .countDistinct(entry.column, KEYS_ALIAS);
43
+ if (entry.target.tenantKey && tenantPredicate) {
44
+ qb = qb.where(entry.target.tenantKey, tenantPredicate.operator, tenantPredicate.value);
45
+ }
46
+ const [row] = await qb.execute({
47
+ abortSignal: options.context?.abortSignal,
48
+ });
49
+ const issue = relationshipKeyIssue(entry, readCount(row?.[ROWS_ALIAS]), readCount(row?.[KEYS_ALIAS]));
50
+ if (issue) {
51
+ issues.push(issue);
52
+ }
53
+ }
54
+ return {
55
+ ok: issues.length === 0,
56
+ checked: entries.map((entry) => entry.relationship),
57
+ issues,
58
+ };
59
+ }
@@ -10,15 +10,14 @@
10
10
  * is not addressable through a relationship, so there are no cross-dataset
11
11
  * metrics.
12
12
  *
13
- * Note that the `kind` passed here is a declaration, not something checked
14
- * against the data — there is no uniqueness concept in the model, so nothing
15
- * verifies that a `belongsTo` target column really is unique. What a
16
- * mis-declaration costs depends on the builder. One that implements the
17
- * optional `leftAnyJoin` (ClickHouse `LEFT ANY JOIN`) takes at most one target
18
- * row per base row, so the aggregate cannot inflate — it just silently picks an
19
- * arbitrary one of the matches. A builder without it falls back to `leftJoin`,
20
- * where duplicate target keys fan out and do inflate the aggregate. Either way
21
- * the declaration has to be right.
13
+ * Note that the `kind` passed here is a declaration, not something checked at
14
+ * query time. Joins are single-match (`leftAnyJoin`, ClickHouse
15
+ * `LEFT ANY JOIN`), so a mis-declared to-one relationship cannot inflate an
16
+ * aggregate, but it does make the join pick an arbitrary one of the matching
17
+ * target rows. Builders without `leftAnyJoin` are refused rather than
18
+ * downgraded to a fan-out `leftJoin`. The in-memory backend refuses duplicate
19
+ * target keys outright, and `checkRelationships()` reports them against a live
20
+ * database, so a wrong declaration can be caught before it skews results.
22
21
  *
23
22
  * @example
24
23
  * ```ts
@@ -29,7 +28,8 @@
29
28
  * customerId: dimension.string({ column: "customer_id" }),
30
29
  * },
31
30
  * relationships: {
32
- * customer: belongsTo(() => Customers, { from: "customerId", to: "id" }),
31
+ * // Join keys are source columns, not dimension names.
32
+ * customer: belongsTo(() => Customers, { from: "customer_id", to: "id" }),
33
33
  * },
34
34
  * });
35
35
  *
@@ -10,15 +10,14 @@
10
10
  * is not addressable through a relationship, so there are no cross-dataset
11
11
  * metrics.
12
12
  *
13
- * Note that the `kind` passed here is a declaration, not something checked
14
- * against the data — there is no uniqueness concept in the model, so nothing
15
- * verifies that a `belongsTo` target column really is unique. What a
16
- * mis-declaration costs depends on the builder. One that implements the
17
- * optional `leftAnyJoin` (ClickHouse `LEFT ANY JOIN`) takes at most one target
18
- * row per base row, so the aggregate cannot inflate — it just silently picks an
19
- * arbitrary one of the matches. A builder without it falls back to `leftJoin`,
20
- * where duplicate target keys fan out and do inflate the aggregate. Either way
21
- * the declaration has to be right.
13
+ * Note that the `kind` passed here is a declaration, not something checked at
14
+ * query time. Joins are single-match (`leftAnyJoin`, ClickHouse
15
+ * `LEFT ANY JOIN`), so a mis-declared to-one relationship cannot inflate an
16
+ * aggregate, but it does make the join pick an arbitrary one of the matching
17
+ * target rows. Builders without `leftAnyJoin` are refused rather than
18
+ * downgraded to a fan-out `leftJoin`. The in-memory backend refuses duplicate
19
+ * target keys outright, and `checkRelationships()` reports them against a live
20
+ * database, so a wrong declaration can be caught before it skews results.
22
21
  *
23
22
  * @example
24
23
  * ```ts
@@ -29,7 +28,8 @@
29
28
  * customerId: dimension.string({ column: "customer_id" }),
30
29
  * },
31
30
  * relationships: {
32
- * customer: belongsTo(() => Customers, { from: "customerId", to: "id" }),
31
+ * // Join keys are source columns, not dimension names.
32
+ * customer: belongsTo(() => Customers, { from: "customer_id", to: "id" }),
33
33
  * },
34
34
  * });
35
35
  *
@@ -72,7 +72,6 @@ export interface SemanticGrainPlan {
72
72
  field: string;
73
73
  unit: TimeGrain;
74
74
  output: 'period';
75
- timezone?: string;
76
75
  weekStart?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
77
76
  }
78
77
  /** @deprecated Part of the frozen plan/backend protocol; use `createDatasetClient({ queryBuilder })` instead. */
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-plan.d.ts","sourceRoot":"","sources":["../src/semantic-plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"semantic-plan.d.ts","sourceRoot":"","sources":["../src/semantic-plan.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-planner.d.ts","sourceRoot":"","sources":["../src/semantic-planner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAGhB,WAAW,EACX,SAAS,EACT,gBAAgB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,QAAQ,EAIT,MAAM,oBAAoB,CAAC;AAyL5B,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,kBAAkB,EACtB,KAAK,GAAE,YAAiB,EACxB,OAAO,CAAC,EAAE,gBAAgB,GACzB,QAAQ,CAgBV;AA2FD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,GAAG,gBAAgB,EACpC,KAAK,GAAE,WAAgB,EACvB,OAAO,CAAC,EAAE,gBAAgB,GACzB,QAAQ,CAYV"}
1
+ {"version":3,"file":"semantic-planner.d.ts","sourceRoot":"","sources":["../src/semantic-planner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAGhB,WAAW,EACX,SAAS,EACT,gBAAgB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,QAAQ,EAIT,MAAM,oBAAoB,CAAC;AA6L5B,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,kBAAkB,EACtB,KAAK,GAAE,YAAiB,EACxB,OAAO,CAAC,EAAE,gBAAgB,GACzB,QAAQ,CAkBV;AA2FD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,GAAG,gBAAgB,EACpC,KAAK,GAAE,WAAgB,EACvB,OAAO,CAAC,EAAE,gBAAgB,GACzB,QAAQ,CAaV"}