@hypequery/datasets 0.18.0 → 0.19.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/agent-catalog.d.ts +9 -0
- package/dist/agent-catalog.d.ts.map +1 -1
- package/dist/aggregations.d.ts +2 -0
- package/dist/aggregations.d.ts.map +1 -1
- package/dist/aggregations.js +4 -0
- package/dist/api.type-test.js +35 -0
- package/dist/cache/query-signature.d.ts.map +1 -1
- package/dist/cache/query-signature.js +17 -0
- package/dist/catalog.d.ts +11 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +12 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -0
- package/dist/contract.d.ts +5 -1
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +7 -0
- package/dist/dataset-query.d.ts.map +1 -1
- package/dist/dataset-query.js +6 -1
- package/dist/dataset.d.ts +2 -2
- package/dist/dataset.d.ts.map +1 -1
- package/dist/dataset.js +3 -0
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +15 -4
- package/dist/in-memory-backend.d.ts.map +1 -1
- package/dist/in-memory-backend.js +34 -7
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/measure.d.ts +5 -0
- package/dist/measure.d.ts.map +1 -1
- package/dist/measure.js +5 -0
- package/dist/portable-execution-errors.d.ts +4 -0
- package/dist/portable-execution-errors.d.ts.map +1 -1
- package/dist/portable-execution-errors.js +4 -1
- package/dist/portable-executor.d.ts.map +1 -1
- package/dist/portable-executor.js +6 -3
- package/dist/protocol-adapter.d.ts.map +1 -1
- package/dist/protocol-adapter.js +15 -7
- package/dist/protocol-rehydrate.d.ts +5 -1
- package/dist/protocol-rehydrate.d.ts.map +1 -1
- package/dist/protocol-rehydrate.js +20 -10
- package/dist/query-builder-protocol.d.ts +7 -3
- package/dist/query-builder-protocol.d.ts.map +1 -1
- package/dist/query-planner.d.ts.map +1 -1
- package/dist/query-planner.js +5 -0
- package/dist/relationship-check.d.ts +47 -0
- package/dist/relationship-check.d.ts.map +1 -0
- package/dist/relationship-check.js +59 -0
- package/dist/relationships.d.ts +10 -10
- package/dist/relationships.js +10 -10
- package/dist/semantic-planner.d.ts.map +1 -1
- package/dist/semantic-planner.js +5 -1
- package/dist/semantic-query-schema.d.ts.map +1 -1
- package/dist/semantic-query-schema.js +5 -0
- package/dist/types.d.ts +39 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/agent-catalog-projection.d.ts +6 -0
- package/dist/utils/agent-catalog-projection.d.ts.map +1 -1
- package/dist/utils/agent-catalog-projection.js +4 -0
- package/dist/utils/approximate-measures.d.ts +10 -0
- package/dist/utils/approximate-measures.d.ts.map +1 -0
- package/dist/utils/approximate-measures.js +15 -0
- package/dist/utils/dataset-contract.d.ts.map +1 -1
- package/dist/utils/dataset-contract.js +2 -2
- package/dist/utils/dataset-metric-ref.d.ts.map +1 -1
- package/dist/utils/dataset-metric-ref.js +5 -0
- package/dist/utils/dataset-query-validation.d.ts.map +1 -1
- package/dist/utils/dataset-query-validation.js +6 -3
- package/dist/utils/dataset-time-grains.d.ts +15 -0
- package/dist/utils/dataset-time-grains.d.ts.map +1 -0
- package/dist/utils/dataset-time-grains.js +17 -0
- package/dist/utils/filtered-aggregation-sql.d.ts.map +1 -1
- package/dist/utils/filtered-aggregation-sql.js +1 -0
- package/dist/utils/portable-aggregations.d.ts +14 -0
- package/dist/utils/portable-aggregations.d.ts.map +1 -0
- package/dist/utils/portable-aggregations.js +15 -0
- package/dist/utils/portable-grains.d.ts +22 -0
- package/dist/utils/portable-grains.d.ts.map +1 -0
- package/dist/utils/portable-grains.js +35 -0
- package/dist/utils/portable-semantic-query.d.ts.map +1 -1
- package/dist/utils/portable-semantic-query.js +2 -1
- package/dist/utils/protocol-metric-expressions.d.ts.map +1 -1
- package/dist/utils/protocol-metric-expressions.js +2 -1
- package/dist/utils/relationship-builder-plan.d.ts +6 -3
- package/dist/utils/relationship-builder-plan.d.ts.map +1 -1
- package/dist/utils/relationship-builder-plan.js +13 -5
- package/dist/utils/relationship-key-check.d.ts +43 -0
- package/dist/utils/relationship-key-check.d.ts.map +1 -0
- package/dist/utils/relationship-key-check.js +72 -0
- package/dist/utils/segments.d.ts +31 -0
- package/dist/utils/segments.d.ts.map +1 -0
- package/dist/utils/segments.js +91 -0
- package/dist/utils/semantic-metadata-validation.d.ts.map +1 -1
- package/dist/utils/semantic-metadata-validation.js +22 -1
- package/dist/utils/unsupported-contract-reasons.d.ts +32 -0
- package/dist/utils/unsupported-contract-reasons.d.ts.map +1 -0
- package/dist/utils/unsupported-contract-reasons.js +30 -0
- package/package.json +3 -3
package/dist/agent-catalog.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface AgentCatalogMeasure extends SemanticMetadata {
|
|
|
14
14
|
name: string;
|
|
15
15
|
label?: string;
|
|
16
16
|
description?: string;
|
|
17
|
+
/** Present, as `true`, when the value is an estimate; say so when reporting it. */
|
|
18
|
+
approximate?: true;
|
|
17
19
|
}
|
|
18
20
|
export interface AgentCatalogMetric extends SemanticMetadata {
|
|
19
21
|
name: string;
|
|
@@ -47,9 +49,16 @@ export interface AgentCatalogDataset extends SemanticMetadata {
|
|
|
47
49
|
measures: AgentCatalogMeasure[];
|
|
48
50
|
metrics: AgentCatalogMetric[];
|
|
49
51
|
filters: AgentCatalogFilter[];
|
|
52
|
+
/** Named segments an agent can select; their conditions are never shown. */
|
|
53
|
+
segments?: AgentCatalogSegment[];
|
|
50
54
|
relationships: AgentCatalogRelationship[];
|
|
51
55
|
limits: DatasetLimits;
|
|
52
56
|
}
|
|
57
|
+
export interface AgentCatalogSegment {
|
|
58
|
+
name: string;
|
|
59
|
+
label?: string;
|
|
60
|
+
description?: string;
|
|
61
|
+
}
|
|
53
62
|
export interface AgentSafeCatalog {
|
|
54
63
|
datasets: AgentCatalogDataset[];
|
|
55
64
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-catalog.d.ts","sourceRoot":"","sources":["../src/agent-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,SAAS,EACT,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAOpB,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-catalog.d.ts","sourceRoot":"","sources":["../src/agent-catalog.ts"],"names":[],"mappings":"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"}
|
package/dist/aggregations.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ import type { AggregationSpec } from './types.js';
|
|
|
18
18
|
export declare function sum(field: string): AggregationSpec;
|
|
19
19
|
export declare function count(field: string): AggregationSpec;
|
|
20
20
|
export declare function countDistinct(field: string): AggregationSpec;
|
|
21
|
+
/** Estimated distinct count (ClickHouse `uniq`). */
|
|
22
|
+
export declare function approxCountDistinct(field: string): AggregationSpec;
|
|
21
23
|
export declare function avg(field: string): AggregationSpec;
|
|
22
24
|
export declare function min(field: string): AggregationSpec;
|
|
23
25
|
export declare function max(field: string): AggregationSpec;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregations.d.ts","sourceRoot":"","sources":["../src/aggregations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAWnE,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAEpD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAE5D;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAGxE;AAED,mDAAmD;AACnD,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAErD;AAED,0DAA0D;AAC1D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,CAKjE;AAED,0DAA0D;AAC1D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,CAKjE;AAED,iCAAiC;AACjC,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAErD;AAED,uBAAuB;AACvB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAEvD"}
|
|
1
|
+
{"version":3,"file":"aggregations.d.ts","sourceRoot":"","sources":["../src/aggregations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,YAAY,CAAC;AAWnE,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAEpD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAE5D;AAED,oDAAoD;AACpD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElE;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAElD;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,eAAe,CAGxE;AAED,mDAAmD;AACnD,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAErD;AAED,0DAA0D;AAC1D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,CAKjE;AAED,0DAA0D;AAC1D,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,eAAe,CAKjE;AAED,iCAAiC;AACjC,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAErD;AAED,uBAAuB;AACvB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAEvD"}
|
package/dist/aggregations.js
CHANGED
|
@@ -31,6 +31,10 @@ export function count(field) {
|
|
|
31
31
|
export function countDistinct(field) {
|
|
32
32
|
return createAggregation('countDistinct', field);
|
|
33
33
|
}
|
|
34
|
+
/** Estimated distinct count (ClickHouse `uniq`). */
|
|
35
|
+
export function approxCountDistinct(field) {
|
|
36
|
+
return createAggregation('approxCountDistinct', field);
|
|
37
|
+
}
|
|
34
38
|
export function avg(field) {
|
|
35
39
|
return createAggregation('avg', field);
|
|
36
40
|
}
|
package/dist/api.type-test.js
CHANGED
|
@@ -21,6 +21,25 @@ const Orders = dataset('orders', {
|
|
|
21
21
|
}),
|
|
22
22
|
},
|
|
23
23
|
});
|
|
24
|
+
const _SegmentedOrders = dataset('segmentedOrders', {
|
|
25
|
+
source: 'orders',
|
|
26
|
+
dimensions: { status: dimension.string() },
|
|
27
|
+
measures: { revenue: measure.sum('amount') },
|
|
28
|
+
segments: { paid: { filters: [eq('status', 'paid')] } },
|
|
29
|
+
});
|
|
30
|
+
const validDatasetSegments = { segments: ['paid'] };
|
|
31
|
+
const validMetricSegments = { segments: ['paid'] };
|
|
32
|
+
void validDatasetSegments;
|
|
33
|
+
void validMetricSegments;
|
|
34
|
+
// @ts-expect-error only declared segment names are accepted.
|
|
35
|
+
const invalidDatasetSegments = { segments: ['paidd'] };
|
|
36
|
+
// @ts-expect-error only declared segment names are accepted on metric queries.
|
|
37
|
+
const invalidMetricSegments = { segments: ['paidd'] };
|
|
38
|
+
// @ts-expect-error a dataset without segments has no selectable segment names.
|
|
39
|
+
const invalidPlainSegments = { segments: ['paid'] };
|
|
40
|
+
void invalidDatasetSegments;
|
|
41
|
+
void invalidMetricSegments;
|
|
42
|
+
void invalidPlainSegments;
|
|
24
43
|
// @ts-expect-error standalone metrics may only target base measures.
|
|
25
44
|
Orders.metric('invalidDerivedMetric', { measure: 'doubledRevenue' });
|
|
26
45
|
dataset('derivedDependency', {
|
|
@@ -186,3 +205,19 @@ void typedAccepted;
|
|
|
186
205
|
void typedClient;
|
|
187
206
|
void typedRuntime;
|
|
188
207
|
void rejectedFactory;
|
|
208
|
+
// ---------------------------------------------------------------------------
|
|
209
|
+
// Portable execution exclusions carry a named reason (HQ-45)
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
import { PortableExecutionUnsupportedError as PortableUnsupported, UNSUPPORTED_CONTRACT_REASONS as REASONS, UnsupportedContractFeatureError as ContractFeatureError, } from './index.js';
|
|
212
|
+
const namedReason = REASONS.ambiguousMeasureSql;
|
|
213
|
+
const literalReason = 'HQ_PORTABLE_DATASET_NOT_ACTIVATED';
|
|
214
|
+
// @ts-expect-error an unnamed reason is not an exclusion
|
|
215
|
+
const unnamedReason = 'HQ_PORTABLE_SOMETHING_ELSE';
|
|
216
|
+
const featureReason = new ContractFeatureError('orders', 'metric', 'detail', namedReason).reason;
|
|
217
|
+
// The three-argument constructor stays valid for existing callers.
|
|
218
|
+
const legacyFeatureError = new ContractFeatureError('orders', 'metric', 'detail');
|
|
219
|
+
const executionReason = new PortableUnsupported('message', { reason: literalReason }).reason;
|
|
220
|
+
void unnamedReason;
|
|
221
|
+
void featureReason;
|
|
222
|
+
void legacyFeatureError;
|
|
223
|
+
void executionReason;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-signature.d.ts","sourceRoot":"","sources":["../../src/cache/query-signature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAGhB,WAAW,EACX,SAAS,EACV,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"query-signature.d.ts","sourceRoot":"","sources":["../../src/cache/query-signature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAGhB,WAAW,EACX,SAAS,EACV,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,CAAC;AAsF3B,wBAAgB,0BAA0B,CACxC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAkBR;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS,GAAG,gBAAgB,EACpC,KAAK,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAmBR"}
|
|
@@ -69,6 +69,21 @@ function tenantSignature(ds, query, context) {
|
|
|
69
69
|
}
|
|
70
70
|
return { key: ds.tenantKey, operator: predicate.operator, value: predicate.value };
|
|
71
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Selected segments keyed by their resolved definitions, not just their names,
|
|
74
|
+
* so editing a segment cannot serve rows cached under the old one. Absent when
|
|
75
|
+
* no segment is selected, which keeps existing signatures unchanged.
|
|
76
|
+
*/
|
|
77
|
+
function segmentSignature(ds, names) {
|
|
78
|
+
if (!names?.length)
|
|
79
|
+
return {};
|
|
80
|
+
return {
|
|
81
|
+
segments: [...new Set(names)].sort().map(name => ({
|
|
82
|
+
name,
|
|
83
|
+
filters: filterSignature(ds.segments?.[name]?.filters),
|
|
84
|
+
})),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
72
87
|
export function buildDatasetQuerySignature(ds, query, context) {
|
|
73
88
|
return stableStringify({
|
|
74
89
|
v: SIGNATURE_VERSION,
|
|
@@ -79,6 +94,7 @@ export function buildDatasetQuerySignature(ds, query, context) {
|
|
|
79
94
|
// `null` distinguishes the "all measures" default from an explicit [].
|
|
80
95
|
measures: query.measures ?? null,
|
|
81
96
|
filters: filterSignature(query.filters),
|
|
97
|
+
...segmentSignature(ds, query.segments),
|
|
82
98
|
orderBy: orderBySignature(query.orderBy),
|
|
83
99
|
by: query.by ?? null,
|
|
84
100
|
limit: query.limit ?? null,
|
|
@@ -98,6 +114,7 @@ export function buildMetricQuerySignature(metric, query, context) {
|
|
|
98
114
|
metricKind: ref.spec.__type,
|
|
99
115
|
dimensions: query.dimensions ?? null,
|
|
100
116
|
filters: filterSignature(query.filters),
|
|
117
|
+
...segmentSignature(ref.dataset, query.segments),
|
|
101
118
|
orderBy: orderBySignature(query.orderBy),
|
|
102
119
|
by: grain ?? null,
|
|
103
120
|
limit: query.limit ?? null,
|
package/dist/catalog.d.ts
CHANGED
|
@@ -19,10 +19,19 @@ export interface MeasureCatalogEntry extends SemanticMetadata {
|
|
|
19
19
|
label?: string;
|
|
20
20
|
description?: string;
|
|
21
21
|
filterCount: number;
|
|
22
|
+
/** Present, as `true`, when the measure returns an estimate. */
|
|
23
|
+
approximate?: true;
|
|
22
24
|
}
|
|
23
25
|
export interface DerivedMeasureCatalogEntry extends SemanticMetadata {
|
|
24
26
|
label?: string;
|
|
25
27
|
description?: string;
|
|
28
|
+
/** Present, as `true`, when any measure the formula uses is approximate. */
|
|
29
|
+
approximate?: true;
|
|
30
|
+
}
|
|
31
|
+
/** A named segment. Its filters stay in the definition and are never catalogued. */
|
|
32
|
+
export interface SegmentCatalogEntry {
|
|
33
|
+
label?: string;
|
|
34
|
+
description?: string;
|
|
26
35
|
}
|
|
27
36
|
export interface FilterCatalogEntry extends SemanticMetadata {
|
|
28
37
|
field: string;
|
|
@@ -72,6 +81,8 @@ export interface DatasetCatalog extends SemanticMetadata {
|
|
|
72
81
|
derivedMeasures?: Record<string, DerivedMeasureCatalogEntry>;
|
|
73
82
|
metrics: Record<string, MetricCatalogEntry>;
|
|
74
83
|
filters: Record<string, FilterCatalogEntry>;
|
|
84
|
+
/** Named segments; absent when the dataset declares none. */
|
|
85
|
+
segments?: Record<string, SegmentCatalogEntry>;
|
|
75
86
|
relationships: Record<string, RelationshipCatalogEntry>;
|
|
76
87
|
limits?: DatasetLimits;
|
|
77
88
|
requiresTenant: boolean;
|
package/dist/catalog.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,EACV,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
package/dist/catalog.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { SEMANTIC_FILTER_OPERATORS
|
|
1
|
+
import { SEMANTIC_FILTER_OPERATORS } from './constants.js';
|
|
2
|
+
import { datasetTimeGrains } from './utils/dataset-time-grains.js';
|
|
3
|
+
import { isApproximateAggregation, isApproximateDerivedMeasure } from './utils/approximate-measures.js';
|
|
2
4
|
import { listGroupableRelationshipFields, listQueryableRelationshipFields, } from './utils/relationship-fields.js';
|
|
3
5
|
import { snapshotSemanticMetadata } from './utils/semantic-metadata.js';
|
|
4
6
|
function dimensionToCatalog(dimension) {
|
|
@@ -24,6 +26,7 @@ function measureToCatalog(measure) {
|
|
|
24
26
|
description: measure.description,
|
|
25
27
|
...snapshotSemanticMetadata(measure),
|
|
26
28
|
filterCount: measure.filters?.length ?? 0,
|
|
29
|
+
...(isApproximateAggregation(measure.aggregation) ? { approximate: true } : {}),
|
|
27
30
|
};
|
|
28
31
|
}
|
|
29
32
|
function filterToCatalog(filter, dimensions) {
|
|
@@ -81,7 +84,7 @@ export function getDatasetCatalog(dataset) {
|
|
|
81
84
|
const measureNames = Object.keys(dataset.measures);
|
|
82
85
|
const derivedMeasureNames = Object.keys(dataset.derivedMeasures ?? {});
|
|
83
86
|
const metricNames = Object.keys(dataset.metrics ?? {});
|
|
84
|
-
const supportedGrains =
|
|
87
|
+
const supportedGrains = [...datasetTimeGrains(dataset)];
|
|
85
88
|
const maxLimit = dataset.limits?.maxResultSize;
|
|
86
89
|
const relationships = Object.fromEntries(Object.entries(dataset.relationships).map(([name, relationship]) => [
|
|
87
90
|
name,
|
|
@@ -112,6 +115,7 @@ export function getDatasetCatalog(dataset) {
|
|
|
112
115
|
...snapshotSemanticMetadata(definition),
|
|
113
116
|
label: definition.label,
|
|
114
117
|
description: definition.description,
|
|
118
|
+
...(isApproximateDerivedMeasure(dataset.measures, definition) ? { approximate: true } : {}),
|
|
115
119
|
},
|
|
116
120
|
])),
|
|
117
121
|
} : {}),
|
|
@@ -119,6 +123,12 @@ export function getDatasetCatalog(dataset) {
|
|
|
119
123
|
name,
|
|
120
124
|
metricToCatalog(metric),
|
|
121
125
|
])),
|
|
126
|
+
...(Object.keys(dataset.segments ?? {}).length > 0 ? {
|
|
127
|
+
segments: Object.fromEntries(Object.entries(dataset.segments).map(([name, segment]) => [name, {
|
|
128
|
+
...(segment.label !== undefined ? { label: segment.label } : {}),
|
|
129
|
+
...(segment.description !== undefined ? { description: segment.description } : {}),
|
|
130
|
+
}])),
|
|
131
|
+
} : {}),
|
|
122
132
|
filters: Object.fromEntries(Object.entries(dataset.filters).map(([name, filter]) => [
|
|
123
133
|
name,
|
|
124
134
|
filterToCatalog(filter, dataset.dimensions),
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1D;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1D;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAQrD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAmC,SAAS,EAAE,CAAC;AAEjF;;GAEG;AACH,eAAO,MAAM,yBAAyB,oFAWkB,CAAC;AAEzD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAEvE"}
|
package/dist/constants.js
CHANGED
package/dist/contract.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DatasetCatalogSource, type DimensionCatalogEntry, type MeasureCatalogEntry, type MetricCatalogEntry, type FilterCatalogEntry, type RelationshipCatalogEntry } from './catalog.js';
|
|
1
|
+
import { type DatasetCatalogSource, type DimensionCatalogEntry, type MeasureCatalogEntry, type SegmentCatalogEntry, type MetricCatalogEntry, type FilterCatalogEntry, type RelationshipCatalogEntry } from './catalog.js';
|
|
2
2
|
import type { DatasetDefaults, DatasetFreshness, DatasetLimits, SemanticMetadata } from './types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Version of the semantic contract format. Bump when the serialized shape
|
|
@@ -24,6 +24,8 @@ export interface ContractMeasure extends SemanticMetadata {
|
|
|
24
24
|
sql?: string;
|
|
25
25
|
label?: string;
|
|
26
26
|
description?: string;
|
|
27
|
+
/** Present, as `true`, when the measure returns an estimate. */
|
|
28
|
+
approximate?: true;
|
|
27
29
|
}
|
|
28
30
|
export interface ContractMetric extends SemanticMetadata {
|
|
29
31
|
kind: MetricCatalogEntry['kind'];
|
|
@@ -67,6 +69,8 @@ export interface ContractDataset extends SemanticMetadata {
|
|
|
67
69
|
measures: Record<string, ContractMeasure>;
|
|
68
70
|
metrics: Record<string, ContractMetric>;
|
|
69
71
|
filters: Record<string, ContractFilter>;
|
|
72
|
+
/** Named segments (label and description only); absent when none are declared. */
|
|
73
|
+
segments?: Record<string, SegmentCatalogEntry>;
|
|
70
74
|
relationships: Record<string, ContractRelationship>;
|
|
71
75
|
limits?: DatasetLimits;
|
|
72
76
|
}
|
package/dist/contract.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC9B,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,WAAW,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
|
package/dist/contract.js
CHANGED
|
@@ -57,6 +57,12 @@ function datasetToContract(catalog, includeSql) {
|
|
|
57
57
|
measures: sortedRecord(Object.entries(catalog.measures).map(([name, entry]) => [name, measureToContract(entry, includeSql)])),
|
|
58
58
|
metrics: sortedRecord(Object.entries(catalog.metrics).map(([name, entry]) => [name, metricToContract(entry)])),
|
|
59
59
|
filters: sortedRecord(Object.entries(catalog.filters).map(([name, entry]) => [name, filterToContract(entry)])),
|
|
60
|
+
...(catalog.segments !== undefined ? {
|
|
61
|
+
segments: sortedRecord(Object.entries(catalog.segments).map(([name, entry]) => [name, {
|
|
62
|
+
...(entry.label !== undefined ? { label: entry.label } : {}),
|
|
63
|
+
...(entry.description !== undefined ? { description: entry.description } : {}),
|
|
64
|
+
}])),
|
|
65
|
+
} : {}),
|
|
60
66
|
relationships: sortedRecord(Object.entries(catalog.relationships).map(([name, entry]) => [name, relationshipToContract(entry)])),
|
|
61
67
|
...(catalog.limits !== undefined ? { limits: limitsToContract(catalog.limits) } : {}),
|
|
62
68
|
};
|
|
@@ -96,6 +102,7 @@ function measureToContract(entry, includeSql) {
|
|
|
96
102
|
...(entry.label !== undefined ? { label: entry.label } : {}),
|
|
97
103
|
...(entry.description !== undefined ? { description: entry.description } : {}),
|
|
98
104
|
...snapshotSemanticMetadata(entry),
|
|
105
|
+
...(entry.approximate ? { approximate: true } : {}),
|
|
99
106
|
};
|
|
100
107
|
}
|
|
101
108
|
function metricToContract(entry) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset-query.d.ts","sourceRoot":"","sources":["../src/dataset-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"dataset-query.d.ts","sourceRoot":"","sources":["../src/dataset-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAS7F,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAgBxD,MAAM,WAAW,4BAA4B;IAC3C,cAAc,EAAE,uBAAuB,CAAC;IACxC,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2FAA2F;IAC3F,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,YAAY,EACnB,OAAO,CAAC,EAAE,gBAAgB,GACzB,gBAAgB,CAElB;AAED,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,4BAA4B,GACpC,gBAAgB,CAoDlB;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,kBAAkB,CAAC,CAmB7B"}
|
package/dist/dataset-query.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { appendOrderLimitOffset, applyMeasureDefinition, buildDimensionSelectionPlan, resolveFilterField, resolveTenantFilterColumn, } from './query-planner.js';
|
|
1
|
+
import { appendOrderLimitOffset, applyMeasureDefinition, buildDimensionSelectionPlan, resolveDimensionExpression, resolveFilterField, resolveTenantFilterColumn, } from './query-planner.js';
|
|
2
2
|
import { validateDatasetQueryInput } from './utils/dataset-query-validation.js';
|
|
3
3
|
import { getRuntimeTenantPredicate } from './utils/tenant-runtime.js';
|
|
4
4
|
import { overfetchLimit } from './utils/pagination.js';
|
|
5
5
|
import { applyRelationshipJoins, buildRelationshipBuilderContext, qualifyBaseColumn, } from './utils/relationship-builder-plan.js';
|
|
6
6
|
import { hasSelectedDerivedMeasure, runDerivedDatasetQuery, } from './utils/dataset-derived-query.js';
|
|
7
7
|
import { toDatasetQueryResult } from './utils/dataset-query-result.js';
|
|
8
|
+
import { segmentFilters } from './utils/segments.js';
|
|
8
9
|
export function validateDatasetQuery(ds, query, context) {
|
|
9
10
|
return validateDatasetQueryInput(ds, query, context);
|
|
10
11
|
}
|
|
@@ -39,6 +40,10 @@ export function buildDatasetQueryBuilder(ds, query, options) {
|
|
|
39
40
|
const resolvedField = resolveFilterField(ds, filter.field, joinCtx);
|
|
40
41
|
qb = qb.where(resolvedField, filter.operator, filter.value);
|
|
41
42
|
}
|
|
43
|
+
// Segments are author-defined, so they bypass the caller filter allow-list.
|
|
44
|
+
for (const filter of segmentFilters(ds, query.segments)) {
|
|
45
|
+
qb = qb.where(resolveDimensionExpression(ds, filter.field, joinCtx), filter.operator, filter.value);
|
|
46
|
+
}
|
|
42
47
|
return appendOrderLimitOffset(qb, query.orderBy, options.skipDefaultOrderBy ? undefined : query.by, options.executionLimit ?? query.limit, query.offset, joinCtx);
|
|
43
48
|
}
|
|
44
49
|
export async function runDatasetQuery(ds, query, options) {
|
package/dist/dataset.d.ts
CHANGED
|
@@ -29,6 +29,6 @@
|
|
|
29
29
|
* });
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
|
-
import type { DatasetConfig, DatasetInstance, DatasetMeasureDefinition, BaseMeasures, DerivedMeasures, DimensionDefinition, RelationshipDefinition } from './types.js';
|
|
33
|
-
export declare function dataset<TDatasetName extends string, TDimensions extends Record<string, DimensionDefinition>, TDefinitions extends Record<string, DatasetMeasureDefinition> = {}, TRelationships extends Record<string, RelationshipDefinition> = Record<string, never
|
|
32
|
+
import type { DatasetConfig, DatasetInstance, DatasetMeasureDefinition, BaseMeasures, DerivedMeasures, DimensionDefinition, RelationshipDefinition, SegmentDefinition } from './types.js';
|
|
33
|
+
export declare function dataset<TDatasetName extends string, TDimensions extends Record<string, DimensionDefinition>, TDefinitions extends Record<string, DatasetMeasureDefinition> = {}, TRelationships extends Record<string, RelationshipDefinition> = Record<string, never>, const TSegments extends Record<string, SegmentDefinition> = {}>(name: TDatasetName, config: DatasetConfig<TDimensions, TDefinitions, TRelationships, TSegments>): DatasetInstance<TDimensions, BaseMeasures<TDefinitions>, TRelationships, TDatasetName, DerivedMeasures<TDefinitions>, TSegments>;
|
|
34
34
|
//# sourceMappingURL=dataset.d.ts.map
|
package/dist/dataset.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../src/dataset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"dataset.d.ts","sourceRoot":"","sources":["../src/dataset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EAKtB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAsBpB,wBAAgB,OAAO,CACrB,YAAY,SAAS,MAAM,EAC3B,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,EACvD,YAAY,SAAS,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,GAAG,EAAE,EAClE,cAAc,SAAS,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACrF,KAAK,CAAC,SAAS,SAAS,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,EAAE,EAE9D,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,aAAa,CAAC,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,CAAC,GAC1E,eAAe,CAAC,WAAW,EAAE,YAAY,CAAC,YAAY,CAAC,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC,CA+ElI"}
|
package/dist/dataset.js
CHANGED
|
@@ -36,6 +36,7 @@ import { validateDatasetDefinition } from './utils/dataset-definition-validation
|
|
|
36
36
|
import { snapshotSemanticMetadata } from './utils/semantic-metadata.js';
|
|
37
37
|
import { validateSemanticMetadata } from './utils/semantic-metadata-validation.js';
|
|
38
38
|
import { splitDatasetMeasures } from './utils/dataset-measures.js';
|
|
39
|
+
import { normalizeSegments } from './utils/segments.js';
|
|
39
40
|
export function dataset(name, config) {
|
|
40
41
|
// Structural validation runs before anything is normalized, so an invalid
|
|
41
42
|
// model fails at definition time rather than on the first query that reaches
|
|
@@ -75,6 +76,7 @@ export function dataset(name, config) {
|
|
|
75
76
|
},
|
|
76
77
|
tenantKey: config.tenantKey,
|
|
77
78
|
timeKey: config.timeKey,
|
|
79
|
+
...(config.timeGrains === undefined ? {} : { timeGrains: Object.freeze([...config.timeGrains]) }),
|
|
78
80
|
dimensions,
|
|
79
81
|
measures,
|
|
80
82
|
derivedMeasures,
|
|
@@ -82,6 +84,7 @@ export function dataset(name, config) {
|
|
|
82
84
|
relationships,
|
|
83
85
|
limits: config.limits,
|
|
84
86
|
cache: config.cache,
|
|
87
|
+
segments: normalizeSegments(name, { tenantKey: config.tenantKey, dimensions }, config.segments),
|
|
85
88
|
metric,
|
|
86
89
|
};
|
|
87
90
|
return ds;
|
package/dist/executor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAGhB,kBAAkB,EAClB,eAAe,EAEhB,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAEV,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
|
package/dist/executor.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { protocolMetricCapabilityErrors } from './utils/protocol-metric-capabilities.js';
|
|
2
2
|
import { toQueryBuilderFactory } from './query-builder-protocol.js';
|
|
3
3
|
import { quoteSQLIdentifier, validateSQLIdentifier } from './sql-utils.js';
|
|
4
|
-
import {
|
|
4
|
+
import { unsupportedTimeGrainError } from './utils/dataset-time-grains.js';
|
|
5
5
|
import { validateFilterValue } from './validation.js';
|
|
6
|
-
import { applyAggregationSpec, appendOrderLimitOffset, buildDimensionSelectionPlan, resolveFilterField, resolveTenantFilterColumn, } from './query-planner.js';
|
|
6
|
+
import { applyAggregationSpec, appendOrderLimitOffset, buildDimensionSelectionPlan, resolveDimensionExpression, resolveFilterField, resolveTenantFilterColumn, } from './query-planner.js';
|
|
7
7
|
import { assertMetricHandle, getMetricGrain, getMetricRef, isTenantScopedFilter, } from './utils/metric-handle.js';
|
|
8
8
|
import { validateDerivedCteGrouping } from './utils/derived-cte-validation.js';
|
|
9
9
|
import { buildDatasetQueryBuilder, runDatasetQuery, validateDatasetQuery, } from './dataset-query.js';
|
|
@@ -19,6 +19,7 @@ import { resolveDatasetCacheRuntime, } from './utils/dataset-cache-policy.js';
|
|
|
19
19
|
import { isQualifiedField, resolveQualifiedField } from './utils/relationship-fields.js';
|
|
20
20
|
import { validateQualifiedFilter, validateRelationshipTenantRuntime, } from './utils/relationship-validation.js';
|
|
21
21
|
import { applyRelationshipJoins, buildRelationshipBuilderContext, qualifyBaseColumn, } from './utils/relationship-builder-plan.js';
|
|
22
|
+
import { segmentFilters, segmentSelectionErrors } from './utils/segments.js';
|
|
22
23
|
function validateQuery(metric, query, context) {
|
|
23
24
|
const errors = protocolMetricCapabilityErrors(metric, query);
|
|
24
25
|
const ref = getMetricRef(metric);
|
|
@@ -97,8 +98,10 @@ function validateQuery(metric, query, context) {
|
|
|
97
98
|
errors.push(`Cannot use "by" grain — dataset "${ds.name}" has no timeKey.`);
|
|
98
99
|
}
|
|
99
100
|
// Validate grain is one the planner can bucket on
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
errors.push(...segmentSelectionErrors(ds, query.segments));
|
|
102
|
+
const grainError = query.by && ds.timeKey ? unsupportedTimeGrainError(ds, query.by) : undefined;
|
|
103
|
+
if (grainError) {
|
|
104
|
+
errors.push(grainError);
|
|
102
105
|
}
|
|
103
106
|
if (query.limit != null && (!Number.isInteger(query.limit) || query.limit < 0)) {
|
|
104
107
|
errors.push(`Invalid limit: expected a non-negative integer.`);
|
|
@@ -273,6 +276,11 @@ export class MetricQueryEngine {
|
|
|
273
276
|
const resolvedField = resolveFilterField(ds, filter.field, joinCtx);
|
|
274
277
|
qb = qb.where(resolvedField, filter.operator, filter.value);
|
|
275
278
|
}
|
|
279
|
+
// Segments: author-defined, so they resolve dimensions directly rather
|
|
280
|
+
// than through the caller-facing filter allow-list.
|
|
281
|
+
for (const filter of segmentFilters(ds, query.segments)) {
|
|
282
|
+
qb = qb.where(resolveDimensionExpression(ds, filter.field, joinCtx), filter.operator, filter.value);
|
|
283
|
+
}
|
|
276
284
|
// Order, limit, offset
|
|
277
285
|
qb = appendOrderLimitOffset(qb, query.orderBy, grain, query.limit, query.offset, joinCtx);
|
|
278
286
|
return qb;
|
|
@@ -316,6 +324,9 @@ export class MetricQueryEngine {
|
|
|
316
324
|
const resolvedField = resolveFilterField(ds, filter.field, joinCtx);
|
|
317
325
|
cteBuilder = cteBuilder.where(resolvedField, filter.operator, filter.value);
|
|
318
326
|
}
|
|
327
|
+
for (const filter of segmentFilters(ds, query.segments)) {
|
|
328
|
+
cteBuilder = cteBuilder.where(resolveDimensionExpression(ds, filter.field, joinCtx), filter.operator, filter.value);
|
|
329
|
+
}
|
|
319
330
|
const { sql: cteSql, parameters: cteParams } = cteBuilder.toSQLWithParams();
|
|
320
331
|
const groupingErrors = validateDerivedCteGrouping(cteSql, aggregateAliases, groupByParts);
|
|
321
332
|
if (groupingErrors.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in-memory-backend.d.ts","sourceRoot":"","sources":["../src/in-memory-backend.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAGV,eAAe,EAKhB,MAAM,oBAAoB,CAAC;AAG5B,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3D,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"in-memory-backend.d.ts","sourceRoot":"","sources":["../src/in-memory-backend.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAGV,eAAe,EAKhB,MAAM,oBAAoB,CAAC;AAG5B,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAC3D,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAuV3D;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,eAAe,CAwE7E"}
|
|
@@ -48,7 +48,12 @@ function applyTenant(rows, tenant) {
|
|
|
48
48
|
/**
|
|
49
49
|
* Enriches base rows with columns from to-one joined targets, keyed by the
|
|
50
50
|
* qualified name `<relationship>.<column>`. Mirrors a query-time LEFT JOIN:
|
|
51
|
-
* base rows without a matching target keep the joined columns undefined
|
|
51
|
+
* base rows without a matching target keep the joined columns undefined, and
|
|
52
|
+
* NULL keys never match.
|
|
53
|
+
*
|
|
54
|
+
* A duplicate target key means the relationship is not really to-one. Rather
|
|
55
|
+
* than silently picking one of the matches, the join is refused so the
|
|
56
|
+
* mis-declaration surfaces in tests.
|
|
52
57
|
*/
|
|
53
58
|
function applyJoins(rows, joins, tables) {
|
|
54
59
|
if (!joins || joins.length === 0) {
|
|
@@ -58,18 +63,24 @@ function applyJoins(rows, joins, tables) {
|
|
|
58
63
|
const targetRows = applyTenant(tables[join.source] ?? [], join.tenant);
|
|
59
64
|
const index = new Map();
|
|
60
65
|
for (const row of targetRows) {
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
const value = row[join.to];
|
|
67
|
+
if (value == null) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const key = String(value);
|
|
71
|
+
if (index.has(key)) {
|
|
72
|
+
throw new Error(`Relationship "${join.relationship}" is declared to-one, but "${join.source}.${join.to}" ` +
|
|
73
|
+
`has more than one row with key ${JSON.stringify(key)}. Declare it as hasMany or make the key unique.`);
|
|
65
74
|
}
|
|
75
|
+
index.set(key, row);
|
|
66
76
|
}
|
|
67
77
|
return { join, index };
|
|
68
78
|
});
|
|
69
79
|
return rows.map((row) => {
|
|
70
80
|
const enriched = { ...row };
|
|
71
81
|
for (const { join, index } of indexes) {
|
|
72
|
-
const
|
|
82
|
+
const key = row[join.from];
|
|
83
|
+
const match = key == null ? undefined : index.get(String(key));
|
|
73
84
|
if (match) {
|
|
74
85
|
for (const [column, value] of Object.entries(match)) {
|
|
75
86
|
enriched[`${join.relationship}.${column}`] = value;
|
|
@@ -84,6 +95,20 @@ function periodForValue(value, grain) {
|
|
|
84
95
|
if (Number.isNaN(date.getTime())) {
|
|
85
96
|
return String(value);
|
|
86
97
|
}
|
|
98
|
+
// Sub-day buckets keep their time of day, in the form a ClickHouse DateTime
|
|
99
|
+
// takes in JSON (RFC 0015).
|
|
100
|
+
if (grain.unit === 'minute' || grain.unit === 'hour') {
|
|
101
|
+
// ClickHouse DateTime strings have no offset. Keep their wall-clock hour
|
|
102
|
+
// instead of interpreting them in the Node process's local time zone.
|
|
103
|
+
const naive = typeof value === 'string'
|
|
104
|
+
? /^(\d{4}-\d{2}-\d{2})[ T](\d{2}):(\d{2})(?::\d{2}(?:\.\d+)?)?$/.exec(value)
|
|
105
|
+
: null;
|
|
106
|
+
if (naive) {
|
|
107
|
+
return `${naive[1]} ${naive[2]}:${grain.unit === 'hour' ? '00' : naive[3]}:00`;
|
|
108
|
+
}
|
|
109
|
+
const iso = date.toISOString();
|
|
110
|
+
return `${iso.slice(0, 10)} ${grain.unit === 'hour' ? `${iso.slice(11, 13)}:00` : iso.slice(11, 16)}:00`;
|
|
111
|
+
}
|
|
87
112
|
if (grain.unit === 'year') {
|
|
88
113
|
return `${date.getUTCFullYear()}-01-01`;
|
|
89
114
|
}
|
|
@@ -172,8 +197,10 @@ function aggregateRows(rows, aggregation) {
|
|
|
172
197
|
return values.reduce((total, value) => total + Number(value ?? 0), 0);
|
|
173
198
|
case 'count':
|
|
174
199
|
return filteredRows.length;
|
|
200
|
+
// Exact computation is a faithful approxCountDistinct (RFC 0015).
|
|
175
201
|
case 'countDistinct':
|
|
176
|
-
|
|
202
|
+
case 'approxCountDistinct':
|
|
203
|
+
return new Set(values.filter(value => value != null)).size;
|
|
177
204
|
case 'avg':
|
|
178
205
|
return values.length === 0
|
|
179
206
|
? 0
|