@hypequery/datasets 0.24.0 → 0.26.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 (106) hide show
  1. package/dist/cache/definition-identity.d.ts +9 -6
  2. package/dist/cache/definition-identity.d.ts.map +1 -1
  3. package/dist/cache/definition-identity.js +12 -6
  4. package/dist/cache/protocol-cache-keys.d.ts.map +1 -1
  5. package/dist/cache/protocol-cache-keys.js +29 -6
  6. package/dist/cache/query-signature.d.ts.map +1 -1
  7. package/dist/cache/query-signature.js +11 -3
  8. package/dist/catalog.d.ts +4 -0
  9. package/dist/catalog.d.ts.map +1 -1
  10. package/dist/catalog.js +2 -0
  11. package/dist/contract.d.ts +3 -0
  12. package/dist/contract.d.ts.map +1 -1
  13. package/dist/contract.js +2 -0
  14. package/dist/dataset-compilation.d.ts +2 -0
  15. package/dist/dataset-compilation.d.ts.map +1 -1
  16. package/dist/dataset-sql-dialect.d.ts +3 -1
  17. package/dist/dataset-sql-dialect.d.ts.map +1 -1
  18. package/dist/dataset.d.ts +3 -1
  19. package/dist/dataset.d.ts.map +1 -1
  20. package/dist/dataset.js +23 -32
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/metric-query-engine.d.ts +0 -1
  24. package/dist/metric-query-engine.d.ts.map +1 -1
  25. package/dist/metric-query-engine.js +8 -1
  26. package/dist/protocol-adapter.d.ts.map +1 -1
  27. package/dist/protocol-adapter.js +4 -6
  28. package/dist/protocol-rehydrate.d.ts.map +1 -1
  29. package/dist/protocol-rehydrate.js +2 -0
  30. package/dist/query-builder-protocol.d.ts +3 -1
  31. package/dist/query-builder-protocol.d.ts.map +1 -1
  32. package/dist/relationship-check.d.ts.map +1 -1
  33. package/dist/relationship-check.js +3 -5
  34. package/dist/semantic-planner.d.ts.map +1 -1
  35. package/dist/semantic-planner.js +35 -15
  36. package/dist/semantic-query-schema.d.ts +6 -0
  37. package/dist/semantic-query-schema.d.ts.map +1 -1
  38. package/dist/semantic-query-schema.js +6 -0
  39. package/dist/tools.d.ts.map +1 -1
  40. package/dist/tools.js +4 -3
  41. package/dist/types.d.ts +84 -7
  42. package/dist/types.d.ts.map +1 -1
  43. package/dist/utils/aggregate-state-functions.d.ts +2 -1
  44. package/dist/utils/aggregate-state-functions.d.ts.map +1 -1
  45. package/dist/utils/aggregate-state-functions.js +5 -19
  46. package/dist/utils/build-dataset-query-builder.d.ts +1 -1
  47. package/dist/utils/build-dataset-query-builder.d.ts.map +1 -1
  48. package/dist/utils/build-dataset-query-builder.js +12 -15
  49. package/dist/utils/clickhouse-dataset-sql-dialect.d.ts.map +1 -1
  50. package/dist/utils/clickhouse-dataset-sql-dialect.js +3 -0
  51. package/dist/utils/compile-dataset-query.d.ts +1 -1
  52. package/dist/utils/compile-dataset-query.d.ts.map +1 -1
  53. package/dist/utils/compile-dataset-query.js +16 -5
  54. package/dist/utils/dataset-definition-validation.d.ts +1 -1
  55. package/dist/utils/dataset-definition-validation.d.ts.map +1 -1
  56. package/dist/utils/dataset-definition-validation.js +19 -0
  57. package/dist/utils/dataset-query-validation.d.ts +1 -1
  58. package/dist/utils/dataset-query-validation.d.ts.map +1 -1
  59. package/dist/utils/dataset-query-validation.js +12 -2
  60. package/dist/utils/dataset-source.d.ts +35 -2
  61. package/dist/utils/dataset-source.d.ts.map +1 -1
  62. package/dist/utils/dataset-source.js +47 -4
  63. package/dist/utils/dataset-time-keys.d.ts +32 -0
  64. package/dist/utils/dataset-time-keys.d.ts.map +1 -0
  65. package/dist/utils/dataset-time-keys.js +55 -0
  66. package/dist/utils/enforced-constraints.d.ts +14 -0
  67. package/dist/utils/enforced-constraints.d.ts.map +1 -0
  68. package/dist/utils/enforced-constraints.js +57 -0
  69. package/dist/utils/metric-derived-query.d.ts.map +1 -1
  70. package/dist/utils/metric-derived-query.js +6 -12
  71. package/dist/utils/metric-query-builder.d.ts +1 -1
  72. package/dist/utils/metric-query-builder.d.ts.map +1 -1
  73. package/dist/utils/metric-query-builder.js +7 -13
  74. package/dist/utils/metric-query-validation.d.ts.map +1 -1
  75. package/dist/utils/metric-query-validation.js +7 -1
  76. package/dist/utils/portable-aggregations.d.ts +6 -3
  77. package/dist/utils/portable-aggregations.d.ts.map +1 -1
  78. package/dist/utils/portable-aggregations.js +16 -7
  79. package/dist/utils/query-timezone.d.ts +1 -1
  80. package/dist/utils/query-timezone.d.ts.map +1 -1
  81. package/dist/utils/query-timezone.js +3 -3
  82. package/dist/utils/relationship-builder-plan.d.ts +12 -10
  83. package/dist/utils/relationship-builder-plan.d.ts.map +1 -1
  84. package/dist/utils/relationship-builder-plan.js +20 -19
  85. package/dist/utils/relationship-measure-sql.d.ts.map +1 -1
  86. package/dist/utils/relationship-measure-sql.js +6 -3
  87. package/dist/utils/relationship-validation.d.ts.map +1 -1
  88. package/dist/utils/relationship-validation.js +2 -0
  89. package/dist/utils/row-scope.d.ts +23 -0
  90. package/dist/utils/row-scope.d.ts.map +1 -0
  91. package/dist/utils/row-scope.js +26 -0
  92. package/dist/utils/scoped-dataset-source.d.ts +23 -0
  93. package/dist/utils/scoped-dataset-source.d.ts.map +1 -0
  94. package/dist/utils/scoped-dataset-source.js +34 -0
  95. package/dist/utils/snapshot-execution-context.d.ts.map +1 -1
  96. package/dist/utils/snapshot-execution-context.js +3 -0
  97. package/dist/utils/time-measure-axis-sql.d.ts +1 -1
  98. package/dist/utils/time-measure-axis-sql.d.ts.map +1 -1
  99. package/dist/utils/time-measure-axis-sql.js +2 -1
  100. package/dist/utils/time-measure-leaf-sql.d.ts +1 -1
  101. package/dist/utils/time-measure-leaf-sql.d.ts.map +1 -1
  102. package/dist/utils/time-measure-leaf-sql.js +3 -1
  103. package/dist/utils/time-measure-source-sql.d.ts +3 -0
  104. package/dist/utils/time-measure-source-sql.d.ts.map +1 -1
  105. package/dist/utils/time-measure-source-sql.js +10 -9
  106. package/package.json +3 -3
@@ -5,7 +5,7 @@ import { parseProtocolIdentifier, parseProtocolQualifiedIdentifier, validateProt
5
5
  import { SEMANTIC_FILTER_OPERATORS } from './constants.js';
6
6
  import { toProtocolSemanticMetadata } from './utils/protocol-semantic-metadata.js';
7
7
  import { assertPublishableTimeGrains, isPortableTimeGrain, requirePortableTimeGrain } from './utils/portable-grains.js';
8
- import { requirePortableAggregation } from './utils/portable-aggregations.js';
8
+ import { requirePublishableMeasureAggregation } from './utils/portable-aggregations.js';
9
9
  import { assertNoPublishedSegments } from './utils/segments.js';
10
10
  function fieldSchema(type) {
11
11
  switch (type) {
@@ -81,10 +81,6 @@ export function buildProtocolDatasetContract(dataset, options = {}) {
81
81
  }
82
82
  assertNoPublishedSegments(dataset);
83
83
  assertPublishableTimeGrains(dataset);
84
- if (dataset.final) {
85
- throw new Error(`Dataset "${dataset.name}" is declared final: true, which the deployment contract cannot carry yet. ` +
86
- 'Publishing it would serve the source without FINAL and count unmerged row versions.');
87
- }
88
84
  const metrics = Object.entries(options.metrics ?? {})
89
85
  .filter(([, metric]) => (metric.__type === 'grained_metric_ref' ? metric.metric : metric).datasetName === dataset.name)
90
86
  .map(([name, metric]) => {
@@ -100,6 +96,7 @@ export function buildProtocolDatasetContract(dataset, options = {}) {
100
96
  ...(dataset.description !== undefined ? { description: dataset.description } : {}),
101
97
  ...toProtocolSemanticMetadata(dataset),
102
98
  source: dataset.source,
99
+ ...(dataset.rowResolution === undefined ? {} : { rowResolution: { ...dataset.rowResolution } }),
103
100
  ...(dataset.freshness !== undefined ? { freshness: { ...dataset.freshness } } : {}),
104
101
  ...(dataset.owner !== undefined ? { owner: dataset.owner } : {}),
105
102
  ...(dataset.defaults !== undefined
@@ -134,8 +131,9 @@ export function buildProtocolDatasetContract(dataset, options = {}) {
134
131
  })).sort(byName),
135
132
  measures: Object.entries(baseMeasures).map(([name, measure]) => ({
136
133
  name,
137
- aggregation: requirePortableAggregation(measure.aggregation, `Measure "${dataset.name}.${name}"`),
134
+ aggregation: requirePublishableMeasureAggregation(measure.aggregation, `Measure "${dataset.name}.${name}"`),
138
135
  field: measure.field,
136
+ ...(measure.stateFunction !== undefined ? { stateFunction: measure.stateFunction } : {}),
139
137
  ...(measure.argField !== undefined ? { argField: measure.argField } : {}),
140
138
  ...(measure.level !== undefined ? { level: measure.level } : {}),
141
139
  ...(measure.sql !== undefined
@@ -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;AAOpB,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;AA8QD;;;;;;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"}
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;AAOpB,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;AA+QD;;;;;;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,CAyF7C;AAED,gFAAgF;AAChF,wBAAgB,mCAAmC,CACjD,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,gCAAqC,GAC7C,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAG7C"}
@@ -70,6 +70,7 @@ function rehydrateMeasure(datasetName, measure) {
70
70
  ...snapshotSemanticMetadata(measure),
71
71
  aggregation: measure.aggregation,
72
72
  field: String(measure.field),
73
+ ...(measure.stateFunction !== undefined ? { stateFunction: measure.stateFunction } : {}),
73
74
  ...(measure.argField !== undefined ? { argField: String(measure.argField) } : {}),
74
75
  ...(measure.level !== undefined ? { level: measure.level } : {}),
75
76
  ...(measure.sql !== undefined
@@ -255,6 +256,7 @@ export function rehydrateProtocolDatasets(contracts, options = {}) {
255
256
  const name = String(contract.name);
256
257
  const instance = dataset(name, {
257
258
  source: contract.source,
259
+ ...(contract.rowResolution === undefined ? {} : { rowResolution: contract.rowResolution }),
258
260
  ...snapshotSemanticMetadata(contract),
259
261
  ...(contract.description !== undefined ? { description: contract.description } : {}),
260
262
  ...(contract.owner !== undefined ? { owner: contract.owner } : {}),
@@ -47,11 +47,13 @@ export interface QueryBuilderLike {
47
47
  where(column: string, operator: string, value: unknown): QueryBuilderLike;
48
48
  /**
49
49
  * Optional: read the table source with ClickHouse `FINAL`. Needed only for
50
- * datasets declared `final: true`; querying one through a builder without
50
+ * datasets that declare `rowResolution`; querying one through a builder without
51
51
  * it is refused rather than run without `FINAL`, which would count every
52
52
  * unmerged row version.
53
53
  */
54
54
  final?(): QueryBuilderLike;
55
+ /** Query-level ClickHouse settings, sent with the query. */
56
+ settings?(opts: Record<string, string | number | boolean>): QueryBuilderLike;
55
57
  leftJoin(table: string, leftColumn: string, rightColumn: string, alias?: string, on?: QueryBuilderJoinCondition | QueryBuilderJoinCondition[]): QueryBuilderLike;
56
58
  /**
57
59
  * Single-match LEFT JOIN (ClickHouse `LEFT ANY JOIN`). Required to query
@@ -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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"}
@@ -1 +1 @@
1
- {"version":3,"file":"relationship-check.d.ts","sourceRoot":"","sources":["../src/relationship-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAyB,KAAK,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAGnG,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;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,kBAAkB,EACtB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,wBAAwB,CAAC,CAqCnC"}
1
+ {"version":3,"file":"relationship-check.d.ts","sourceRoot":"","sources":["../src/relationship-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAyB,KAAK,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAInG,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;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,kBAAkB,EACtB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,wBAAwB,CAAC,CAkCnC"}
@@ -18,7 +18,8 @@
18
18
  */
19
19
  import { datasetSourceBuilder } from './utils/dataset-source.js';
20
20
  import { toQueryBuilderFactory } from './query-builder-protocol.js';
21
- import { getRuntimeTenantPredicate, validateTenantRuntime } from './utils/tenant-runtime.js';
21
+ import { validateTenantRuntime } from './utils/tenant-runtime.js';
22
+ import { applyRowScope, datasetRowScope } from './utils/row-scope.js';
22
23
  import { resolveDatasetSqlDialect } from './utils/dataset-sql-dialect.js';
23
24
  import { listToOneRelationships, readCount, relationshipKeyIssue, } from './utils/relationship-key-check.js';
24
25
  const ROWS_ALIAS = '__hq_rows';
@@ -32,7 +33,6 @@ const KEYS_ALIAS = '__hq_keys';
32
33
  export async function checkRelationships(ds, options) {
33
34
  const factory = toQueryBuilderFactory(options.queryBuilder);
34
35
  const dialect = resolveDatasetSqlDialect(factory);
35
- const tenantPredicate = getRuntimeTenantPredicate(options.context);
36
36
  const entries = listToOneRelationships(ds, options.relationships);
37
37
  const issues = [];
38
38
  for (const entry of entries) {
@@ -47,9 +47,7 @@ export async function checkRelationships(ds, options) {
47
47
  for (const column of entry.columns)
48
48
  qb = qb.where(column, 'isNotNull', undefined);
49
49
  }
50
- if (entry.target.tenantKey && tenantPredicate) {
51
- qb = qb.where(entry.target.tenantKey, tenantPredicate.operator, tenantPredicate.value);
52
- }
50
+ qb = applyRowScope(qb, datasetRowScope(entry.target, options.context));
53
51
  const [row] = await qb.execute({
54
52
  abortSignal: options.context?.abortSignal,
55
53
  });
@@ -1 +1 @@
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;AA+M5B,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,kBAAkB,EACtB,KAAK,GAAE,YAAiB,EACxB,OAAO,CAAC,EAAE,gBAAgB,GACzB,QAAQ,CAoBV;AA2FD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,GAAG,gBAAgB,EACpC,KAAK,GAAE,WAAgB,EACvB,OAAO,CAAC,EAAE,gBAAgB,GACzB,QAAQ,CAcV"}
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,EAKT,MAAM,oBAAoB,CAAC;AAgO5B,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,kBAAkB,EACtB,KAAK,GAAE,YAAiB,EACxB,OAAO,CAAC,EAAE,gBAAgB,GACzB,QAAQ,CAsBV;AA2FD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,GAAG,gBAAgB,EACpC,KAAK,GAAE,WAAgB,EACvB,OAAO,CAAC,EAAE,gBAAgB,GACzB,QAAQ,CAgBV"}
@@ -4,9 +4,10 @@ import { protocolMetricCapabilityErrors } from './utils/protocol-metric-capabili
4
4
  import { getMetricGrain, getMetricRef, } from './utils/metric-handle.js';
5
5
  import { validateDatasetQuery } from './dataset-query.js';
6
6
  import { isSupportedTimeGrain } from './constants.js';
7
- import { getRuntimeTenantPredicate } from './utils/tenant-runtime.js';
7
+ import { datasetRowScope, runtimeConstraints } from './utils/row-scope.js';
8
8
  import { isQualifiedField, resolveQualifiedField } from './utils/relationship-fields.js';
9
9
  import { segmentFilters } from './utils/segments.js';
10
+ import { selectsAlternateTimeKey } from './utils/dataset-time-keys.js';
10
11
  function resolveField(ds, field) {
11
12
  const dimension = ds.dimensions[field];
12
13
  if (dimension?.sql) {
@@ -67,10 +68,33 @@ function normalizeFilters(ds, filters = []) {
67
68
  * `FINAL`. Running a final dataset there would count unmerged row versions.
68
69
  */
69
70
  function rejectFinalOnBackend(ds) {
70
- if (ds.final) {
71
- throw new Error(`Dataset "${ds.name}" is declared final: true, which requires the queryBuilder execution path.`);
71
+ if (ds.rowResolution) {
72
+ throw new Error(`Dataset "${ds.name}" reads its source with FINAL, which requires the queryBuilder execution path.`);
72
73
  }
73
74
  }
75
+ /**
76
+ * The frozen plan protocol has no field for enforced constraints. Dropping
77
+ * them would run the call unrestricted, so it is refused instead.
78
+ */
79
+ function rejectConstraintsOnBackend(context) {
80
+ if (runtimeConstraints(context).length > 0) {
81
+ throw new Error('Enforced constraints require the queryBuilder execution path.');
82
+ }
83
+ }
84
+ /**
85
+ * The dataset's row scope as the plan's single tenant predicate. The plan
86
+ * protocol carries at most one, so a wider scope is refused, never truncated.
87
+ */
88
+ function planRowScope(ds, context) {
89
+ const scope = datasetRowScope(ds, context);
90
+ if (scope.length > 1) {
91
+ throw new Error(`Dataset "${ds.name}" has more than one row predicate, which requires the queryBuilder execution path.`);
92
+ }
93
+ if (scope.length === 0)
94
+ return undefined;
95
+ const { column, ...predicate } = scope[0];
96
+ return { field: column, ...predicate };
97
+ }
74
98
  function collectJoins(ds, dimensions = [], filters = [], orderBy = [], context) {
75
99
  const referenced = [
76
100
  ...dimensions,
@@ -80,7 +104,6 @@ function collectJoins(ds, dimensions = [], filters = [], orderBy = [], context)
80
104
  if (referenced.length === 0) {
81
105
  return undefined;
82
106
  }
83
- const tenantPredicate = getRuntimeTenantPredicate(context);
84
107
  const joins = new Map();
85
108
  for (const name of referenced) {
86
109
  const { relationshipName, relationship, target } = resolveQualifiedPlanField(ds, name);
@@ -96,9 +119,7 @@ function collectJoins(ds, dimensions = [], filters = [], orderBy = [], context)
96
119
  from: relationship.from,
97
120
  to: relationship.to,
98
121
  type: 'left',
99
- tenant: tenantPredicate && target.tenantKey
100
- ? { field: target.tenantKey, ...tenantPredicate }
101
- : undefined,
122
+ tenant: planRowScope(target, context),
102
123
  });
103
124
  }
104
125
  return Array.from(joins.values());
@@ -125,13 +146,6 @@ function aggregationForMeasure(ds, name) {
125
146
  filters: normalizeFilters(ds, measure.filters),
126
147
  };
127
148
  }
128
- function tenantForContext(ds, context) {
129
- const tenantPredicate = getRuntimeTenantPredicate(context);
130
- if (!tenantPredicate || !ds.tenantKey) {
131
- return undefined;
132
- }
133
- return { field: ds.tenantKey, ...tenantPredicate };
134
- }
135
149
  function grainForQuery(ds, unit) {
136
150
  if (!unit) {
137
151
  return undefined;
@@ -162,16 +176,19 @@ function aggregatePlan(ds, query, aggregations, context) {
162
176
  orderBy: query.orderBy,
163
177
  limit: query.limit,
164
178
  offset: query.offset,
165
- tenant: tenantForContext(ds, context),
179
+ tenant: planRowScope(ds, context),
166
180
  joins: collectJoins(ds, query.dimensions, query.filters, query.orderBy, context),
167
181
  };
168
182
  }
169
183
  export function buildDatasetPlan(ds, query = {}, context) {
170
184
  rejectFinalOnBackend(ds);
185
+ rejectConstraintsOnBackend(context);
171
186
  if ((query.measures ?? []).some(name => name.includes('.')))
172
187
  throw new Error('Relationship measures require the queryBuilder execution path.');
173
188
  if (query.timezone !== undefined)
174
189
  throw new Error('Execution timezone requires the queryBuilder execution path.');
190
+ if (selectsAlternateTimeKey(ds, query.timeKey))
191
+ throw new Error('Alternate time keys require the queryBuilder execution path.');
175
192
  rejectTimeMeasuresOnBackend(ds, query);
176
193
  if ((query.measures ?? []).some(name => getDerivedMeasure(ds.measures, name) !== undefined)) {
177
194
  throw new Error('Derived dataset measures require the queryBuilder execution path.');
@@ -251,7 +268,10 @@ export function buildMetricPlan(metric, query = {}, context) {
251
268
  if (errors.length)
252
269
  throw new Error(`Invalid metric query: ${errors.join('; ')}`);
253
270
  const ref = getMetricRef(metric);
271
+ if (selectsAlternateTimeKey(ref.dataset, query.timeKey))
272
+ throw new Error('Alternate time keys require the queryBuilder execution path.');
254
273
  rejectFinalOnBackend(ref.dataset);
274
+ rejectConstraintsOnBackend(context);
255
275
  const grain = getMetricGrain(metric, query);
256
276
  const plannedQuery = { ...query, by: grain };
257
277
  if (ref.spec.__type === 'derived_metric_spec') {
@@ -21,6 +21,12 @@ export interface SemanticQuerySchemaOptions extends SemanticQuerySchemaLimits {
21
21
  * protocol does not carry post-aggregation conditions yet.
22
22
  */
23
23
  having?: boolean;
24
+ /**
25
+ * Accept a `timeKey` selection on datasets that declare alternate time axes.
26
+ * Off by default, like `having`: enable it only on surfaces that pass the
27
+ * field through to the dataset client.
28
+ */
29
+ timeKey?: boolean;
24
30
  /** Include Serve's opt-in result metadata flag. */
25
31
  includeMeta?: boolean;
26
32
  /** Require at least one dimension or measure for dataset queries. */
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-query-schema.d.ts","sourceRoot":"","sources":["../src/semantic-query-schema.ts"],"names":[],"mappings":"AAGA,OAAO,EAAK,KAAK,UAAU,EAAE,MAAM,KAAK,CAAC;AACzC,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACxB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,MAAM,WAAW,yBAAyB;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,0BAA2B,SAAQ,yBAAyB;IAC3E,iFAAiF;IACjF,UAAU,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC;IAC5B;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;;;;;OAUG;IACH,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED,gGAAgG;AAChG,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAC5C,kBAAkB,EAClB,YAAY,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAC9C,CAAC;AAEF,eAAO,MAAM,oCAAoC;;;;;;;EAO/C,CAAC;AAEH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC;IACjC,QAAQ,CAAC,sBAAsB,EAAE,UAAU,CAAC;IAC5C,QAAQ,CAAC,qBAAqB,EAAE,UAAU,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,oFAAoF;AACpF,MAAM,MAAM,yBAAyB,GAAG,oBAAoB,GAAG,cAAc,CAAC;AA+M9E,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,yBAAyB,EAClC,OAAO,GAAE,0BAA+B,GACvC,UAAU,CAMZ;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,yBAAyB,EAClC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,0BAA+B,EACxC,cAAc,CAAC,EAAE,2BAA2B,GAC3C,UAAU,CAcZ;AA0BD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3C,UAAU,CAKZ;AAyBD,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,EACnD,OAAO,GAAE,0BAA+B,GACvC,6BAA6B,CAgD/B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,yBAAyB,EAClC,OAAO,GAAE,0BAA+B,EACxC,IAAI,SAAkB,GACrB,cAAc,CAEhB;AAED,kEAAkE;AAClE,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,yBAAyB,EAClC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,0BAA+B,EACxC,cAAc,CAAC,EAAE,2BAA2B,EAC5C,IAAI,SAAiB,GACpB,cAAc,CAKhB"}
1
+ {"version":3,"file":"semantic-query-schema.d.ts","sourceRoot":"","sources":["../src/semantic-query-schema.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ import { SEMANTIC_FILTER_OPERATORS, SEMANTIC_HAVING_OPERATORS } from './constant
7
7
  import { zodToProtocolSchema } from './protocol-schema-adapter.js';
8
8
  import { compareStrings, stableStringify, uniqueSorted } from './utils/canonical-json.js';
9
9
  import { zodToDraft7JsonSchema } from './utils/zod-json-schema.js';
10
+ import { datasetTimeKeys } from './utils/dataset-time-keys.js';
10
11
  export const DEFAULT_SEMANTIC_QUERY_SCHEMA_LIMITS = Object.freeze({
11
12
  maxResultSize: 10_000,
12
13
  maxOffset: 10_000,
@@ -182,6 +183,11 @@ function queryShape(catalog, metricName, options, relationshipOperators, metric,
182
183
  ? z.number().int().nonnegative()
183
184
  : z.number().int().nonnegative().max(limits.maxOffset)).optional(),
184
185
  [grainField]: fieldEnum(grains).optional(),
186
+ // Only datasets with more than one axis accept the field, so every other
187
+ // schema and manifest hash is unchanged.
188
+ ...(options.timeKey && grains.length > 0 && datasetTimeKeys(catalog).length > 1 ? {
189
+ timeKey: fieldEnum(datasetTimeKeys(catalog)).optional().describe(`Time axis for the grain and time-based measures. Defaults to ${catalog.timeKey}.`),
190
+ } : {}),
185
191
  timezone: z.string().max(100).refine(isQueryTimezone, 'Use an IANA timezone such as UTC or America/New_York.').optional(),
186
192
  ...(options.includeMeta ? { includeMeta: z.boolean().optional() } : {}),
187
193
  };
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/dist/tools.js CHANGED
@@ -2,7 +2,8 @@ import { getDatasetCatalog, } from './catalog.js';
2
2
  import { buildCanonicalSemanticQuerySchemas, buildDatasetInputSchema, buildMetricInputSchema, toSemanticJsonSchema, } from './semantic-query-schema.js';
3
3
  import { parseCanonicalToolInput, redactSemanticToolSql, semanticToolNamePart, } from './utils/semantic-tool.js';
4
4
  function buildCatalogTool(datasets, analytics, includeSql) {
5
- const schemas = buildCanonicalSemanticQuerySchemas(datasets);
5
+ // Parsed input reaches the client whole, so it can carry a selected time axis.
6
+ const schemas = buildCanonicalSemanticQuerySchemas(datasets, { timeKey: true });
6
7
  return {
7
8
  name: 'query_dataset',
8
9
  description: 'Query governed analytics datasets by selecting dimensions, measures, filters, and time grains.',
@@ -17,7 +18,7 @@ function buildCatalogTool(datasets, analytics, includeSql) {
17
18
  }
18
19
  function buildDatasetTools(datasets, analytics, includeSql) {
19
20
  return Object.entries(datasets).map(([datasetName, dataset]) => {
20
- const schema = buildDatasetInputSchema(dataset);
21
+ const schema = buildDatasetInputSchema(dataset, { timeKey: true });
21
22
  return {
22
23
  name: `query_${semanticToolNamePart(datasetName)}`,
23
24
  description: `Query the ${datasetName} analytics dataset.`,
@@ -34,7 +35,7 @@ function buildMetricTools(datasets, analytics, includeSql) {
34
35
  const tools = [];
35
36
  for (const [datasetName, dataset] of Object.entries(datasets)) {
36
37
  for (const [metricName, metric] of Object.entries(dataset.metrics ?? {})) {
37
- const schema = buildMetricInputSchema(dataset, metricName, {}, metric.contract());
38
+ const schema = buildMetricInputSchema(dataset, metricName, { timeKey: true }, metric.contract());
38
39
  tools.push({
39
40
  name: `query_${semanticToolNamePart(metricName)}`,
40
41
  description: `Query the ${metricName} metric from the ${datasetName} dataset.`,
package/dist/types.d.ts CHANGED
@@ -1,3 +1,20 @@
1
+ /**
2
+ * How a dataset's rows are resolved, as the deployment contract carries it
3
+ * (RFC 0021). `{ kind: 'final' }` reads the source with `FINAL`, and is what the
4
+ * deprecated `final: true` means; naming the engine also filters the resolved rows by its deletion or sign
5
+ * column, so only current rows remain.
6
+ */
7
+ export type RowResolution = {
8
+ readonly kind: 'final';
9
+ } | {
10
+ readonly kind: 'final';
11
+ readonly engine: 'replacing';
12
+ readonly deletedColumn?: string;
13
+ } | {
14
+ readonly kind: 'final';
15
+ readonly engine: 'collapsing' | 'versioned-collapsing';
16
+ readonly signColumn: string;
17
+ };
1
18
  import type { QueryableRelationshipMeasureNames, RelationshipMeasureDefinition } from './utils/relationship-measure-types.js';
2
19
  import type { DatasetFilterFor } from './utils/dataset-filter-types.js';
3
20
  import type { QueryBuilderFactoryInput } from './query-builder-protocol.js';
@@ -314,6 +331,11 @@ export interface MetricQuery {
314
331
  limit?: number;
315
332
  offset?: number;
316
333
  by?: TimeGrain;
334
+ /**
335
+ * Time axis for `by` and for window and shift measures: the dataset's
336
+ * `timeKey` or one of its `timeKeys`. Defaults to `timeKey`.
337
+ */
338
+ timeKey?: string;
317
339
  /** IANA timezone for buckets and local time-key bounds; overrides the client default. */
318
340
  timezone?: string;
319
341
  }
@@ -332,6 +354,11 @@ export interface DatasetQuery {
332
354
  limit?: number;
333
355
  offset?: number;
334
356
  by?: TimeGrain;
357
+ /**
358
+ * Time axis for `by` and for window and shift measures: the dataset's
359
+ * `timeKey` or one of its `timeKeys`. Defaults to `timeKey`.
360
+ */
361
+ timeKey?: string;
335
362
  /** IANA timezone for buckets and local time-key bounds; overrides the client default. */
336
363
  timezone?: string;
337
364
  }
@@ -387,6 +414,14 @@ export type SemanticTenantRuntime = string | {
387
414
  export interface SemanticExecutionRuntime {
388
415
  builderFactory?: QueryBuilderFactoryInput;
389
416
  tenant?: SemanticTenantRuntime;
417
+ /**
418
+ * RFC 0019 enforced constraints: comparisons on the queried dataset's
419
+ * declared filters or one-hop relationship fields, ANDed with the caller's
420
+ * filters. Resolve them from trusted context (the authenticated principal),
421
+ * never from caller input. A constraint the dataset cannot enforce refuses
422
+ * the call.
423
+ */
424
+ constraints?: MetricFilter[];
390
425
  }
391
426
  export interface ExecutionContext {
392
427
  runtime?: SemanticExecutionRuntime;
@@ -446,7 +481,7 @@ export interface DerivedMetricConfig<TDatasetName extends string = string> exten
446
481
  label?: string;
447
482
  description?: string;
448
483
  }
449
- export interface DatasetConfig<TDimensions extends Record<string, DimensionDefinition> = Record<string, DimensionDefinition>, TMeasures extends Record<string, DatasetMeasureDefinition> = Record<string, MeasureDefinition>, TRelationships extends Record<string, RelationshipDefinition> = Record<string, never>, TSegments extends Record<string, SegmentDefinition> = Record<string, SegmentDefinition>, TFilters extends SemanticFiltersDefinition | undefined = SemanticFiltersDefinition> extends SemanticMetadata {
484
+ export interface DatasetConfig<TDimensions extends Record<string, DimensionDefinition> = Record<string, DimensionDefinition>, TMeasures extends Record<string, DatasetMeasureDefinition> = Record<string, MeasureDefinition>, TRelationships extends Record<string, RelationshipDefinition> = Record<string, never>, TSegments extends Record<string, SegmentDefinition> = Record<string, SegmentDefinition>, TFilters extends SemanticFiltersDefinition | undefined = SemanticFiltersDefinition, TTimeKey extends string | undefined = string | undefined, TTimeKeys extends readonly string[] = readonly string[]> extends SemanticMetadata {
450
485
  source: string;
451
486
  /**
452
487
  * Read the source with ClickHouse `FINAL`, so queries see one row per
@@ -455,14 +490,33 @@ export interface DatasetConfig<TDimensions extends Record<string, DimensionDefin
455
490
  * a CollapsingMergeTree. Without it, row versions that have not been merged
456
491
  * yet are each counted. Applies to every query on this dataset, to its
457
492
  * relationship-key checks, and to joins that target it.
493
+ *
494
+ * @deprecated Use `rowResolution: { kind: 'final' }`, which means the same and
495
+ * can also name the engine. `final: true` still works and is read as that.
458
496
  */
459
497
  final?: boolean;
498
+ /**
499
+ * Read the source with ClickHouse `FINAL` (RFC 0021), as code and as the
500
+ * deployment contract carries it. `{ kind: 'final' }` reads `FINAL` only;
501
+ * naming the engine also keeps only rows whose deletion column is 0, or whose
502
+ * sign column is 1, after `FINAL`.
503
+ */
504
+ rowResolution?: RowResolution;
460
505
  description?: string;
461
506
  freshness?: DatasetFreshness;
462
507
  owner?: string;
463
508
  defaults?: DatasetDefaults;
464
509
  tenantKey?: string;
465
- timeKey?: string;
510
+ /** The default time axis: what `by` buckets on when a query selects no `timeKey`. */
511
+ timeKey?: TTimeKey;
512
+ /**
513
+ * Further time axes a query may select with `query.timeKey`, such as
514
+ * `shipped_at` beside a `created_at` default. Each is a dimension name or a
515
+ * column, like `timeKey`, and requires `timeKey` to be set. The selected
516
+ * axis drives grains, window and shift measures, and their time-range
517
+ * checks; `timeGrains` applies to every axis.
518
+ */
519
+ timeKeys?: TTimeKeys;
466
520
  /**
467
521
  * Restricts the time grains this dataset supports. Defaults to every grain
468
522
  * the planner can bucket on. Use it, for example, to refuse `minute` and
@@ -482,12 +536,18 @@ export interface DatasetConfig<TDimensions extends Record<string, DimensionDefin
482
536
  */
483
537
  segments?: TSegments;
484
538
  }
485
- export interface DatasetInstance<TDimensions extends Record<string, DimensionDefinition> = Record<string, DimensionDefinition>, TMeasures extends Record<string, DatasetMeasureDefinition> = Record<string, DatasetMeasureDefinition>, TRelationships extends Record<string, RelationshipDefinition> = Record<string, never>, TDatasetName extends string = string, TDerivedMeasures extends Record<string, DerivedMeasureDefinition> = Record<string, DerivedMeasureDefinition>, TSegments extends Record<string, SegmentDefinition> = Record<string, SegmentDefinition>, TFilters extends SemanticFiltersDefinition = SemanticFiltersDefinition> {
539
+ export interface DatasetInstance<TDimensions extends Record<string, DimensionDefinition> = Record<string, DimensionDefinition>, TMeasures extends Record<string, DatasetMeasureDefinition> = Record<string, DatasetMeasureDefinition>, TRelationships extends Record<string, RelationshipDefinition> = Record<string, never>, TDatasetName extends string = string, TDerivedMeasures extends Record<string, DerivedMeasureDefinition> = Record<string, DerivedMeasureDefinition>, TSegments extends Record<string, SegmentDefinition> = Record<string, SegmentDefinition>, TFilters extends SemanticFiltersDefinition = SemanticFiltersDefinition, TTimeKey extends string | undefined = string | undefined, TTimeKeys extends string = string> {
486
540
  __type: 'dataset';
487
541
  name: TDatasetName;
488
542
  source: string;
489
- /** Source is read with `FINAL`; see `DatasetConfig.final`. */
543
+ /**
544
+ * True whenever `rowResolution` is set.
545
+ *
546
+ * @deprecated Read `rowResolution` instead.
547
+ */
490
548
  final?: boolean;
549
+ /** How the source's rows are resolved; see `DatasetConfig.rowResolution`. */
550
+ rowResolution?: RowResolution;
491
551
  description?: string;
492
552
  examples?: readonly string[];
493
553
  synonyms?: readonly string[];
@@ -499,7 +559,9 @@ export interface DatasetInstance<TDimensions extends Record<string, DimensionDef
499
559
  sensitivity?: SemanticSensitivity;
500
560
  defaults?: DatasetDefaults;
501
561
  tenantKey?: string;
502
- timeKey?: string;
562
+ timeKey?: TTimeKey;
563
+ /** Alternate time axes, excluding `timeKey`; see `DatasetConfig.timeKeys`. */
564
+ timeKeys?: readonly TTimeKeys[];
503
565
  timeGrains?: readonly TimeGrain[];
504
566
  dimensions: TDimensions;
505
567
  /** All declared measures: base aggregates, formulas, and time windows. */
@@ -511,8 +573,8 @@ export interface DatasetInstance<TDimensions extends Record<string, DimensionDef
511
573
  limits?: DatasetLimits;
512
574
  cache?: DatasetCachePolicy;
513
575
  segments: TSegments;
514
- metric<TName extends string>(metricName: TName, metricConfig: BaseMetricConfig<BaseMeasures<TMeasures>>): BaseMetricRef<TDatasetName, TName, DatasetInstance<TDimensions, TMeasures, TRelationships, TDatasetName, TDerivedMeasures, TSegments, TFilters>>;
515
- metric<TName extends string>(metricName: TName, metricConfig: DerivedMetricConfig<TDatasetName>): DerivedMetricRef<TDatasetName, TName, DatasetInstance<TDimensions, TMeasures, TRelationships, TDatasetName, TDerivedMeasures, TSegments, TFilters>>;
576
+ metric<TName extends string>(metricName: TName, metricConfig: BaseMetricConfig<BaseMeasures<TMeasures>>): BaseMetricRef<TDatasetName, TName, DatasetInstance<TDimensions, TMeasures, TRelationships, TDatasetName, TDerivedMeasures, TSegments, TFilters, TTimeKey, TTimeKeys>>;
577
+ metric<TName extends string>(metricName: TName, metricConfig: DerivedMetricConfig<TDatasetName>): DerivedMetricRef<TDatasetName, TName, DatasetInstance<TDimensions, TMeasures, TRelationships, TDatasetName, TDerivedMeasures, TSegments, TFilters, TTimeKey, TTimeKeys>>;
516
578
  }
517
579
  export interface DatasetRegistryInstance {
518
580
  register(ds: DatasetInstance): void;
@@ -555,6 +617,11 @@ export type DatasetQueryableMeasures<TDataset extends DatasetInstance<any, any,
555
617
  };
556
618
  /** Segment names declared by a dataset. */
557
619
  export type DatasetSegmentNames<TDataset extends DatasetInstance<any, any, any, any>> = keyof TDataset['segments'] & string;
620
+ /**
621
+ * Time axes a query may select with `timeKey`: the dataset's `timeKey` and its
622
+ * `timeKeys`. `never` when the dataset declares no time axis.
623
+ */
624
+ export type DatasetTimeKeyNames<TDataset extends DatasetInstance<any, any, any, any>> = Exclude<TDataset['timeKey'], undefined> | (NonNullable<TDataset['timeKeys']> extends readonly (infer TKey)[] ? TKey & string : never);
558
625
  /**
559
626
  * Fields a result can be ordered by. This is the selection-independent superset
560
627
  * (every dimension + measure, plus the synthetic `period` column for grained
@@ -577,6 +644,11 @@ export interface DatasetQueryFor<TDataset extends DatasetInstance<any, any, any,
577
644
  limit?: number;
578
645
  offset?: number;
579
646
  by?: TimeGrain;
647
+ /**
648
+ * Time axis for `by` and for window and shift measures: the dataset's
649
+ * `timeKey` or one of its `timeKeys`. Defaults to `timeKey`.
650
+ */
651
+ timeKey?: DatasetTimeKeyNames<TDataset>;
580
652
  /** IANA timezone for buckets and local time-key bounds; overrides the client default. */
581
653
  timezone?: string;
582
654
  includeMeta?: boolean;
@@ -622,6 +694,11 @@ export interface MetricQueryFor<TDataset extends DatasetInstance<any, any, any,
622
694
  limit?: number;
623
695
  offset?: number;
624
696
  by?: TimeGrain;
697
+ /**
698
+ * Time axis for `by` and for window and shift measures: the dataset's
699
+ * `timeKey` or one of its `timeKeys`. Defaults to `timeKey`.
700
+ */
701
+ timeKey?: DatasetTimeKeyNames<TDataset>;
625
702
  /** IANA timezone for buckets and local time-key bounds; overrides the client default. */
626
703
  timezone?: string;
627
704
  includeMeta?: boolean;