@mastra/pg 1.32.0-alpha.3 → 1.32.0-alpha.5

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/index.js CHANGED
@@ -19187,7 +19187,26 @@ async function getScorePercentiles(client, schema, args) {
19187
19187
  const TRACE_STATUS_SQL = `CASE WHEN r."error" IS NOT NULL THEN 'error' ELSE 'success' END`;
19188
19188
  /** Core versions without the field reject it in strict query results, so it is only returned when core knows it. */
19189
19189
  const timeToFirstChunkSupported = "timeToFirstChunkMs" in coreStorage.TRACE_QUERY_FIELD_REGISTRY.trace;
19190
- const timeToFirstChunkFeatures = timeToFirstChunkSupported ? ["trace-query-time-to-first-chunk"] : [];
19190
+ /** Core before the sort rejects `orderBy` on the field, so the sort is only declared when core plans it. */
19191
+ const timeToFirstChunkSortSupported = coreStorage.TRACE_QUERY_ORDER_FIELDS?.includes("timeToFirstChunkMs") === true;
19192
+ const timeToFirstChunkFeatures = [...timeToFirstChunkSupported ? ["trace-query-time-to-first-chunk"] : [], ...timeToFirstChunkSortSupported ? ["trace-query-time-to-first-chunk-sort"] : []];
19193
+ /**
19194
+ * Keyset bounds for a cursor's sort value: terms for rows strictly past it in `direction`, and the
19195
+ * condition for rows level with it. Empty values sort last in both directions, so they are past
19196
+ * every value and level only with each other.
19197
+ */
19198
+ function keysetSortBounds(field, direction, sortValue, values) {
19199
+ if (sortValue === null) return {
19200
+ past: [],
19201
+ level: `${field} IS NULL`
19202
+ };
19203
+ values.push(sortValue);
19204
+ const parameter = `$${values.length}::${typeof sortValue === "number" ? "float8" : "timestamptz"}`;
19205
+ return {
19206
+ past: [`${field} ${direction === "asc" ? ">" : "<"} ${parameter}`, `${field} IS NULL`],
19207
+ level: `${field} = ${parameter}`
19208
+ };
19209
+ }
19191
19210
  function durationMsSql(startedAt, endedAt) {
19192
19211
  return `EXTRACT(EPOCH FROM (${endedAt} - ${startedAt}))::numeric * 1000`;
19193
19212
  }
@@ -19203,6 +19222,7 @@ const TRACE_FIELDS = {
19203
19222
  endedAt: "r.\"endedAt\"",
19204
19223
  durationMs: durationMsSql("r.\"startedAt\"", "r.\"endedAt\""),
19205
19224
  timeToFirstChunkMs: "r.\"timeToFirstChunkMs\"",
19225
+ entityId: "r.\"entityId\"",
19206
19226
  entityName: "r.\"entityName\"",
19207
19227
  entityType: "r.\"entityType\"",
19208
19228
  name: "r.\"name\"",
@@ -19504,6 +19524,7 @@ const ROOT_PUSHDOWN_FIELDS = /* @__PURE__ */ new Set([
19504
19524
  "organizationId",
19505
19525
  "startedAt",
19506
19526
  "endedAt",
19527
+ "entityId",
19507
19528
  "entityName",
19508
19529
  "entityType",
19509
19530
  "name",
@@ -19779,8 +19800,8 @@ LIMIT $${values.length}`,
19779
19800
  values
19780
19801
  };
19781
19802
  }
19782
- const orderField = plan.orderBy.field === "startedAt" ? "\"startedAt\"" : "\"endedAt\"";
19783
- const direction = plan.orderBy.direction === "asc" ? "ASC" : "DESC";
19803
+ const orderField = `"${plan.orderBy.field}"`;
19804
+ const direction = `${plan.orderBy.direction === "asc" ? "ASC" : "DESC"} NULLS LAST`;
19784
19805
  if (plan.paginationMode === "page") {
19785
19806
  values.push(plan.perPage, plan.page * plan.perPage);
19786
19807
  return {
@@ -19794,10 +19815,9 @@ LIMIT $${values.length - 1} OFFSET $${values.length}`,
19794
19815
  }
19795
19816
  let pageCondition = "";
19796
19817
  if (plan.cursor) {
19797
- const comparison = plan.orderBy.direction === "asc" ? ">" : "<";
19798
- const sortParameter = `$${values.length + 1}`;
19799
- pageCondition = `WHERE (${orderField} ${comparison} ${sortParameter} OR (${orderField} = ${sortParameter} AND "traceId" > ${`$${values.length + 2}`}))`;
19800
- values.push(plan.cursor.sortValue, plan.cursor.traceId);
19818
+ const { past, level } = keysetSortBounds(orderField, plan.orderBy.direction, plan.cursor.sortValue, values);
19819
+ values.push(plan.cursor.traceId);
19820
+ pageCondition = `WHERE (${[...past, `(${level} AND "traceId" > $${values.length})`].join(" OR ")})`;
19801
19821
  }
19802
19822
  values.push(plan.limit + 1);
19803
19823
  return {
@@ -20130,7 +20150,7 @@ async function queryTraces(client, schema, plan, timeoutMs) {
20130
20150
  traces,
20131
20151
  page: { next: rows.length > plan.limit && last ? coreStorage.encodeTraceQueryCursor(plan, {
20132
20152
  result: "traces",
20133
- sortValue: last[plan.orderBy.field],
20153
+ sortValue: last[plan.orderBy.field] ?? null,
20134
20154
  traceId: last.traceId
20135
20155
  }) : null }
20136
20156
  });
@@ -20202,11 +20222,8 @@ function selectedKeys(rows, values) {
20202
20222
  function afterCursor(plan, values) {
20203
20223
  if (!plan.cursor) return "TRUE";
20204
20224
  const cursor = plan.cursor;
20205
- values.push(cursor.sortValue);
20206
- const timestamp = `$${values.length}::timestamptz`;
20207
- const field = `s."${plan.orderBy.field}"`;
20208
- const terms = [`${field} ${plan.orderBy.direction === "asc" ? ">" : "<"} ${timestamp}`];
20209
- const equal = [`${field} = ${timestamp}`];
20225
+ const { past: terms, level } = keysetSortBounds(`s."${plan.orderBy.field}"`, plan.orderBy.direction, cursor.sortValue, values);
20226
+ const equal = [level];
20210
20227
  for (const key of identityFields) {
20211
20228
  const ref = `s."${key}" COLLATE "C"`;
20212
20229
  const value = cursor[key];
@@ -20272,7 +20289,7 @@ function compilePostgresSpanQuery(schema, plan) {
20272
20289
  "version"
20273
20290
  ].map((field) => `s."${field}"`).join(", ")}
20274
20291
  FROM candidates s WHERE s."startedAt" >= $1 AND s."startedAt" < $2 AND (${predicate.sql}) AND ${after}
20275
- ORDER BY s."${plan.orderBy.field}" ${plan.orderBy.direction === "asc" ? "ASC" : "DESC"}, ${identityOrder}
20292
+ ORDER BY s."${plan.orderBy.field}" ${plan.orderBy.direction === "asc" ? "ASC" : "DESC"} NULLS LAST, ${identityOrder}
20276
20293
  LIMIT $${values.length}`,
20277
20294
  values
20278
20295
  };
@@ -20593,6 +20610,7 @@ const DIMENSION_SQL = {
20593
20610
  entityName: "r.\"entityName\"",
20594
20611
  name: "r.\"name\"",
20595
20612
  spanType: "r.\"spanType\"",
20613
+ entityId: "r.\"entityId\"",
20596
20614
  environment: "r.\"environment\"",
20597
20615
  status: TRACE_STATUS_SQL,
20598
20616
  serviceName: "r.\"serviceName\"",
@@ -21827,7 +21845,8 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
21827
21845
  "feedback",
21828
21846
  "trace-query-context-ids",
21829
21847
  ...timeToFirstChunkFeatures,
21830
- "trace-query-root-span-fields"
21848
+ "trace-query-root-span-fields",
21849
+ "trace-query-root-entity-id"
21831
21850
  ];
21832
21851
  return [
21833
21852
  "metrics",
@@ -21850,7 +21869,8 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
21850
21869
  "feedback",
21851
21870
  "trace-query-context-ids",
21852
21871
  ...timeToFirstChunkFeatures,
21853
- "trace-query-root-span-fields"
21872
+ "trace-query-root-span-fields",
21873
+ "trace-query-root-entity-id"
21854
21874
  ];
21855
21875
  }
21856
21876
  async #run(op, fn, details) {