@mastra/pg 1.27.0-alpha.0 → 1.27.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.
@@ -3,7 +3,7 @@ name: mastra-pg
3
3
  description: Documentation for @mastra/pg. Use when working with @mastra/pg APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/pg"
6
- version: "1.27.0-alpha.0"
6
+ version: "1.27.0-alpha.1"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.27.0-alpha.0",
2
+ "version": "1.27.0-alpha.1",
3
3
  "package": "@mastra/pg",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -45,6 +45,8 @@ export const agent = new Agent({
45
45
 
46
46
  **options.readOnly** (`boolean`): When true, prevents memory from saving new messages and provides working memory as read-only context (without the updateWorkingMemory tool). Useful for read-only operations like previews, internal routing agents, or sub agents that should reference but not modify memory.
47
47
 
48
+ **options.retainFullInput** (`boolean`): When true, the request input is processed exactly as supplied instead of being filtered against stored history. Use this when you assemble the input yourself and need the message sequence preserved. Stored history is still loaded underneath, and every input message that isn't already stored is saved to the thread, including few-shot examples. Can be set per call on memory.options or agent-wide in the memory constructor options.
49
+
48
50
  **options.semanticRecall** (`boolean | { topK: number; messageRange: number | { before: number; after: number }; scope?: 'thread' | 'resource' }`): Enable semantic search in message history. Can be a boolean or an object with configuration options. When enabled, requires both vector store and embedder to be configured. Default topK is 4, default messageRange is {before: 1, after: 1}.
49
51
 
50
52
  **options.workingMemory** (`WorkingMemory`): Configuration for working memory feature. Can be { enabled: boolean; template?: string; schema?: ZodObject\<any> | JSONSchema7; scope?: 'thread' | 'resource' } or { enabled: boolean } to disable.
@@ -15,7 +15,7 @@ Storage adapters use the shared core retention contract for `prune()`, or a data
15
15
  | Adapter | Mechanism | Retention support |
16
16
  | -------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
17
17
  | libSQL | `prune()` | All supported growth domains |
18
- | PostgreSQL | `prune()` | All supported growth domains. V-next observability drops expired partitions or chunks |
18
+ | PostgreSQL | `prune()` | All supported growth domains. vNext observability drops expired partitions or chunks |
19
19
  | MongoDB | `prune()` or native TTL | All supported growth domains. Native TTL indexes are also available |
20
20
  | DuckDB | `prune()` | Observability spans, metrics, logs, scores, and feedback |
21
21
  | MySQL | `prune()` | Observability spans |
@@ -102,10 +102,10 @@ Each domain specifies its age-prunable tables and the timestamp column that anch
102
102
  | `memory` | `resources` | `createdAt` | Resource age |
103
103
  | `threadState` | `threadState` | `updatedAt` | Inactivity: state for still-active threads survives |
104
104
  | `observability` | `spans` | `startedAt` | Span age |
105
- | `observability` | `metrics` | `timestamp` | Metric event age (v-next only) |
106
- | `observability` | `logs` | `timestamp` | Log event age (v-next only) |
107
- | `observability` | `scores` | `timestamp` | Score event age (v-next only) |
108
- | `observability` | `feedback` | `timestamp` | Feedback event age (v-next only) |
105
+ | `observability` | `metrics` | `timestamp` | Metric event age (vNext only) |
106
+ | `observability` | `logs` | `timestamp` | Log event age (vNext only) |
107
+ | `observability` | `scores` | `timestamp` | Score event age (vNext only) |
108
+ | `observability` | `feedback` | `timestamp` | Feedback event age (vNext only) |
109
109
  | `scores` | `scorers` | `createdAt` | Score record age |
110
110
  | `workflows` | `workflowSnapshot` | `updatedAt` | Inactivity, suspended or long-running workflows survive |
111
111
  | `backgroundTasks` | `backgroundTasks` | `completedAt` | Time since completion, in-flight tasks (`NULL`) are never pruned |
@@ -122,7 +122,7 @@ Each domain specifies its age-prunable tables and the timestamp column that anch
122
122
  > - On PostgreSQL, timestamp anchors use the timezone-aware mirror columns (for example `createdAtZ`, `completedAtZ`).
123
123
  > - DuckDB observability stores append-only events for all five signals. Its `spans` policy uses the event `timestamp` column rather than `startedAt`.
124
124
  > - LibSQL and PostgreSQL support all domains above except `harness`, which PostgreSQL doesn't implement. MongoDB supports all except `threadState` and `harness`. DuckDB, MySQL, Microsoft SQL Server, Oracle Database, Amazon Aurora DSQL, and Google Cloud Spanner currently support retention only in their `observability` domains, with the signal coverage shown in the support matrix.
125
- > - The v-next PostgreSQL observability domain stores signal events in day-partitioned tables (`spans`, `metrics`, `logs`, `scores`, `feedback`). For it, `prune()` drops whole day partitions (or TimescaleDB chunks) that are entirely older than the cutoff instead of deleting rows: effective level of detail is one day, and a partition is only dropped once its entire day is past `maxAge`. `PruneResult.deleted` reports the number of rows in the dropped partitions.
125
+ > - The vNext PostgreSQL observability domain stores signal events in day-partitioned tables (`spans`, `metrics`, `logs`, `scores`, `feedback`). For it, `prune()` drops whole day partitions (or TimescaleDB chunks) that are entirely older than the cutoff instead of deleting rows: effective level of detail is one day, and a partition is only dropped once its entire day is past `maxAge`. `PruneResult.deleted` reports the number of rows in the dropped partitions.
126
126
 
127
127
  ## Methods
128
128
 
@@ -208,7 +208,9 @@ You can also cancel a long-running prune with an `AbortSignal`: the loop stops b
208
208
 
209
209
  ClickHouse observability storage uses native table TTLs instead of `prune()`. Configure retention as days per signal. `init()` applies the TTLs to new and existing tables and skips `ALTER TABLE` statements when the configured TTL is already present.
210
210
 
211
- For deployments that need to update TTL configuration without running the full initialization path, call `applyRetention()` on the v-next observability store:
211
+ Omitted signals, and signals set to zero or less, get no TTL. When you remove a signal from `retention`, the next `init()` or `applyRetention()` removes that table's TTL. If Mastra can't read the current TTLs from `system.tables`, it applies the configured TTLs and leaves the others unchanged.
212
+
213
+ For deployments that need to update TTL configuration without running the full initialization path, call `applyRetention()` on the vNext observability store:
212
214
 
213
215
  ```typescript
214
216
  import { ObservabilityStorageClickhouseVNext } from '@mastra/clickhouse'
package/dist/index.cjs CHANGED
@@ -5666,6 +5666,19 @@ var ChannelsPG = class ChannelsPG extends _mastra_core_storage.ChannelsStorage {
5666
5666
  function jsonbArg(value) {
5667
5667
  return value === void 0 || value === null ? null : JSON.stringify(value);
5668
5668
  }
5669
+ /** Preserve JSON null as data, rather than converting it to an absent SQL value. */
5670
+ function jsonDataArg(value) {
5671
+ return value === void 0 ? null : JSON.stringify(value);
5672
+ }
5673
+ const ITEM_SELECT_COLUMNS = [
5674
+ ...Object.keys(_mastra_core_storage.DATASET_ITEMS_SCHEMA),
5675
+ "createdAtZ",
5676
+ "updatedAtZ"
5677
+ ].map((column) => [
5678
+ "input",
5679
+ "groundTruth",
5680
+ "expectedTrajectory"
5681
+ ].includes(column) ? `"${column}"::text AS "${column}"` : `"${column}"`).join(", ");
5669
5682
  function parseStoredJSON(value) {
5670
5683
  if (typeof value === "string") try {
5671
5684
  return JSON.parse(value);
@@ -5840,9 +5853,9 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
5840
5853
  groundTruthSchema: row.groundTruthSchema ? (0, _mastra_core_storage.safelyParseJSON)(row.groundTruthSchema) : void 0,
5841
5854
  requestContextSchema: row.requestContextSchema ? (0, _mastra_core_storage.safelyParseJSON)(row.requestContextSchema) : void 0,
5842
5855
  tags: row.tags ? (0, _mastra_core_storage.safelyParseJSON)(row.tags) : void 0,
5843
- targetType: row.targetType || null,
5844
- targetIds: row.targetIds || null,
5845
- scorerIds: row.scorerIds || null,
5856
+ targetType: row.targetType || void 0,
5857
+ targetIds: row.targetIds ?? void 0,
5858
+ scorerIds: row.scorerIds ?? void 0,
5846
5859
  organizationId: row.organizationId ?? null,
5847
5860
  projectId: row.projectId ?? null,
5848
5861
  candidateKey: row.candidateKey ?? null,
@@ -5944,9 +5957,9 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
5944
5957
  inputSchema: input.inputSchema ?? void 0,
5945
5958
  groundTruthSchema: input.groundTruthSchema ?? void 0,
5946
5959
  requestContextSchema: input.requestContextSchema ?? void 0,
5947
- targetType: input.targetType ?? null,
5948
- targetIds: input.targetIds ?? null,
5949
- scorerIds: input.scorerIds ?? null,
5960
+ targetType: input.targetType ?? void 0,
5961
+ targetIds: input.targetIds ?? void 0,
5962
+ scorerIds: input.scorerIds ?? void 0,
5950
5963
  organizationId: input.organizationId ?? null,
5951
5964
  projectId: input.projectId ?? null,
5952
5965
  candidateKey: input.candidateKey ?? null,
@@ -6073,9 +6086,9 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6073
6086
  groundTruthSchema: (args.groundTruthSchema !== void 0 ? args.groundTruthSchema : existing.groundTruthSchema) ?? void 0,
6074
6087
  requestContextSchema: (args.requestContextSchema !== void 0 ? args.requestContextSchema : existing.requestContextSchema) ?? void 0,
6075
6088
  tags: (args.tags !== void 0 ? args.tags : existing.tags) ?? void 0,
6076
- targetType: (args.targetType !== void 0 ? args.targetType : existing.targetType) ?? null,
6077
- targetIds: (args.targetIds !== void 0 ? args.targetIds : existing.targetIds) ?? null,
6078
- scorerIds: (args.scorerIds !== void 0 ? args.scorerIds : existing.scorerIds) ?? null,
6089
+ targetType: (args.targetType !== void 0 ? args.targetType : existing.targetType) ?? void 0,
6090
+ targetIds: (args.targetIds !== void 0 ? args.targetIds : existing.targetIds) ?? void 0,
6091
+ scorerIds: (args.scorerIds !== void 0 ? args.scorerIds : existing.scorerIds) ?? void 0,
6079
6092
  organizationId: existing.organizationId ?? null,
6080
6093
  projectId: existing.projectId ?? null,
6081
6094
  candidateKey: existing.candidateKey ?? null,
@@ -6253,8 +6266,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6253
6266
  parentOrganizationId,
6254
6267
  parentProjectId,
6255
6268
  JSON.stringify(args.input),
6256
- jsonbArg(args.groundTruth),
6257
- jsonbArg(args.expectedTrajectory),
6269
+ jsonDataArg(args.groundTruth),
6270
+ jsonDataArg(args.expectedTrajectory),
6258
6271
  jsonbArg(args.toolMocks),
6259
6272
  args.unmockedToolPolicy ?? null,
6260
6273
  jsonbArg(args.scorerIds),
@@ -6370,8 +6383,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6370
6383
  parentOrganizationId,
6371
6384
  parentProjectId,
6372
6385
  JSON.stringify(mergedInput),
6373
- jsonbArg(mergedGroundTruth),
6374
- jsonbArg(mergedExpectedTrajectory),
6386
+ jsonDataArg(mergedGroundTruth),
6387
+ jsonDataArg(mergedExpectedTrajectory),
6375
6388
  jsonbArg(mergedToolMocks),
6376
6389
  mergedUnmockedToolPolicy ?? null,
6377
6390
  jsonbArg(mergedScorerIds),
@@ -6460,8 +6473,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6460
6473
  parentOrganizationId,
6461
6474
  parentProjectId,
6462
6475
  JSON.stringify(existing.input),
6463
- jsonbArg(existing.groundTruth),
6464
- jsonbArg(existing.expectedTrajectory),
6476
+ jsonDataArg(existing.groundTruth),
6477
+ jsonDataArg(existing.expectedTrajectory),
6465
6478
  jsonbArg(existing.toolMocks),
6466
6479
  existing.unmockedToolPolicy ?? null,
6467
6480
  jsonbArg(existing.scorerIds),
@@ -6561,7 +6574,7 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6561
6574
  details: { datasetId: input.datasetId }
6562
6575
  });
6563
6576
  const externalIds = [...new Set(input.items.flatMap((item) => item.externalId ? [item.externalId] : []))];
6564
- const historyRows = externalIds.length ? await t.manyOrNone(`SELECT * FROM ${itemsTable} WHERE "datasetId" = $1 AND "externalId" = ANY($2::text[]) ORDER BY "datasetVersion"`, [input.datasetId, externalIds]) : [];
6577
+ const historyRows = externalIds.length ? await t.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${itemsTable} WHERE "datasetId" = $1 AND "externalId" = ANY($2::text[]) ORDER BY "datasetVersion"`, [input.datasetId, externalIds]) : [];
6565
6578
  const plan = this.planDatasetItemBatch(input.items, historyRows.map((row) => this.transformItemRowFull(row)), () => crypto.randomUUID());
6566
6579
  const resolved = new Map([...plan.existingCurrentItems].map(([id, row]) => [id, this.datasetItemFromRow(row)]));
6567
6580
  if (plan.inserts.length > 0) {
@@ -6578,8 +6591,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6578
6591
  dataset.organizationId ?? null,
6579
6592
  dataset.projectId ?? null,
6580
6593
  JSON.stringify(item.input),
6581
- jsonbArg(item.groundTruth),
6582
- jsonbArg(item.expectedTrajectory),
6594
+ jsonDataArg(item.groundTruth),
6595
+ jsonDataArg(item.expectedTrajectory),
6583
6596
  jsonbArg(item.toolMocks),
6584
6597
  item.unmockedToolPolicy ?? null,
6585
6598
  jsonbArg(item.scorerIds),
@@ -6656,7 +6669,7 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6656
6669
  category: _mastra_core_error.ErrorCategory.USER,
6657
6670
  details: { datasetId: input.datasetId }
6658
6671
  });
6659
- const currentItems = (await t.manyOrNone(`SELECT * FROM ${itemsTable} WHERE "id" = ANY($1::text[]) AND "datasetId" = $2 AND "validTo" IS NULL AND "isDeleted" = false`, [input.itemIds, input.datasetId])).map((row) => this.transformItemRow(row));
6672
+ const currentItems = (await t.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${itemsTable} WHERE "id" = ANY($1::text[]) AND "datasetId" = $2 AND "validTo" IS NULL AND "isDeleted" = false`, [input.itemIds, input.datasetId])).map((row) => this.transformItemRow(row));
6660
6673
  if (currentItems.length === 0) return;
6661
6674
  const parentOrganizationId = dataset.organizationId ?? null;
6662
6675
  const parentProjectId = dataset.projectId ?? null;
@@ -6671,8 +6684,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6671
6684
  parentOrganizationId,
6672
6685
  parentProjectId,
6673
6686
  JSON.stringify(item.input),
6674
- jsonbArg(item.groundTruth),
6675
- jsonbArg(item.expectedTrajectory),
6687
+ jsonDataArg(item.groundTruth),
6688
+ jsonDataArg(item.expectedTrajectory),
6676
6689
  jsonbArg(item.toolMocks),
6677
6690
  item.unmockedToolPolicy ?? null,
6678
6691
  jsonbArg(item.scorerIds),
@@ -6712,8 +6725,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6712
6725
  schemaName: getSchemaName$5(this.#schema)
6713
6726
  });
6714
6727
  let result;
6715
- if (args.datasetVersion !== void 0) result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $2) AND "isDeleted" = false ORDER BY "datasetVersion" DESC LIMIT 1`, [args.id, args.datasetVersion]);
6716
- else result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 AND "validTo" IS NULL AND "isDeleted" = false`, [args.id]);
6728
+ if (args.datasetVersion !== void 0) result = await client.oneOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "id" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $2) AND "isDeleted" = false ORDER BY "datasetVersion" DESC LIMIT 1`, [args.id, args.datasetVersion]);
6729
+ else result = await client.oneOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "id" = $1 AND "validTo" IS NULL AND "isDeleted" = false`, [args.id]);
6717
6730
  return result ? this.transformItemRow(result) : null;
6718
6731
  } catch (error) {
6719
6732
  throw new _mastra_core_error.MastraError({
@@ -6729,7 +6742,7 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6729
6742
  indexName: _mastra_core_storage.TABLE_DATASET_ITEMS,
6730
6743
  schemaName: getSchemaName$5(this.#schema)
6731
6744
  });
6732
- return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "datasetId" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $3) AND "isDeleted" = false ORDER BY "createdAt" DESC, "id" ASC`, [
6745
+ return (await this.#db.readClient.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "datasetId" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $3) AND "isDeleted" = false ORDER BY "createdAt" DESC, "id" ASC`, [
6733
6746
  datasetId,
6734
6747
  version,
6735
6748
  version
@@ -6748,7 +6761,7 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6748
6761
  indexName: _mastra_core_storage.TABLE_DATASET_ITEMS,
6749
6762
  schemaName: getSchemaName$5(this.#schema)
6750
6763
  });
6751
- return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`, [itemId]) || []).map((row) => this.transformItemRowFull(row));
6764
+ return (await this.#db.readClient.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`, [itemId]) || []).map((row) => this.transformItemRowFull(row));
6752
6765
  } catch (error) {
6753
6766
  throw new _mastra_core_error.MastraError({
6754
6767
  id: (0, _mastra_core_storage.createStorageErrorId)("PG", "GET_ITEM_HISTORY", "FAILED"),
@@ -6820,7 +6833,7 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6820
6833
  const { offset, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
6821
6834
  const limitValue = perPageInput === false ? total : perPage;
6822
6835
  return {
6823
- items: (await client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${orderBy.field}" ${orderBy.direction}, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6836
+ items: (await client.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} ${whereClause} ORDER BY "${orderBy.field}" ${orderBy.direction}, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6824
6837
  ...queryParams,
6825
6838
  limitValue,
6826
6839
  offset
@@ -17270,7 +17283,8 @@ const TRACE_FIELDS = {
17270
17283
  entityName: "r.\"entityName\"",
17271
17284
  entityType: "r.\"entityType\"",
17272
17285
  environment: "r.\"environment\"",
17273
- status: TRACE_STATUS_SQL
17286
+ status: TRACE_STATUS_SQL,
17287
+ tags: "r.\"tags\""
17274
17288
  };
17275
17289
  const SPAN_FIELDS = {
17276
17290
  name: "s.\"name\"",
@@ -17372,6 +17386,19 @@ function compileScalarPredicate(predicate, registry, parameterOffset, allowMetad
17372
17386
  sql: `${field} IS ${predicate.operator === "exists" ? "NOT " : ""}NULL`,
17373
17387
  values: fieldValues
17374
17388
  };
17389
+ if (predicate.type === "collection") {
17390
+ if (predicate.operator === "includes" || predicate.operator === "notIncludes") {
17391
+ const contains = `${field} @> ARRAY[$${parameterOffset}]::text[]`;
17392
+ return {
17393
+ sql: predicate.operator === "includes" ? contains : `cardinality(${field}) > 0 AND NOT (${contains})`,
17394
+ values: [...fieldValues, predicate.value]
17395
+ };
17396
+ }
17397
+ return {
17398
+ sql: `cardinality(${field}) ${predicate.operator === "empty" ? "=" : ">"} 0`,
17399
+ values: fieldValues
17400
+ };
17401
+ }
17375
17402
  if (predicate.type === "membership") {
17376
17403
  const list = placeholders(predicate.values, parameterOffset);
17377
17404
  if (predicate.operator === "in") return {
@@ -17425,6 +17452,7 @@ function compileFeedbackScalarPredicate(predicate, parameterOffset) {
17425
17452
  };
17426
17453
  }
17427
17454
  if (predicate.field !== "value") return compileScalarPredicate(predicate, FEEDBACK_FIELDS, parameterOffset);
17455
+ if (predicate.type === "collection") throw new Error(`Unsupported trusted trace-query field: ${predicate.field}`);
17428
17456
  if (predicate.type === "presence") {
17429
17457
  const present = `(s."valueString" IS NOT NULL OR s."valueNumber" IS NOT NULL)`;
17430
17458
  return {
@@ -17808,22 +17836,23 @@ LIMIT $${values.length}`,
17808
17836
  }
17809
17837
  function compilePostgresTraceQueryValues(schema, plan) {
17810
17838
  const { ctes, values } = compilePostgresTraceScope(schema, plan, discoveryCollections(plan.predicateScope), plan.scope);
17811
- let field;
17812
- if (plan.predicateScope === "trace" && plan.path.startsWith("metadata.")) {
17839
+ let extracted;
17840
+ if (plan.predicateScope === "trace" && plan.path === "tags") extracted = `SELECT value FROM (SELECT DISTINCT r."traceId", UNNEST(r."tags") AS value FROM root_scope r) t`;
17841
+ else if (plan.predicateScope === "trace" && plan.path.startsWith("metadata.")) {
17813
17842
  const keyParameter = `$${values.length + 1}`;
17814
- field = `COALESCE(
17843
+ extracted = `SELECT COALESCE(
17815
17844
  CASE WHEN jsonb_typeof(r."metadataSearch" -> ${keyParameter}) = 'string' THEN r."metadataSearch" ->> ${keyParameter} END,
17816
17845
  CASE WHEN jsonb_typeof(r."metadataRaw" -> ${keyParameter}) = 'string' THEN NULLIF(btrim(r."metadataRaw" ->> ${keyParameter}), '') END
17817
- )`;
17846
+ )::text AS value FROM root_scope r`;
17818
17847
  values.push(plan.path.slice(9));
17819
- } else field = fieldSql(discoveryRegistry(plan.predicateScope), plan.path);
17848
+ } else extracted = `SELECT ${fieldSql(discoveryRegistry(plan.predicateScope), plan.path)}::text AS value FROM ${discoverySource(plan.predicateScope)}`;
17820
17849
  const searchParameter = values.length + 1;
17821
17850
  const search = plan.search ? `AND strpos(lower(value), lower($${searchParameter})) > 0` : "";
17822
17851
  if (plan.search) values.push(plan.search);
17823
17852
  values.push(plan.limit + 1);
17824
17853
  return {
17825
17854
  text: `WITH ${ctes.join(",\n")}, extracted AS (
17826
- SELECT ${field}::text AS value FROM ${discoverySource(plan.predicateScope)}
17855
+ ${extracted}
17827
17856
  )
17828
17857
  SELECT value, count(*)::bigint AS count
17829
17858
  FROM extracted