@mastra/duckdb 1.11.0-alpha.0 → 1.11.0-alpha.2

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.
@@ -709,6 +709,23 @@ function jsonV(val) {
709
709
  if (val === null || val === void 0) return "NULL";
710
710
  return require_db.DuckDBConnection.sqlValue(JSON.stringify(val));
711
711
  }
712
+ /**
713
+ * Trim, drop blank, and dedupe tags before they are written, matching the
714
+ * PostgreSQL and ClickHouse stores so tag predicates and discovery agree.
715
+ */
716
+ function normalizeTags(tags) {
717
+ if (!Array.isArray(tags)) return [];
718
+ const seen = /* @__PURE__ */ new Set();
719
+ const result = [];
720
+ for (const t of tags) {
721
+ if (typeof t !== "string") continue;
722
+ const trimmed = t.trim();
723
+ if (trimmed === "" || seen.has(trimmed)) continue;
724
+ seen.add(trimmed);
725
+ result.push(trimmed);
726
+ }
727
+ return result;
728
+ }
712
729
  /** Coerce a value to a Date. Throws if value is nullish. */
713
730
  function toDate(val) {
714
731
  if (val === null || val === void 0) throw new Error("Expected date value but received null/undefined");
@@ -2705,6 +2722,9 @@ async function getScorePercentiles(db, args) {
2705
2722
  //#endregion
2706
2723
  //#region src/storage/domains/observability/trace-query.ts
2707
2724
  const TRACE_STATUS_SQL = `CASE WHEN r.error IS NOT NULL THEN 'error' ELSE 'success' END`;
2725
+ function durationMsSql(startedAt, endedAt) {
2726
+ return `date_diff('millisecond', ${startedAt}, ${endedAt})`;
2727
+ }
2708
2728
  const TRACE_FIELDS = {
2709
2729
  traceId: {
2710
2730
  sql: "r.traceId",
@@ -2726,6 +2746,10 @@ const TRACE_FIELDS = {
2726
2746
  sql: "r.endedAt",
2727
2747
  parameterType: "timestamp"
2728
2748
  },
2749
+ durationMs: {
2750
+ sql: durationMsSql("r.startedAt", "r.endedAt"),
2751
+ parameterType: "scalar"
2752
+ },
2729
2753
  entityName: {
2730
2754
  sql: "r.entityName",
2731
2755
  parameterType: "scalar"
@@ -2741,6 +2765,10 @@ const TRACE_FIELDS = {
2741
2765
  status: {
2742
2766
  sql: TRACE_STATUS_SQL,
2743
2767
  parameterType: "scalar"
2768
+ },
2769
+ tags: {
2770
+ sql: "r.tags",
2771
+ parameterType: "scalar"
2744
2772
  }
2745
2773
  };
2746
2774
  const SPAN_FIELDS = {
@@ -2943,6 +2971,25 @@ function compileScalarPredicate(predicate, registry, allowMetadata = false) {
2943
2971
  sql: `${field.sql} IS ${predicate.operator === "exists" ? "NOT " : ""}NULL`,
2944
2972
  values: fieldValues
2945
2973
  };
2974
+ if (predicate.type === "collection") {
2975
+ const members = `coalesce(TRY_CAST(${field.sql} AS VARCHAR[]), []::VARCHAR[])`;
2976
+ if (!("value" in predicate)) return {
2977
+ sql: `len(${members}) ${predicate.operator === "empty" ? "=" : ">"} 0`,
2978
+ values: fieldValues
2979
+ };
2980
+ if (predicate.operator === "includes") return {
2981
+ sql: `list_contains(${members}, ?)`,
2982
+ values: [...fieldValues, predicate.value]
2983
+ };
2984
+ return {
2985
+ sql: `len(${members}) > 0 AND NOT list_contains(${members}, ?)`,
2986
+ values: [
2987
+ ...fieldValues,
2988
+ ...fieldValues,
2989
+ predicate.value
2990
+ ]
2991
+ };
2992
+ }
2946
2993
  if (predicate.type === "membership") {
2947
2994
  const list = predicate.values.map(() => parameterSql(field.parameterType)).join(", ");
2948
2995
  if (predicate.operator === "in") return {
@@ -3007,7 +3054,7 @@ function compileFeedbackScalarPredicate(predicate) {
3007
3054
  values: compiled.values
3008
3055
  };
3009
3056
  }
3010
- if (predicate.field !== "value") return compileScalarPredicate(predicate, FEEDBACK_FIELDS);
3057
+ if (predicate.field !== "value" || predicate.type === "collection") return compileScalarPredicate(predicate, FEEDBACK_FIELDS);
3011
3058
  if (predicate.type === "presence") return {
3012
3059
  sql: `s.value IS ${predicate.operator === "exists" ? "NOT " : ""}NULL`,
3013
3060
  values: []
@@ -3161,7 +3208,7 @@ function compileDuckDBTraceScope(relatedCollections, scope) {
3161
3208
  END AS provider,
3162
3209
  startedAt,
3163
3210
  endedAt,
3164
- date_diff('millisecond', startedAt, endedAt) AS durationMs,
3211
+ ${durationMsSql("startedAt", "endedAt")} AS durationMs,
3165
3212
  CASE WHEN error IS NOT NULL THEN 'error' ELSE 'success' END AS status,
3166
3213
  error,
3167
3214
  entityType,
@@ -3393,7 +3440,11 @@ function compileDuckDBTraceQueryValues(plan) {
3393
3440
  ...scopeValues
3394
3441
  ];
3395
3442
  let fieldSql;
3396
- if (plan.predicateScope === "trace" && plan.path.startsWith("metadata.")) {
3443
+ let source = discoverySource(plan.predicateScope);
3444
+ if (plan.predicateScope === "trace" && plan.path === "tags") {
3445
+ fieldSql = "unnest(list_distinct(TRY_CAST(r.tags AS VARCHAR[])))";
3446
+ source = `${source} WHERE r.tags IS NOT NULL`;
3447
+ } else if (plan.predicateScope === "trace" && plan.path.startsWith("metadata.")) {
3397
3448
  const jsonPath = `$.${JSON.stringify(plan.path.slice(9))}`;
3398
3449
  fieldSql = `NULLIF(trim(CASE WHEN json_type(r.metadata, ?) = 'VARCHAR' THEN json_extract_string(r.metadata, ?) END), '')`;
3399
3450
  values.push(jsonPath, jsonPath);
@@ -3403,7 +3454,7 @@ function compileDuckDBTraceQueryValues(plan) {
3403
3454
  const search = plan.search ? "AND strpos(lower(CAST(value AS VARCHAR)), lower(?)) > 0" : "";
3404
3455
  return {
3405
3456
  sql: `WITH ${ctes.join(",\n ")}, extracted AS (
3406
- SELECT ${fieldSql} AS value FROM ${discoverySource(plan.predicateScope)}
3457
+ SELECT ${fieldSql} AS value FROM ${source}
3407
3458
  )
3408
3459
  SELECT CAST(value AS VARCHAR) AS value, count(*) AS count
3409
3460
  FROM extracted
@@ -4001,7 +4052,7 @@ function createStartSpanRow(s) {
4001
4052
  serviceName: s.serviceName ?? null,
4002
4053
  attributes: s.attributes ?? null,
4003
4054
  metadata: s.metadata ?? null,
4004
- tags: s.tags ?? null,
4055
+ tags: s.tags == null ? null : normalizeTags(s.tags),
4005
4056
  scope: s.scope ?? null,
4006
4057
  links: null,
4007
4058
  input: s.input ?? null,
@@ -4040,7 +4091,7 @@ function createEndSpanRow(s) {
4040
4091
  serviceName: s.serviceName ?? null,
4041
4092
  attributes: s.attributes ?? null,
4042
4093
  metadata: s.metadata ?? null,
4043
- tags: s.tags ?? null,
4094
+ tags: s.tags == null ? null : normalizeTags(s.tags),
4044
4095
  scope: s.scope ?? null,
4045
4096
  links: s.links ?? null,
4046
4097
  input: s.input ?? null,
@@ -4842,6 +4893,7 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends _mastr
4842
4893
  "metrics",
4843
4894
  "logs",
4844
4895
  "trace-query",
4896
+ "trace-query-root-duration",
4845
4897
  "trace-query-discovery",
4846
4898
  "thread-query",
4847
4899
  "trace-query-tenant-scope"
@@ -4851,6 +4903,7 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends _mastr
4851
4903
  "logs",
4852
4904
  "delta-polling",
4853
4905
  "trace-query",
4906
+ "trace-query-root-duration",
4854
4907
  "trace-query-discovery",
4855
4908
  "thread-query",
4856
4909
  "trace-query-tenant-scope"
@@ -5008,4 +5061,4 @@ var ObservabilityStorageDuckDB = class ObservabilityStorageDuckDB extends _mastr
5008
5061
  //#endregion
5009
5062
  exports.ObservabilityStorageDuckDB = ObservabilityStorageDuckDB;
5010
5063
 
5011
- //# sourceMappingURL=observability-CdS3iFtO.cjs.map
5064
+ //# sourceMappingURL=observability-D276d4Zq.cjs.map