@mastra/duckdb 1.15.0 → 1.16.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/docs/SKILL.md +1 -1
  2. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  3. package/dist/{features-CFAYHYYE.cjs → features-CEjjQRE6.cjs} +8 -1
  4. package/dist/{features-CFAYHYYE.cjs.map → features-CEjjQRE6.cjs.map} +1 -1
  5. package/dist/{features-BI3qUHJ7.js → features-uOeZunqR.js} +3 -2
  6. package/dist/{features-BI3qUHJ7.js.map → features-uOeZunqR.js.map} +1 -1
  7. package/dist/index.cjs +5 -2
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.js +5 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/{observability-642joQI8.js → observability-Bv3eObB-.js} +173 -48
  12. package/dist/observability-Bv3eObB-.js.map +1 -0
  13. package/dist/{observability-C9FRo6K3.cjs → observability-DCB8fs52.cjs} +173 -48
  14. package/dist/observability-DCB8fs52.cjs.map +1 -0
  15. package/dist/storage/domains/observability/ddl.d.ts +1 -1
  16. package/dist/storage/domains/observability/ddl.d.ts.map +1 -1
  17. package/dist/storage/domains/observability/index.d.ts +3 -2
  18. package/dist/storage/domains/observability/index.d.ts.map +1 -1
  19. package/dist/storage/domains/observability/span-query.d.ts +8 -0
  20. package/dist/storage/domains/observability/span-query.d.ts.map +1 -1
  21. package/dist/storage/domains/observability/trace-aggregate.d.ts +7 -1
  22. package/dist/storage/domains/observability/trace-aggregate.d.ts.map +1 -1
  23. package/dist/storage/domains/observability/tracing.d.ts.map +1 -1
  24. package/dist/storage/features.d.ts +1 -0
  25. package/dist/storage/features.d.ts.map +1 -1
  26. package/dist/storage/index.d.ts +1 -0
  27. package/dist/storage/index.d.ts.map +1 -1
  28. package/package.json +6 -6
  29. package/dist/observability-642joQI8.js.map +0 -1
  30. package/dist/observability-C9FRo6K3.cjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { a as DuckDBConnection, i as timeToFirstChunkSupported, o as DuckDBQueryTimeoutError, r as timeToFirstChunkFeatures, t as spanQueryFeatures } from "./features-BI3qUHJ7.js";
1
+ import { a as timeToFirstChunkSupported, i as timeToFirstChunkFeatures, n as spanQueryFeatures, o as DuckDBConnection, s as DuckDBQueryTimeoutError, t as spanAggregateFeatures } from "./features-uOeZunqR.js";
2
2
  import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
3
3
  import * as coreStorage from "@mastra/core/storage";
4
4
  import { BRANCH_SPAN_TYPES, METRIC_DISTINCT_COLUMNS, ObservabilityStorage, computeTraceStatus, createStorageErrorId, executeRetentionPrune, feedbackRecordSchema, listBranchesArgsSchema, listFeedbackArgsSchema, listLogsArgsSchema, listMetricsArgsSchema, listScoresArgsSchema, listTracesArgsSchema, resolveRetentionTargets, retentionCutoffMs, toTraceSpans } from "@mastra/core/storage";
@@ -80,6 +80,12 @@ CREATE TABLE IF NOT EXISTS span_events (
80
80
  entityVersionId VARCHAR,
81
81
  parentEntityVersionId VARCHAR,
82
82
  rootEntityVersionId VARCHAR,
83
+ parentEntityType VARCHAR,
84
+ parentEntityId VARCHAR,
85
+ parentEntityName VARCHAR,
86
+ rootEntityType VARCHAR,
87
+ rootEntityId VARCHAR,
88
+ rootEntityName VARCHAR,
83
89
 
84
90
  -- Context
85
91
  userId VARCHAR,
@@ -372,6 +378,12 @@ const ALL_MIGRATIONS = [
372
378
  `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS hasOutputPayload BOOLEAN`,
373
379
  `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS hasErrorPayload BOOLEAN`,
374
380
  `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS timeToFirstChunkMs DOUBLE`,
381
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS parentEntityType VARCHAR`,
382
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS parentEntityId VARCHAR`,
383
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS parentEntityName VARCHAR`,
384
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS rootEntityType VARCHAR`,
385
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS rootEntityId VARCHAR`,
386
+ `ALTER TABLE span_events ADD COLUMN IF NOT EXISTS rootEntityName VARCHAR`,
375
387
  `ALTER TABLE metric_events ADD COLUMN IF NOT EXISTS cursorId BIGINT`,
376
388
  `ALTER TABLE metric_events ADD COLUMN IF NOT EXISTS entityVersionId VARCHAR`,
377
389
  `ALTER TABLE metric_events ADD COLUMN IF NOT EXISTS parentEntityVersionId VARCHAR`,
@@ -3956,15 +3968,8 @@ const identityFields = [
3956
3968
  "traceId",
3957
3969
  "spanId"
3958
3970
  ];
3959
- const missingFields = /* @__PURE__ */ new Set([
3960
- "parentEntityType",
3961
- "parentEntityId",
3962
- "parentEntityName",
3963
- "rootEntityType",
3964
- "rootEntityId",
3965
- "rootEntityName",
3966
- "executionSource"
3967
- ]);
3971
+ /** Span rows store the execution source as `source`. */
3972
+ const columnSql = (field) => field === "executionSource" ? "e.source AS executionSource" : `e.${field}`;
3968
3973
  const identities = identityFields.join(", ");
3969
3974
  const fields = [
3970
3975
  ...identityFields,
@@ -4028,7 +4033,11 @@ function afterCursor(plan) {
4028
4033
  values
4029
4034
  };
4030
4035
  }
4031
- function compileDuckDBSpanQuery(plan) {
4036
+ /**
4037
+ * The spans `querySpans()` selects, as CTEs ending in `selected`: the current completed copy of
4038
+ * each span that started in the window and matches `where`. Values are in placeholder order.
4039
+ */
4040
+ function compileDuckDBSpanSelection(plan) {
4032
4041
  const values = [plan.timeRange.from, plan.timeRange.to];
4033
4042
  const scope = [];
4034
4043
  if (plan.scope) {
@@ -4043,28 +4052,44 @@ function compileDuckDBSpanQuery(plan) {
4043
4052
  sql: "TRUE",
4044
4053
  values: []
4045
4054
  };
4046
- const after = afterCursor(plan);
4047
- values.push(plan.timeRange.from, plan.timeRange.to, ...predicate.values, ...after.values, plan.limit + 1);
4055
+ values.push(plan.timeRange.from, plan.timeRange.to, ...predicate.values);
4048
4056
  const join = identityFields.map((field) => `e.${field} IS NOT DISTINCT FROM c.${field}`).join(" AND ");
4057
+ const partition = identityFields.map((field) => `e.${field}`).join(", ");
4049
4058
  const legacyModelFields = coreStorage.SPAN_QUERY_FIELD_REGISTRY ? "" : `CASE WHEN json_type(e.attributes, '$.model') = 'VARCHAR' THEN json_extract_string(e.attributes, '$.model') END AS model,
4050
4059
  CASE WHEN json_type(e.attributes, '$.provider') = 'VARCHAR' THEN json_extract_string(e.attributes, '$.provider') END AS provider,`;
4051
4060
  return {
4052
- sql: `WITH candidates AS MATERIALIZED (
4061
+ ctes: [
4062
+ `candidates AS MATERIALIZED (
4053
4063
  SELECT ${identities} FROM span_events
4054
4064
  WHERE eventType = 'start' AND timestamp >= CAST(? AS TIMESTAMP) AND timestamp < CAST(? AS TIMESTAMP)
4055
4065
  ${scope.length ? `AND ${scope.join(" AND ")}` : ""}
4056
4066
  GROUP BY ${identities}
4057
- ), ranked AS (
4058
- SELECT ${fields.map((field) => missingFields.has(field) ? `CAST(NULL AS VARCHAR) AS ${field}` : `e.${field}`).join(", ")},
4059
- min(e.timestamp) FILTER (WHERE e.eventType = 'start') OVER (PARTITION BY ${identityFields.map((field) => `e.${field}`).join(", ")}) AS startedAt, e.endedAt, e.cursorId,
4067
+ )`,
4068
+ `span_versions AS (
4069
+ SELECT ${fields.map(columnSql).join(", ")},
4070
+ min(e.timestamp) FILTER (WHERE e.eventType = 'start') OVER (PARTITION BY ${partition}) AS startedAt, e.endedAt, e.cursorId,
4060
4071
  ${legacyModelFields}
4061
- date_diff('millisecond', min(e.timestamp) FILTER (WHERE e.eventType = 'start') OVER (PARTITION BY ${identityFields.map((field) => `e.${field}`).join(", ")}), e.endedAt) AS durationMs,
4072
+ date_diff('millisecond', min(e.timestamp) FILTER (WHERE e.eventType = 'start') OVER (PARTITION BY ${partition}), e.endedAt) AS durationMs,
4062
4073
  CASE WHEN e.error IS NULL THEN 'success' ELSE 'error' END AS status,
4063
4074
  CASE WHEN e.error IS NULL THEN NULL ELSE 'error' END AS error,
4064
- row_number() OVER (PARTITION BY ${identityFields.map((field) => `e.${field}`).join(", ")}
4075
+ row_number() OVER (PARTITION BY ${partition}
4065
4076
  ORDER BY CASE WHEN e.endedAt IS NULL THEN 1 ELSE 0 END, e.cursorId DESC NULLS LAST, e.endedAt DESC) AS rank
4066
4077
  FROM span_events e INNER JOIN candidates c ON ${join}
4067
- )
4078
+ )`,
4079
+ `selected AS (
4080
+ SELECT * FROM span_versions s
4081
+ WHERE rank = 1 AND endedAt IS NOT NULL AND startedAt >= CAST(? AS TIMESTAMP) AND startedAt < CAST(? AS TIMESTAMP) AND (${predicate.sql})
4082
+ )`
4083
+ ],
4084
+ values
4085
+ };
4086
+ }
4087
+ function compileDuckDBSpanQuery(plan) {
4088
+ const { ctes, values } = compileDuckDBSpanSelection(plan);
4089
+ const after = afterCursor(plan);
4090
+ values.push(...after.values, plan.limit + 1);
4091
+ return {
4092
+ sql: `WITH ${ctes.join(", ")}
4068
4093
  SELECT ${[
4069
4094
  ...fields,
4070
4095
  "startedAt",
@@ -4073,7 +4098,7 @@ function compileDuckDBSpanQuery(plan) {
4073
4098
  "status",
4074
4099
  "cursorId"
4075
4100
  ].map((field) => `s.${field}`).join(", ")}
4076
- FROM ranked s WHERE rank = 1 AND endedAt IS NOT NULL AND startedAt >= CAST(? AS TIMESTAMP) AND startedAt < CAST(? AS TIMESTAMP) AND (${predicate.sql}) AND ${after.sql}
4101
+ FROM selected s WHERE ${after.sql}
4077
4102
  ORDER BY s.${plan.orderBy.field} ${plan.orderBy.direction === "asc" ? "ASC" : "DESC"} NULLS LAST, ${identityFields.map((field) => `s.${field} ASC NULLS LAST`).join(", ")}
4078
4103
  LIMIT ?`,
4079
4104
  values
@@ -4416,7 +4441,7 @@ const DIMENSION_SQL = {
4416
4441
  environment: "r.environment",
4417
4442
  status: TRACE_STATUS_SQL,
4418
4443
  serviceName: "r.serviceName",
4419
- executionSource: "r.executionSource",
4444
+ executionSource: "r.source",
4420
4445
  threadId: "r.threadId",
4421
4446
  resourceId: "r.resourceId",
4422
4447
  userId: "r.userId",
@@ -4424,6 +4449,28 @@ const DIMENSION_SQL = {
4424
4449
  organizationId: "r.organizationId",
4425
4450
  experimentId: "r.experimentId"
4426
4451
  };
4452
+ /** Span column expressions (alias `r`, a `selected` span row) for each groupable span dimension. */
4453
+ const SPAN_DIMENSION_SQL = Object.fromEntries([
4454
+ "name",
4455
+ "spanType",
4456
+ "entityType",
4457
+ "entityId",
4458
+ "entityName",
4459
+ "parentEntityType",
4460
+ "parentEntityName",
4461
+ "rootEntityType",
4462
+ "rootEntityName",
4463
+ "environment",
4464
+ "status",
4465
+ "serviceName",
4466
+ "executionSource",
4467
+ "threadId",
4468
+ "resourceId",
4469
+ "userId",
4470
+ "sessionId",
4471
+ "organizationId",
4472
+ "experimentId"
4473
+ ].map((field) => [field, `r.${field}`]));
4427
4474
  const PERCENTILES = {
4428
4475
  "duration.p50": .5,
4429
4476
  "duration.p90": .9,
@@ -4440,18 +4487,47 @@ const COMPARISON_SQL = {
4440
4487
  };
4441
4488
  function compileDuckDBTraceAggregate(plan, options = {}) {
4442
4489
  const { ctes, values } = compileDuckDBTraceCandidates(plan, "r.*");
4443
- const dimensionSql = (field) => {
4444
- if (field.startsWith("metadata.")) return {
4445
- sql: TRACE_METADATA_VALUE_SQL,
4446
- values: traceMetadataPathValues(field.slice(9))
4447
- };
4448
- const sql = Object.hasOwn(DIMENSION_SQL, field) ? DIMENSION_SQL[field] : void 0;
4449
- if (sql === void 0) throw new Error(`Unsupported trusted trace-aggregate field: ${field}`);
4450
- return {
4451
- sql,
4490
+ return compileDuckDBAggregate(plan, options, {
4491
+ ctes,
4492
+ values,
4493
+ from: "candidates",
4494
+ dimensionSql: (field) => {
4495
+ if (field.startsWith("metadata.")) return {
4496
+ sql: TRACE_METADATA_VALUE_SQL,
4497
+ values: traceMetadataPathValues(field.slice(9))
4498
+ };
4499
+ return {
4500
+ sql: lookupDimensionSql(DIMENSION_SQL, field),
4501
+ values: []
4502
+ };
4503
+ },
4504
+ usageKey: ["traceId"]
4505
+ });
4506
+ }
4507
+ /**
4508
+ * Compiles a trusted span aggregate plan over the spans `querySpans()` selects. Usage is
4509
+ * attributed by `(traceId, spanId)`, so only the span that recorded a metric row carries it.
4510
+ */
4511
+ function compileDuckDBSpanAggregate(plan, options = {}) {
4512
+ const { ctes, values } = compileDuckDBSpanSelection(plan);
4513
+ return compileDuckDBAggregate(plan, options, {
4514
+ ctes,
4515
+ values,
4516
+ from: "selected",
4517
+ dimensionSql: (field) => ({
4518
+ sql: lookupDimensionSql(SPAN_DIMENSION_SQL, field),
4452
4519
  values: []
4453
- };
4454
- };
4520
+ }),
4521
+ usageKey: ["traceId", "spanId"]
4522
+ });
4523
+ }
4524
+ function lookupDimensionSql(columns, field) {
4525
+ const sql = Object.hasOwn(columns, field) ? columns[field] : void 0;
4526
+ if (sql === void 0) throw new Error(`Unsupported trusted aggregate field: ${field}`);
4527
+ return sql;
4528
+ }
4529
+ function compileDuckDBAggregate(plan, options, source) {
4530
+ const { ctes, values, dimensionSql } = source;
4455
4531
  const distinctSql = (field) => field === "traceId" ? {
4456
4532
  sql: "r.traceId",
4457
4533
  values: []
@@ -4482,16 +4558,18 @@ function compileDuckDBTraceAggregate(plan, options = {}) {
4482
4558
  const hasCost = measureKinds.has("cost");
4483
4559
  if (!hasCost && !measureKinds.has("tokens")) ctes.push(`facts AS (
4484
4560
  SELECT ${factColumns.join(",\n ")}
4485
- FROM candidates r
4561
+ FROM ${source.from} r
4486
4562
  )`);
4487
4563
  else {
4564
+ const keyColumns = source.usageKey.map((key) => `r.${key}`).join(", ");
4488
4565
  ctes.push(`base_facts AS (
4489
- SELECT r.traceId, ${factColumns.join(",\n ")}
4490
- FROM candidates r
4566
+ SELECT ${keyColumns}, ${factColumns.join(",\n ")}
4567
+ FROM ${source.from} r
4491
4568
  )`);
4492
4569
  ctes.push(...compileUsageCtes(plan, values, {
4493
4570
  hasCost,
4494
- dedupe: !options.metricIdsUnique
4571
+ dedupe: !options.metricIdsUnique,
4572
+ key: source.usageKey
4495
4573
  }));
4496
4574
  const usageColumns = USAGE_METRIC_NAMES.map((_, index) => `CASE WHEN u.traceId IS NOT NULL THEN COALESCE(u.t${index}, 0) END AS t${index}`);
4497
4575
  usageColumns.push(`u.traceId IS NOT NULL AS usageBearing`);
@@ -4500,7 +4578,7 @@ function compileDuckDBTraceAggregate(plan, options = {}) {
4500
4578
  SELECT b.*,
4501
4579
  ${usageColumns.join(",\n ")}
4502
4580
  FROM base_facts b
4503
- LEFT JOIN usage u ON u.traceId = b.traceId
4581
+ LEFT JOIN usage u ON ${source.usageKey.map((key) => `u.${key} = b.${key}`).join(" AND ")}
4504
4582
  )`);
4505
4583
  }
4506
4584
  const measureSql = (name, alias = "") => {
@@ -4622,8 +4700,8 @@ function costColumns(alias) {
4622
4700
  return [`CAST(count_if(${alias}covered) AS DOUBLE) / NULLIF(count_if(${alias}usageBearing), 0) AS costCoverage`, `CASE WHEN ${mixedUnitsSql(alias)} THEN '${mixed}' ELSE min(${alias}unitMin) END AS costUnit`];
4623
4701
  }
4624
4702
  /**
4625
- * Builds `usage_bounds`, `usage_rows`, and `usage`: one row per candidate trace that has at least
4626
- * one token metric row, holding per-name token sums (`t<i>`, indexed by
4703
+ * Builds `usage_bounds`, `usage_rows`, and `usage`: one row per population row (trace, or span)
4704
+ * that has at least one token metric row, keyed by the source's usage key, holding per-name token sums (`t<i>`, indexed by
4627
4705
  * `TRACE_AGGREGATE_USAGE_METRIC_NAMES`) and, for cost requests, the trace's pricing state. Metric
4628
4706
  * rows are matched by traceId, usage metric name, tenant scope, and `timestamp >= from` only: a
4629
4707
  * trace that starts in the window can emit metrics after `to`, and the semi-join bounds the scan.
@@ -4637,7 +4715,7 @@ function costColumns(alias) {
4637
4715
  *
4638
4716
  * Placeholders are bound in text order: `param` pushes each value as its placeholder is emitted.
4639
4717
  */
4640
- function compileUsageCtes(plan, values, { hasCost, dedupe }) {
4718
+ function compileUsageCtes(plan, values, { hasCost, dedupe, key }) {
4641
4719
  const param = (value) => {
4642
4720
  values.push(value);
4643
4721
  return "?";
@@ -4664,9 +4742,10 @@ function compileUsageCtes(plan, values, { hasCost, dedupe }) {
4664
4742
  CASE WHEN m.name IN (${list(costNames)})
4665
4743
  THEN COALESCE(json_type(m.costMetadata, '$.error'), 'NULL') <> 'NULL'
4666
4744
  ELSE FALSE
4667
- END AS hasError` : "";
4745
+ END AS hasError,
4746
+ COALESCE(json_extract_string(m.costMetadata, '$.error') = 'partial_cost', FALSE) AS partialCost` : "";
4668
4747
  const rows = `usage_rows AS (
4669
- SELECT ${dedupe ? "DISTINCT ON (m.metricId) " : ""}m.traceId, m.name, m.value${costSelect}
4748
+ SELECT ${dedupe ? "DISTINCT ON (m.metricId) " : ""}${key.map((column) => `m.${column}`).join(", ")}, m.name, m.value${costSelect}
4670
4749
  FROM metric_events m
4671
4750
  WHERE m.timestamp >= (SELECT minTs FROM usage_bounds)
4672
4751
  AND m.timestamp <= (SELECT maxTs FROM usage_bounds)
@@ -4675,17 +4754,17 @@ function compileUsageCtes(plan, values, { hasCost, dedupe }) {
4675
4754
  )`;
4676
4755
  const columns = USAGE_METRIC_NAMES.map((name) => `sum(value) FILTER (WHERE name = ${param(name)})`).map((sql, index) => `${sql} AS t${index}`);
4677
4756
  if (hasCost) {
4678
- const priced = "costRow AND estimatedCost IS NOT NULL AND costUnit IS NOT NULL AND NOT hasError";
4757
+ const priced = "costRow AND estimatedCost IS NOT NULL AND costUnit IS NOT NULL AND (NOT hasError OR partialCost)";
4679
4758
  columns.push(`sum(estimatedCost) FILTER (WHERE ${priced}) AS cost`, `bool_or(${priced}) AS priced`, `bool_or(costRow AND (hasError OR (estimatedCost IS NOT NULL AND costUnit IS NULL))) AS pricingFailure`, `min(costUnit) FILTER (WHERE ${priced}) AS unitMin`, `max(costUnit) FILTER (WHERE ${priced}) AS unitMax`);
4680
4759
  }
4681
4760
  return [
4682
4761
  bounds,
4683
4762
  rows,
4684
4763
  `usage AS (
4685
- SELECT traceId,
4764
+ SELECT ${key.join(", ")},
4686
4765
  ${columns.join(",\n ")}
4687
4766
  FROM usage_rows
4688
- GROUP BY traceId
4767
+ GROUP BY ${key.join(", ")}
4689
4768
  )`
4690
4769
  ];
4691
4770
  }
@@ -4693,7 +4772,12 @@ function nullableNumber(value) {
4693
4772
  return value === null || value === void 0 ? null : Number(value);
4694
4773
  }
4695
4774
  async function aggregateTraces(db, plan, options = {}) {
4696
- const compiled = compileDuckDBTraceAggregate(plan, options);
4775
+ return runAggregate(db, plan, compileDuckDBTraceAggregate(plan, options));
4776
+ }
4777
+ async function aggregateSpans(db, plan, options = {}) {
4778
+ return runAggregate(db, plan, compileDuckDBSpanAggregate(plan, options));
4779
+ }
4780
+ async function runAggregate(db, plan, compiled) {
4697
4781
  let result;
4698
4782
  try {
4699
4783
  result = await db.query(compiled.sql, compiled.values);
@@ -4748,6 +4832,12 @@ const COLUMNS_SQL = [
4748
4832
  "entityVersionId",
4749
4833
  "parentEntityVersionId",
4750
4834
  "rootEntityVersionId",
4835
+ "parentEntityType",
4836
+ "parentEntityId",
4837
+ "parentEntityName",
4838
+ "rootEntityType",
4839
+ "rootEntityId",
4840
+ "rootEntityName",
4751
4841
  "userId",
4752
4842
  "organizationId",
4753
4843
  "resourceId",
@@ -4826,6 +4916,12 @@ const SPAN_RECONSTRUCT_SELECT = `
4826
4916
  ${argMaxNonNull("entityVersionId")},
4827
4917
  ${argMaxNonNull("parentEntityVersionId")},
4828
4918
  ${argMaxNonNull("rootEntityVersionId")},
4919
+ ${argMaxNonNull("parentEntityType")},
4920
+ ${argMaxNonNull("parentEntityId")},
4921
+ ${argMaxNonNull("parentEntityName")},
4922
+ ${argMaxNonNull("rootEntityType")},
4923
+ ${argMaxNonNull("rootEntityId")},
4924
+ ${argMaxNonNull("rootEntityName")},
4829
4925
  ${argMaxNonNull("userId")},
4830
4926
  ${argMaxNonNull("organizationId")},
4831
4927
  ${argMaxNonNull("resourceId")},
@@ -5056,6 +5152,12 @@ function rowToSpanRecord(row) {
5056
5152
  entityVersionId: row.entityVersionId ?? null,
5057
5153
  parentEntityVersionId: row.parentEntityVersionId ?? null,
5058
5154
  rootEntityVersionId: row.rootEntityVersionId ?? null,
5155
+ parentEntityType: row.parentEntityType ?? null,
5156
+ parentEntityId: row.parentEntityId ?? null,
5157
+ parentEntityName: row.parentEntityName ?? null,
5158
+ rootEntityType: row.rootEntityType ?? null,
5159
+ rootEntityId: row.rootEntityId ?? null,
5160
+ rootEntityName: row.rootEntityName ?? null,
5059
5161
  userId: row.userId ?? null,
5060
5162
  organizationId: row.organizationId ?? null,
5061
5163
  resourceId: row.resourceId ?? null,
@@ -5236,6 +5338,12 @@ function toValuesTuple(row) {
5236
5338
  v(row.entityVersionId),
5237
5339
  v(row.parentEntityVersionId),
5238
5340
  v(row.rootEntityVersionId),
5341
+ v(row.parentEntityType),
5342
+ v(row.parentEntityId),
5343
+ v(row.parentEntityName),
5344
+ v(row.rootEntityType),
5345
+ v(row.rootEntityId),
5346
+ v(row.rootEntityName),
5239
5347
  v(row.userId),
5240
5348
  v(row.organizationId),
5241
5349
  v(row.resourceId),
@@ -5289,6 +5397,12 @@ function createStartSpanRow(s) {
5289
5397
  entityVersionId: s.entityVersionId ?? null,
5290
5398
  parentEntityVersionId: s.parentEntityVersionId ?? null,
5291
5399
  rootEntityVersionId: s.rootEntityVersionId ?? null,
5400
+ parentEntityType: s.parentEntityType ?? null,
5401
+ parentEntityId: s.parentEntityId ?? null,
5402
+ parentEntityName: s.parentEntityName ?? null,
5403
+ rootEntityType: s.rootEntityType ?? null,
5404
+ rootEntityId: s.rootEntityId ?? null,
5405
+ rootEntityName: s.rootEntityName ?? null,
5292
5406
  userId: s.userId ?? null,
5293
5407
  organizationId: s.organizationId ?? null,
5294
5408
  resourceId: s.resourceId ?? null,
@@ -5338,6 +5452,12 @@ function createEndSpanRow(s) {
5338
5452
  entityVersionId: s.entityVersionId ?? null,
5339
5453
  parentEntityVersionId: s.parentEntityVersionId ?? null,
5340
5454
  rootEntityVersionId: s.rootEntityVersionId ?? null,
5455
+ parentEntityType: s.parentEntityType ?? null,
5456
+ parentEntityId: s.parentEntityId ?? null,
5457
+ parentEntityName: s.parentEntityName ?? null,
5458
+ rootEntityType: s.rootEntityType ?? null,
5459
+ rootEntityId: s.rootEntityId ?? null,
5460
+ rootEntityName: s.rootEntityName ?? null,
5341
5461
  userId: s.userId ?? null,
5342
5462
  organizationId: s.organizationId ?? null,
5343
5463
  resourceId: s.resourceId ?? null,
@@ -6181,6 +6301,7 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends Observ
6181
6301
  "trace-query",
6182
6302
  "trace-aggregate",
6183
6303
  ...spanQueryFeatures,
6304
+ ...spanAggregateFeatures,
6184
6305
  ...typeof coreStorage.planThreadRowsQuery === "function" ? ["thread-query-rows"] : [],
6185
6306
  "trace-query-root-duration",
6186
6307
  "trace-query-discovery",
@@ -6205,6 +6326,7 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends Observ
6205
6326
  "trace-query",
6206
6327
  "trace-aggregate",
6207
6328
  ...spanQueryFeatures,
6329
+ ...spanAggregateFeatures,
6208
6330
  ...typeof coreStorage.planThreadRowsQuery === "function" ? ["thread-query-rows"] : [],
6209
6331
  "trace-query-root-duration",
6210
6332
  "trace-query-discovery",
@@ -6253,6 +6375,9 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends Observ
6253
6375
  async aggregateTraces(plan) {
6254
6376
  return aggregateTraces(this.db, plan, { metricIdsUnique: this.metricIdsUnique });
6255
6377
  }
6378
+ async aggregateSpans(plan) {
6379
+ return aggregateSpans(this.db, plan, { metricIdsUnique: this.metricIdsUnique });
6380
+ }
6256
6381
  async getTraceQueryObservedFields(plan) {
6257
6382
  return getTraceQueryObservedFields(this.db, plan);
6258
6383
  }
@@ -6376,4 +6501,4 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends Observ
6376
6501
  //#endregion
6377
6502
  export { ObservabilityStorageDuckDB };
6378
6503
 
6379
- //# sourceMappingURL=observability-642joQI8.js.map
6504
+ //# sourceMappingURL=observability-Bv3eObB-.js.map