@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.
- package/dist/cache/definition-identity.d.ts +9 -6
- package/dist/cache/definition-identity.d.ts.map +1 -1
- package/dist/cache/definition-identity.js +12 -6
- package/dist/cache/protocol-cache-keys.d.ts.map +1 -1
- package/dist/cache/protocol-cache-keys.js +29 -6
- package/dist/cache/query-signature.d.ts.map +1 -1
- package/dist/cache/query-signature.js +11 -3
- package/dist/catalog.d.ts +4 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +2 -0
- package/dist/contract.d.ts +3 -0
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +2 -0
- package/dist/dataset-compilation.d.ts +2 -0
- package/dist/dataset-compilation.d.ts.map +1 -1
- package/dist/dataset-sql-dialect.d.ts +3 -1
- package/dist/dataset-sql-dialect.d.ts.map +1 -1
- package/dist/dataset.d.ts +3 -1
- package/dist/dataset.d.ts.map +1 -1
- package/dist/dataset.js +23 -32
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/metric-query-engine.d.ts +0 -1
- package/dist/metric-query-engine.d.ts.map +1 -1
- package/dist/metric-query-engine.js +8 -1
- package/dist/protocol-adapter.d.ts.map +1 -1
- package/dist/protocol-adapter.js +4 -6
- package/dist/protocol-rehydrate.d.ts.map +1 -1
- package/dist/protocol-rehydrate.js +2 -0
- package/dist/query-builder-protocol.d.ts +3 -1
- package/dist/query-builder-protocol.d.ts.map +1 -1
- package/dist/relationship-check.d.ts.map +1 -1
- package/dist/relationship-check.js +3 -5
- package/dist/semantic-planner.d.ts.map +1 -1
- package/dist/semantic-planner.js +35 -15
- package/dist/semantic-query-schema.d.ts +6 -0
- package/dist/semantic-query-schema.d.ts.map +1 -1
- package/dist/semantic-query-schema.js +6 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +4 -3
- package/dist/types.d.ts +84 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/aggregate-state-functions.d.ts +2 -1
- package/dist/utils/aggregate-state-functions.d.ts.map +1 -1
- package/dist/utils/aggregate-state-functions.js +5 -19
- package/dist/utils/build-dataset-query-builder.d.ts +1 -1
- package/dist/utils/build-dataset-query-builder.d.ts.map +1 -1
- package/dist/utils/build-dataset-query-builder.js +12 -15
- package/dist/utils/clickhouse-dataset-sql-dialect.d.ts.map +1 -1
- package/dist/utils/clickhouse-dataset-sql-dialect.js +3 -0
- package/dist/utils/compile-dataset-query.d.ts +1 -1
- package/dist/utils/compile-dataset-query.d.ts.map +1 -1
- package/dist/utils/compile-dataset-query.js +16 -5
- package/dist/utils/dataset-definition-validation.d.ts +1 -1
- package/dist/utils/dataset-definition-validation.d.ts.map +1 -1
- package/dist/utils/dataset-definition-validation.js +19 -0
- package/dist/utils/dataset-query-validation.d.ts +1 -1
- package/dist/utils/dataset-query-validation.d.ts.map +1 -1
- package/dist/utils/dataset-query-validation.js +12 -2
- package/dist/utils/dataset-source.d.ts +35 -2
- package/dist/utils/dataset-source.d.ts.map +1 -1
- package/dist/utils/dataset-source.js +47 -4
- package/dist/utils/dataset-time-keys.d.ts +32 -0
- package/dist/utils/dataset-time-keys.d.ts.map +1 -0
- package/dist/utils/dataset-time-keys.js +55 -0
- package/dist/utils/enforced-constraints.d.ts +14 -0
- package/dist/utils/enforced-constraints.d.ts.map +1 -0
- package/dist/utils/enforced-constraints.js +57 -0
- package/dist/utils/metric-derived-query.d.ts.map +1 -1
- package/dist/utils/metric-derived-query.js +6 -12
- package/dist/utils/metric-query-builder.d.ts +1 -1
- package/dist/utils/metric-query-builder.d.ts.map +1 -1
- package/dist/utils/metric-query-builder.js +7 -13
- package/dist/utils/metric-query-validation.d.ts.map +1 -1
- package/dist/utils/metric-query-validation.js +7 -1
- package/dist/utils/portable-aggregations.d.ts +6 -3
- package/dist/utils/portable-aggregations.d.ts.map +1 -1
- package/dist/utils/portable-aggregations.js +16 -7
- package/dist/utils/query-timezone.d.ts +1 -1
- package/dist/utils/query-timezone.d.ts.map +1 -1
- package/dist/utils/query-timezone.js +3 -3
- package/dist/utils/relationship-builder-plan.d.ts +12 -10
- package/dist/utils/relationship-builder-plan.d.ts.map +1 -1
- package/dist/utils/relationship-builder-plan.js +20 -19
- package/dist/utils/relationship-measure-sql.d.ts.map +1 -1
- package/dist/utils/relationship-measure-sql.js +6 -3
- package/dist/utils/relationship-validation.d.ts.map +1 -1
- package/dist/utils/relationship-validation.js +2 -0
- package/dist/utils/row-scope.d.ts +23 -0
- package/dist/utils/row-scope.d.ts.map +1 -0
- package/dist/utils/row-scope.js +26 -0
- package/dist/utils/scoped-dataset-source.d.ts +23 -0
- package/dist/utils/scoped-dataset-source.d.ts.map +1 -0
- package/dist/utils/scoped-dataset-source.js +34 -0
- package/dist/utils/snapshot-execution-context.d.ts.map +1 -1
- package/dist/utils/snapshot-execution-context.js +3 -0
- package/dist/utils/time-measure-axis-sql.d.ts +1 -1
- package/dist/utils/time-measure-axis-sql.d.ts.map +1 -1
- package/dist/utils/time-measure-axis-sql.js +2 -1
- package/dist/utils/time-measure-leaf-sql.d.ts +1 -1
- package/dist/utils/time-measure-leaf-sql.d.ts.map +1 -1
- package/dist/utils/time-measure-leaf-sql.js +3 -1
- package/dist/utils/time-measure-source-sql.d.ts +3 -0
- package/dist/utils/time-measure-source-sql.d.ts.map +1 -1
- package/dist/utils/time-measure-source-sql.js +10 -9
- package/package.json +3 -3
package/dist/protocol-adapter.js
CHANGED
|
@@ -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 {
|
|
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:
|
|
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;
|
|
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
|
|
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":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,gBAAgB,CAAC;IAGrD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACtD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACxD,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAChE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACtD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACtD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAGtD,kEAAkE;IAClE,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC7E,kEAAkE;IAClE,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC7E,+DAA+D;IAC/D,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC3E,6CAA6C;IAC7C,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC1D,mCAAmC;IACnC,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC5D,gEAAgE;IAChE,mBAAmB,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACvE;;;;;OAKG;IACH,UAAU,CAAC,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAGrF,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAAC;IAE1E;;;;;OAKG;IACH,KAAK,CAAC,IAAI,gBAAgB,CAAC;
|
|
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;
|
|
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 {
|
|
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
|
-
|
|
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,
|
|
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"}
|
package/dist/semantic-planner.js
CHANGED
|
@@ -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 {
|
|
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.
|
|
71
|
-
throw new Error(`Dataset "${ds.name}"
|
|
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:
|
|
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:
|
|
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;
|
|
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;AAGlE,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;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,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;AAsN9E,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"}
|
|
@@ -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
|
};
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,KAAK,oBAAoB,EAC1B,MAAM,cAAc,CAAC;AAatB,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,WAAW,sBAAsB,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO;IACzF,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtE;AAED,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,aAAa,GAAG,YAAY,CAAC;AAEvE,MAAM,WAAW,oBAAoB;IACnC,OAAO,CACL,MAAM,EAAE,kBAAkB,GAAG,YAAY,EACzC,KAAK,CAAC,EAAE,YAAY,GAAG,WAAW,EAClC,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAC/C,SAAS,EAAE,oBAAoB,CAAC;IAChC,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,UAAU,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;CACzB;
|
|
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
|
-
|
|
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
|
|
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
|
-
/**
|
|
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?:
|
|
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;
|