@mastra/duckdb 1.2.0 → 1.3.0-alpha.1
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/CHANGELOG.md +56 -0
- package/dist/docs/SKILL.md +2 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-storage-duckdb.md +150 -0
- package/dist/index.cjs +13 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/{observability-AILZGFQT.cjs → observability-2PJ44OVC.cjs} +307 -33
- package/dist/observability-2PJ44OVC.cjs.map +1 -0
- package/dist/{observability-YJBOVLPV.js → observability-7LL4LLXY.js} +308 -34
- package/dist/observability-7LL4LLXY.js.map +1 -0
- package/dist/storage/domains/observability/index.d.ts +4 -1
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/metrics.d.ts.map +1 -1
- package/dist/storage/domains/observability/scores.d.ts +2 -1
- package/dist/storage/domains/observability/scores.d.ts.map +1 -1
- package/dist/storage/domains/observability/tracing.d.ts +41 -2
- package/dist/storage/domains/observability/tracing.d.ts.map +1 -1
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +9 -9
- package/dist/observability-AILZGFQT.cjs.map +0 -1
- package/dist/observability-YJBOVLPV.js.map +0 -1
|
@@ -1188,7 +1188,16 @@ async function listLogs(db, args) {
|
|
|
1188
1188
|
logs
|
|
1189
1189
|
};
|
|
1190
1190
|
}
|
|
1191
|
-
function
|
|
1191
|
+
function resolveDistinctColumnSql(distinctColumn) {
|
|
1192
|
+
if (!distinctColumn) {
|
|
1193
|
+
throw new Error(`count_distinct aggregation requires a 'distinctColumn' argument`);
|
|
1194
|
+
}
|
|
1195
|
+
if (!storage.METRIC_DISTINCT_COLUMNS.includes(distinctColumn)) {
|
|
1196
|
+
throw new Error(`Invalid distinctColumn: ${distinctColumn}`);
|
|
1197
|
+
}
|
|
1198
|
+
return utils.parseFieldKey(distinctColumn);
|
|
1199
|
+
}
|
|
1200
|
+
function getAggregationSql2(aggregation, measure = "value", distinctColumn) {
|
|
1192
1201
|
switch (aggregation) {
|
|
1193
1202
|
case "sum":
|
|
1194
1203
|
return `SUM(${measure})`;
|
|
@@ -1200,6 +1209,9 @@ function getAggregationSql2(aggregation, measure = "value") {
|
|
|
1200
1209
|
return `MAX(${measure})`;
|
|
1201
1210
|
case "count":
|
|
1202
1211
|
return `CAST(COUNT(${measure}) AS DOUBLE)`;
|
|
1212
|
+
case "count_distinct": {
|
|
1213
|
+
return `CAST(approx_count_distinct(${resolveDistinctColumnSql(distinctColumn)}) AS DOUBLE)`;
|
|
1214
|
+
}
|
|
1203
1215
|
case "last":
|
|
1204
1216
|
return `arg_max(${measure}, timestamp)`;
|
|
1205
1217
|
default:
|
|
@@ -1445,7 +1457,7 @@ async function listMetrics(db, args) {
|
|
|
1445
1457
|
};
|
|
1446
1458
|
}
|
|
1447
1459
|
async function getMetricAggregate(db, args) {
|
|
1448
|
-
const aggSql = getAggregationSql2(args.aggregation);
|
|
1460
|
+
const aggSql = getAggregationSql2(args.aggregation, "value", args.distinctColumn);
|
|
1449
1461
|
const { clause: nameClause, params: nameParams } = buildMetricNameFilter(args.name);
|
|
1450
1462
|
const { clause: filterClause, params: filterParams } = buildWhereClause(
|
|
1451
1463
|
args.filters
|
|
@@ -1529,7 +1541,7 @@ async function getMetricAggregate(db, args) {
|
|
|
1529
1541
|
return { value, estimatedCost: costSummary.estimatedCost, costUnit: costSummary.costUnit };
|
|
1530
1542
|
}
|
|
1531
1543
|
async function getMetricBreakdown(db, args) {
|
|
1532
|
-
const aggSql = getAggregationSql2(args.aggregation);
|
|
1544
|
+
const aggSql = getAggregationSql2(args.aggregation, "value", args.distinctColumn);
|
|
1533
1545
|
const { clause: nameClause, params: nameParams } = buildMetricNameFilter(args.name);
|
|
1534
1546
|
const { clause: filterClause, params: filterParams } = buildWhereClause(
|
|
1535
1547
|
args.filters
|
|
@@ -1543,8 +1555,11 @@ async function getMetricBreakdown(db, args) {
|
|
|
1543
1555
|
const resolvedGroupBy = resolveGroupBy(args.groupBy);
|
|
1544
1556
|
const selectGroupBy = resolvedGroupBy.map((entry) => entry.selectSql).join(", ");
|
|
1545
1557
|
const groupByCols = resolvedGroupBy.map((entry) => entry.groupSql).join(", ");
|
|
1546
|
-
const
|
|
1547
|
-
const
|
|
1558
|
+
const orderDirection = args.orderDirection === "ASC" ? "ASC" : "DESC";
|
|
1559
|
+
const limitClause = typeof args.limit === "number" ? `LIMIT ?` : "";
|
|
1560
|
+
const limitParams = typeof args.limit === "number" ? [args.limit] : [];
|
|
1561
|
+
const sql = `SELECT ${selectGroupBy}, ${aggSql} AS value, ${getCostSummarySelect()} FROM metric_events ${whereClause} GROUP BY ${groupByCols} ORDER BY value ${orderDirection} ${limitClause}`;
|
|
1562
|
+
const rows = await db.query(sql, [...allParams, ...limitParams]);
|
|
1548
1563
|
const groups = rows.map((row) => {
|
|
1549
1564
|
const dimensions = {};
|
|
1550
1565
|
for (const entry of resolvedGroupBy) {
|
|
@@ -1562,7 +1577,7 @@ async function getMetricBreakdown(db, args) {
|
|
|
1562
1577
|
return { groups };
|
|
1563
1578
|
}
|
|
1564
1579
|
async function getMetricTimeSeries(db, args) {
|
|
1565
|
-
const aggSql = getAggregationSql2(args.aggregation);
|
|
1580
|
+
const aggSql = getAggregationSql2(args.aggregation, "value", args.distinctColumn);
|
|
1566
1581
|
const intervalSql = getIntervalSql2(args.interval);
|
|
1567
1582
|
const { clause: nameClause, params: nameParams } = buildMetricNameFilter(args.name);
|
|
1568
1583
|
const { clause: filterClause, params: filterParams } = buildWhereClause(
|
|
@@ -2146,6 +2161,12 @@ async function listScores(db, args) {
|
|
|
2146
2161
|
scores: rows.map((row) => rowToScoreRecord(row))
|
|
2147
2162
|
};
|
|
2148
2163
|
}
|
|
2164
|
+
async function getScoreById(db, scoreId) {
|
|
2165
|
+
const rows = await db.query(`SELECT * FROM score_events WHERE scoreId = ? LIMIT 1`, [
|
|
2166
|
+
scoreId
|
|
2167
|
+
]);
|
|
2168
|
+
return rows[0] ? rowToScoreRecord(rows[0]) : null;
|
|
2169
|
+
}
|
|
2149
2170
|
async function getScoreAggregate(db, args) {
|
|
2150
2171
|
const aggSql = getAggregationSql3(args.aggregation);
|
|
2151
2172
|
const { clause, params } = buildScoreWhereClause(args);
|
|
@@ -2415,11 +2436,91 @@ function rowToSpanRecord(row) {
|
|
|
2415
2436
|
updatedAt: null
|
|
2416
2437
|
};
|
|
2417
2438
|
}
|
|
2418
|
-
function buildHasChildErrorClause(hasChildError) {
|
|
2439
|
+
function buildHasChildErrorClause(hasChildError, rootAlias) {
|
|
2419
2440
|
if (hasChildError === void 0) return "";
|
|
2420
|
-
const base = `SELECT 1 FROM
|
|
2441
|
+
const base = `SELECT 1 FROM span_events c WHERE c.traceId = ${rootAlias}.traceId AND c.spanId != ${rootAlias}.spanId AND c.error IS NOT NULL`;
|
|
2421
2442
|
return hasChildError ? `EXISTS (${base})` : `NOT EXISTS (${base})`;
|
|
2422
2443
|
}
|
|
2444
|
+
var PREFILTER_KEYS = /* @__PURE__ */ new Set([
|
|
2445
|
+
"traceId",
|
|
2446
|
+
"spanId",
|
|
2447
|
+
"parentSpanId",
|
|
2448
|
+
"name",
|
|
2449
|
+
"spanType",
|
|
2450
|
+
"source",
|
|
2451
|
+
"entityType",
|
|
2452
|
+
"entityId",
|
|
2453
|
+
"entityName",
|
|
2454
|
+
"entityVersionId",
|
|
2455
|
+
"experimentId",
|
|
2456
|
+
"userId",
|
|
2457
|
+
"organizationId",
|
|
2458
|
+
"resourceId",
|
|
2459
|
+
"runId",
|
|
2460
|
+
"sessionId",
|
|
2461
|
+
"threadId",
|
|
2462
|
+
"requestId",
|
|
2463
|
+
"environment",
|
|
2464
|
+
"serviceName"
|
|
2465
|
+
]);
|
|
2466
|
+
var SAFE_PREFILTER_ORDER_FIELDS = /* @__PURE__ */ new Set(["startedAt"]);
|
|
2467
|
+
function intersectTimestampRange(existing, incoming) {
|
|
2468
|
+
if (!existing) return { ...incoming };
|
|
2469
|
+
const merged = { ...existing };
|
|
2470
|
+
if (incoming.start !== void 0) {
|
|
2471
|
+
if (merged.start === void 0 || incoming.start.getTime() > merged.start.getTime()) {
|
|
2472
|
+
merged.start = incoming.start;
|
|
2473
|
+
merged.startExclusive = incoming.startExclusive;
|
|
2474
|
+
} else if (incoming.start.getTime() === merged.start.getTime()) {
|
|
2475
|
+
merged.startExclusive = (merged.startExclusive ?? false) || (incoming.startExclusive ?? false);
|
|
2476
|
+
}
|
|
2477
|
+
}
|
|
2478
|
+
if (incoming.end !== void 0) {
|
|
2479
|
+
if (merged.end === void 0 || incoming.end.getTime() < merged.end.getTime()) {
|
|
2480
|
+
merged.end = incoming.end;
|
|
2481
|
+
merged.endExclusive = incoming.endExclusive;
|
|
2482
|
+
} else if (incoming.end.getTime() === merged.end.getTime()) {
|
|
2483
|
+
merged.endExclusive = (merged.endExclusive ?? false) || (incoming.endExclusive ?? false);
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
return merged;
|
|
2487
|
+
}
|
|
2488
|
+
function partitionAnchorFilters(filters) {
|
|
2489
|
+
const prefilter = {};
|
|
2490
|
+
const postAgg = {};
|
|
2491
|
+
let hasChildError;
|
|
2492
|
+
for (const [key, value] of Object.entries(filters)) {
|
|
2493
|
+
if (value === void 0 || value === null) continue;
|
|
2494
|
+
if (key === "hasChildError") {
|
|
2495
|
+
if (typeof value === "boolean") hasChildError = value;
|
|
2496
|
+
continue;
|
|
2497
|
+
}
|
|
2498
|
+
if (key === "startedAt") {
|
|
2499
|
+
prefilter.timestamp = intersectTimestampRange(
|
|
2500
|
+
prefilter.timestamp,
|
|
2501
|
+
value
|
|
2502
|
+
);
|
|
2503
|
+
continue;
|
|
2504
|
+
}
|
|
2505
|
+
if (key === "endedAt") {
|
|
2506
|
+
postAgg.endedAt = value;
|
|
2507
|
+
const dateRange = value;
|
|
2508
|
+
if (dateRange?.end) {
|
|
2509
|
+
prefilter.timestamp = intersectTimestampRange(prefilter.timestamp, {
|
|
2510
|
+
end: dateRange.end,
|
|
2511
|
+
endExclusive: dateRange.endExclusive
|
|
2512
|
+
});
|
|
2513
|
+
}
|
|
2514
|
+
continue;
|
|
2515
|
+
}
|
|
2516
|
+
if (PREFILTER_KEYS.has(key)) {
|
|
2517
|
+
prefilter[key] = value;
|
|
2518
|
+
continue;
|
|
2519
|
+
}
|
|
2520
|
+
postAgg[key] = value;
|
|
2521
|
+
}
|
|
2522
|
+
return { prefilter, postAgg, hasChildError };
|
|
2523
|
+
}
|
|
2423
2524
|
function toValuesTuple(row) {
|
|
2424
2525
|
return [
|
|
2425
2526
|
v(row.eventType),
|
|
@@ -2598,47 +2699,211 @@ async function listTraces(db, args) {
|
|
|
2598
2699
|
const page = Number(args.pagination?.page ?? 0);
|
|
2599
2700
|
const perPage = Number(args.pagination?.perPage ?? 10);
|
|
2600
2701
|
const orderBy = { field: args.orderBy?.field ?? "startedAt", direction: args.orderBy?.direction ?? "DESC" };
|
|
2601
|
-
const {
|
|
2602
|
-
const
|
|
2603
|
-
const
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
const
|
|
2607
|
-
const
|
|
2608
|
-
if (
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2702
|
+
const { prefilter, postAgg, hasChildError } = partitionAnchorFilters(filters);
|
|
2703
|
+
const { clause: prefilterClause, params: prefilterParams } = buildWhereClause(prefilter);
|
|
2704
|
+
const prefilterParts = [`eventType = 'start'`, `parentSpanId IS NULL`];
|
|
2705
|
+
if (prefilterClause) prefilterParts.push(prefilterClause.replace(/^WHERE\s+/i, ""));
|
|
2706
|
+
const prefilterWhere = `WHERE ${prefilterParts.join(" AND ")}`;
|
|
2707
|
+
const outerAlias = "outer_root";
|
|
2708
|
+
const orderDir = orderBy.direction.toUpperCase();
|
|
2709
|
+
if (orderDir !== "ASC" && orderDir !== "DESC") {
|
|
2710
|
+
throw new Error(`Invalid sort direction: ${orderBy.direction}`);
|
|
2711
|
+
}
|
|
2712
|
+
const canOrderInPrefilter = SAFE_PREFILTER_ORDER_FIELDS.has(orderBy.field);
|
|
2713
|
+
const hasPostAggFilters = Object.keys(postAgg).length > 0 || hasChildError !== void 0 || !canOrderInPrefilter;
|
|
2714
|
+
if (!hasPostAggFilters) {
|
|
2715
|
+
const prefilterOrderBy = `ORDER BY timestamp ${orderDir}`;
|
|
2716
|
+
const offset = page * perPage;
|
|
2717
|
+
const countSql2 = `
|
|
2718
|
+
SELECT COUNT(*) as total
|
|
2719
|
+
FROM span_events AS ${outerAlias}
|
|
2720
|
+
${prefilterWhere}
|
|
2721
|
+
`;
|
|
2722
|
+
const countResult2 = await db.query(countSql2, prefilterParams);
|
|
2723
|
+
const total2 = Number(countResult2[0]?.total ?? 0);
|
|
2724
|
+
const pageSql = `
|
|
2725
|
+
WITH page_roots AS (
|
|
2726
|
+
SELECT traceId, spanId
|
|
2727
|
+
FROM span_events AS ${outerAlias}
|
|
2728
|
+
${prefilterWhere}
|
|
2729
|
+
${prefilterOrderBy}
|
|
2730
|
+
LIMIT ? OFFSET ?
|
|
2731
|
+
)
|
|
2612
2732
|
${SPAN_RECONSTRUCT_SELECT}
|
|
2733
|
+
WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM page_roots)
|
|
2613
2734
|
GROUP BY traceId, spanId
|
|
2735
|
+
${buildOrderByClause(orderBy)}
|
|
2736
|
+
`;
|
|
2737
|
+
const rows2 = await db.query(pageSql, [...prefilterParams, perPage, offset]);
|
|
2738
|
+
const spans2 = rows2.map((row) => rowToSpanRecord(row));
|
|
2739
|
+
return {
|
|
2740
|
+
pagination: { total: total2, page, perPage, hasMore: (page + 1) * perPage < total2 },
|
|
2741
|
+
spans: storage.toTraceSpans(spans2)
|
|
2742
|
+
};
|
|
2743
|
+
}
|
|
2744
|
+
const { clause: postAggClause, params: postAggParams } = buildWhereClause(postAgg);
|
|
2745
|
+
const postAggParts = [];
|
|
2746
|
+
if (postAggClause) postAggParts.push(postAggClause.replace(/^WHERE\s+/i, ""));
|
|
2747
|
+
const childErrorClause = buildHasChildErrorClause(hasChildError, "root_spans");
|
|
2748
|
+
if (childErrorClause) postAggParts.push(childErrorClause);
|
|
2749
|
+
const postAggWhere = postAggParts.length > 0 ? `WHERE ${postAggParts.join(" AND ")}` : "";
|
|
2750
|
+
const cteSql = `
|
|
2751
|
+
WITH candidate_roots AS (
|
|
2752
|
+
SELECT traceId, spanId
|
|
2753
|
+
FROM span_events AS ${outerAlias}
|
|
2754
|
+
${prefilterWhere}
|
|
2614
2755
|
),
|
|
2615
2756
|
root_spans AS (
|
|
2616
|
-
|
|
2617
|
-
WHERE
|
|
2757
|
+
${SPAN_RECONSTRUCT_SELECT}
|
|
2758
|
+
WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM candidate_roots)
|
|
2759
|
+
GROUP BY traceId, spanId
|
|
2618
2760
|
)
|
|
2619
2761
|
`;
|
|
2762
|
+
const orderByClause = buildOrderByClause(orderBy);
|
|
2763
|
+
const { clause: paginationClause, params: paginationParams } = buildPaginationClause({ page, perPage });
|
|
2620
2764
|
const countSql = `
|
|
2621
2765
|
${cteSql}
|
|
2622
|
-
SELECT COUNT(*) as total FROM root_spans ${
|
|
2766
|
+
SELECT COUNT(*) as total FROM root_spans ${postAggWhere}
|
|
2623
2767
|
`;
|
|
2624
|
-
const countResult = await db.query(countSql,
|
|
2768
|
+
const countResult = await db.query(countSql, [...prefilterParams, ...postAggParams]);
|
|
2625
2769
|
const total = Number(countResult[0]?.total ?? 0);
|
|
2626
2770
|
const dataSql = `
|
|
2627
2771
|
${cteSql}
|
|
2628
|
-
SELECT * FROM root_spans ${
|
|
2772
|
+
SELECT * FROM root_spans ${postAggWhere} ${orderByClause} ${paginationClause}
|
|
2629
2773
|
`;
|
|
2630
|
-
const rows = await db.query(dataSql, [...
|
|
2774
|
+
const rows = await db.query(dataSql, [...prefilterParams, ...postAggParams, ...paginationParams]);
|
|
2631
2775
|
const spans = rows.map((row) => rowToSpanRecord(row));
|
|
2632
2776
|
return {
|
|
2633
|
-
pagination: {
|
|
2634
|
-
total,
|
|
2635
|
-
page,
|
|
2636
|
-
perPage,
|
|
2637
|
-
hasMore: (page + 1) * perPage < total
|
|
2638
|
-
},
|
|
2777
|
+
pagination: { total, page, perPage, hasMore: (page + 1) * perPage < total },
|
|
2639
2778
|
spans: storage.toTraceSpans(spans)
|
|
2640
2779
|
};
|
|
2641
2780
|
}
|
|
2781
|
+
var BRANCH_SPAN_TYPE_PLACEHOLDERS = storage.BRANCH_SPAN_TYPES.map(() => "?").join(", ");
|
|
2782
|
+
async function getSpans(db, args) {
|
|
2783
|
+
if (args.spanIds.length === 0) {
|
|
2784
|
+
return { traceId: args.traceId, spans: [] };
|
|
2785
|
+
}
|
|
2786
|
+
const placeholders = args.spanIds.map(() => "?").join(", ");
|
|
2787
|
+
const rows = await db.query(
|
|
2788
|
+
`${SPAN_RECONSTRUCT_SELECT}
|
|
2789
|
+
WHERE traceId = ? AND spanId IN (${placeholders})
|
|
2790
|
+
GROUP BY traceId, spanId`,
|
|
2791
|
+
[args.traceId, ...args.spanIds]
|
|
2792
|
+
);
|
|
2793
|
+
return {
|
|
2794
|
+
traceId: args.traceId,
|
|
2795
|
+
spans: rows.map((row) => rowToSpanRecord(row))
|
|
2796
|
+
};
|
|
2797
|
+
}
|
|
2798
|
+
async function listBranches(db, args) {
|
|
2799
|
+
const filters = args.filters ?? {};
|
|
2800
|
+
const page = Number(args.pagination?.page ?? 0);
|
|
2801
|
+
const perPage = Number(args.pagination?.perPage ?? 10);
|
|
2802
|
+
const orderBy = { field: args.orderBy?.field ?? "startedAt", direction: args.orderBy?.direction ?? "DESC" };
|
|
2803
|
+
const userSpanType = filters.spanType;
|
|
2804
|
+
if (typeof userSpanType === "string" && !storage.BRANCH_SPAN_TYPES.includes(userSpanType)) {
|
|
2805
|
+
return {
|
|
2806
|
+
pagination: { total: 0, page, perPage, hasMore: false },
|
|
2807
|
+
branches: []
|
|
2808
|
+
};
|
|
2809
|
+
}
|
|
2810
|
+
const { spanType: _spanType, ...rest } = filters;
|
|
2811
|
+
const { prefilter, postAgg} = partitionAnchorFilters(rest);
|
|
2812
|
+
const { clause: prefilterClause, params: prefilterFilterParams } = buildWhereClause(prefilter);
|
|
2813
|
+
const prefilterParts = [`eventType = 'start'`];
|
|
2814
|
+
let spanTypeParams;
|
|
2815
|
+
if (typeof userSpanType === "string") {
|
|
2816
|
+
prefilterParts.push(`spanType = ?`);
|
|
2817
|
+
spanTypeParams = [userSpanType];
|
|
2818
|
+
} else {
|
|
2819
|
+
prefilterParts.push(`spanType IN (${BRANCH_SPAN_TYPE_PLACEHOLDERS})`);
|
|
2820
|
+
spanTypeParams = [...storage.BRANCH_SPAN_TYPES];
|
|
2821
|
+
}
|
|
2822
|
+
if (prefilterClause) prefilterParts.push(prefilterClause.replace(/^WHERE\s+/i, ""));
|
|
2823
|
+
const prefilterWhere = `WHERE ${prefilterParts.join(" AND ")}`;
|
|
2824
|
+
const prefilterParams = [...spanTypeParams, ...prefilterFilterParams];
|
|
2825
|
+
const outerAlias = "outer_anchor";
|
|
2826
|
+
const orderDir = orderBy.direction.toUpperCase();
|
|
2827
|
+
if (orderDir !== "ASC" && orderDir !== "DESC") {
|
|
2828
|
+
throw new Error(`Invalid sort direction: ${orderBy.direction}`);
|
|
2829
|
+
}
|
|
2830
|
+
const canOrderInPrefilter = SAFE_PREFILTER_ORDER_FIELDS.has(orderBy.field);
|
|
2831
|
+
const hasPostAggFilters = Object.keys(postAgg).length > 0 || !canOrderInPrefilter;
|
|
2832
|
+
if (!hasPostAggFilters) {
|
|
2833
|
+
const prefilterOrderBy = `ORDER BY timestamp ${orderDir}`;
|
|
2834
|
+
const offset = page * perPage;
|
|
2835
|
+
const countSql2 = `
|
|
2836
|
+
SELECT COUNT(*) as total
|
|
2837
|
+
FROM span_events AS ${outerAlias}
|
|
2838
|
+
${prefilterWhere}
|
|
2839
|
+
`;
|
|
2840
|
+
const countResult2 = await db.query(countSql2, prefilterParams);
|
|
2841
|
+
const total2 = Number(countResult2[0]?.total ?? 0);
|
|
2842
|
+
if (total2 === 0) {
|
|
2843
|
+
return {
|
|
2844
|
+
pagination: { total: 0, page, perPage, hasMore: false },
|
|
2845
|
+
branches: []
|
|
2846
|
+
};
|
|
2847
|
+
}
|
|
2848
|
+
const pageSql = `
|
|
2849
|
+
WITH page_anchors AS (
|
|
2850
|
+
SELECT traceId, spanId
|
|
2851
|
+
FROM span_events AS ${outerAlias}
|
|
2852
|
+
${prefilterWhere}
|
|
2853
|
+
${prefilterOrderBy}
|
|
2854
|
+
LIMIT ? OFFSET ?
|
|
2855
|
+
)
|
|
2856
|
+
${SPAN_RECONSTRUCT_SELECT}
|
|
2857
|
+
WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM page_anchors)
|
|
2858
|
+
GROUP BY traceId, spanId
|
|
2859
|
+
${buildOrderByClause(orderBy)}
|
|
2860
|
+
`;
|
|
2861
|
+
const rows2 = await db.query(pageSql, [...prefilterParams, perPage, offset]);
|
|
2862
|
+
const spans2 = rows2.map((row) => rowToSpanRecord(row));
|
|
2863
|
+
return {
|
|
2864
|
+
pagination: { total: total2, page, perPage, hasMore: (page + 1) * perPage < total2 },
|
|
2865
|
+
branches: storage.toTraceSpans(spans2)
|
|
2866
|
+
};
|
|
2867
|
+
}
|
|
2868
|
+
const { clause: postAggClause, params: postAggParams } = buildWhereClause(postAgg);
|
|
2869
|
+
const postAggWhere = postAggClause ? postAggClause : "";
|
|
2870
|
+
const orderByClause = buildOrderByClause(orderBy);
|
|
2871
|
+
const { clause: paginationClause, params: paginationParams } = buildPaginationClause({ page, perPage });
|
|
2872
|
+
const cteSql = `
|
|
2873
|
+
WITH candidate_anchors AS (
|
|
2874
|
+
SELECT traceId, spanId
|
|
2875
|
+
FROM span_events AS ${outerAlias}
|
|
2876
|
+
${prefilterWhere}
|
|
2877
|
+
),
|
|
2878
|
+
branch_anchors AS (
|
|
2879
|
+
${SPAN_RECONSTRUCT_SELECT}
|
|
2880
|
+
WHERE (traceId, spanId) IN (SELECT traceId, spanId FROM candidate_anchors)
|
|
2881
|
+
GROUP BY traceId, spanId
|
|
2882
|
+
)
|
|
2883
|
+
`;
|
|
2884
|
+
const countSql = `
|
|
2885
|
+
${cteSql}
|
|
2886
|
+
SELECT COUNT(*) as total FROM branch_anchors ${postAggWhere}
|
|
2887
|
+
`;
|
|
2888
|
+
const countResult = await db.query(countSql, [...prefilterParams, ...postAggParams]);
|
|
2889
|
+
const total = Number(countResult[0]?.total ?? 0);
|
|
2890
|
+
if (total === 0) {
|
|
2891
|
+
return {
|
|
2892
|
+
pagination: { total: 0, page, perPage, hasMore: false },
|
|
2893
|
+
branches: []
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2896
|
+
const dataSql = `
|
|
2897
|
+
${cteSql}
|
|
2898
|
+
SELECT * FROM branch_anchors ${postAggWhere} ${orderByClause} ${paginationClause}
|
|
2899
|
+
`;
|
|
2900
|
+
const rows = await db.query(dataSql, [...prefilterParams, ...postAggParams, ...paginationParams]);
|
|
2901
|
+
const spans = rows.map((row) => rowToSpanRecord(row));
|
|
2902
|
+
return {
|
|
2903
|
+
pagination: { total, page, perPage, hasMore: (page + 1) * perPage < total },
|
|
2904
|
+
branches: storage.toTraceSpans(spans)
|
|
2905
|
+
};
|
|
2906
|
+
}
|
|
2642
2907
|
|
|
2643
2908
|
// src/storage/domains/observability/index.ts
|
|
2644
2909
|
function buildSignalMigrationRequiredMessage(args) {
|
|
@@ -2741,6 +3006,9 @@ var ObservabilityStorageDuckDB = class extends storage.ObservabilityStorage {
|
|
|
2741
3006
|
async getSpan(args) {
|
|
2742
3007
|
return getSpan(this.db, args);
|
|
2743
3008
|
}
|
|
3009
|
+
async getSpans(args) {
|
|
3010
|
+
return getSpans(this.db, args);
|
|
3011
|
+
}
|
|
2744
3012
|
async getRootSpan(args) {
|
|
2745
3013
|
return getRootSpan(this.db, args);
|
|
2746
3014
|
}
|
|
@@ -2753,6 +3021,9 @@ var ObservabilityStorageDuckDB = class extends storage.ObservabilityStorage {
|
|
|
2753
3021
|
async listTraces(args) {
|
|
2754
3022
|
return listTraces(this.db, args);
|
|
2755
3023
|
}
|
|
3024
|
+
async listBranches(args) {
|
|
3025
|
+
return listBranches(this.db, args);
|
|
3026
|
+
}
|
|
2756
3027
|
// Logs
|
|
2757
3028
|
async batchCreateLogs(args) {
|
|
2758
3029
|
return batchCreateLogs(this.db, args);
|
|
@@ -2815,6 +3086,9 @@ var ObservabilityStorageDuckDB = class extends storage.ObservabilityStorage {
|
|
|
2815
3086
|
async listScores(args) {
|
|
2816
3087
|
return listScores(this.db, args);
|
|
2817
3088
|
}
|
|
3089
|
+
async getScoreById(scoreId) {
|
|
3090
|
+
return getScoreById(this.db, scoreId);
|
|
3091
|
+
}
|
|
2818
3092
|
async getScoreAggregate(args) {
|
|
2819
3093
|
return getScoreAggregate(this.db, args);
|
|
2820
3094
|
}
|
|
@@ -2852,5 +3126,5 @@ var ObservabilityStorageDuckDB = class extends storage.ObservabilityStorage {
|
|
|
2852
3126
|
};
|
|
2853
3127
|
|
|
2854
3128
|
exports.ObservabilityStorageDuckDB = ObservabilityStorageDuckDB;
|
|
2855
|
-
//# sourceMappingURL=observability-
|
|
2856
|
-
//# sourceMappingURL=observability-
|
|
3129
|
+
//# sourceMappingURL=observability-2PJ44OVC.cjs.map
|
|
3130
|
+
//# sourceMappingURL=observability-2PJ44OVC.cjs.map
|