@mastra/pg 1.23.0-alpha.5 → 1.23.0-alpha.7
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/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +328 -166
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +328 -166
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/datasets/index.d.ts +2 -1
- package/dist/storage/domains/datasets/index.d.ts.map +1 -1
- package/dist/storage/domains/experiments/index.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/vector/index.d.ts +9 -8
- package/dist/vector/index.d.ts.map +1 -1
- package/dist/vector/namespace-test-utils.d.ts +9 -0
- package/dist/vector/namespace-test-utils.d.ts.map +1 -0
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -560,6 +560,8 @@ var PgVector = class extends MastraVector {
|
|
|
560
560
|
indexMetadataCache = /* @__PURE__ */ new Map();
|
|
561
561
|
createdIndexes = /* @__PURE__ */ new Map();
|
|
562
562
|
namespaceReadyIndexes = /* @__PURE__ */ new Set();
|
|
563
|
+
/** In-flight lazy namespace migrations, keyed by index name (see {@link ensureNamespaceReady}). */
|
|
564
|
+
namespaceReadyCache = /* @__PURE__ */ new Map();
|
|
563
565
|
indexVectorTypes = /* @__PURE__ */ new Map();
|
|
564
566
|
mutexesByName = /* @__PURE__ */ new Map();
|
|
565
567
|
schema;
|
|
@@ -804,8 +806,10 @@ var PgVector = class extends MastraVector {
|
|
|
804
806
|
AND attnum > 0
|
|
805
807
|
AND NOT attisdropped`, [tableName])).rowCount === 0) return;
|
|
806
808
|
await client.query(`ALTER TABLE ${tableName} ADD COLUMN IF NOT EXISTS namespace VARCHAR(255) NOT NULL DEFAULT '${DEFAULT_NAMESPACE}'`);
|
|
807
|
-
|
|
808
|
-
|
|
809
|
+
if (!(await this.getNamespaceSchemaState(tableName, client)).composite_index) {
|
|
810
|
+
const namespaceIndexName = this.getNamespaceIndexName(parsedIndexName);
|
|
811
|
+
await client.query(`CREATE UNIQUE INDEX IF NOT EXISTS "${namespaceIndexName}" ON ${tableName} (namespace, vector_id)`);
|
|
812
|
+
}
|
|
809
813
|
const legacyConstraints = await client.query(`SELECT c.conname
|
|
810
814
|
FROM pg_constraint c
|
|
811
815
|
WHERE c.conrelid = to_regclass($1)
|
|
@@ -816,21 +820,84 @@ var PgVector = class extends MastraVector {
|
|
|
816
820
|
await client.query(`ALTER TABLE ${tableName} DROP CONSTRAINT "${parsedConstraintName}"`);
|
|
817
821
|
}
|
|
818
822
|
}
|
|
819
|
-
/**
|
|
820
|
-
* Name of the unique (namespace, vector_id) index for a table.
|
|
821
|
-
*
|
|
822
|
-
* The full `<index>_namespace_vector_id_idx` name is kept whenever it fits so tables that
|
|
823
|
-
* were already migrated keep matching `IF NOT EXISTS`. Longer index names would exceed
|
|
824
|
-
* Postgres' 63-char identifier limit, so those fall back to a truncated prefix plus a hash
|
|
825
|
-
* of the index name to distinguish tables that
|
|
826
|
-
* share a long prefix.
|
|
827
|
-
*/
|
|
828
823
|
getNamespaceIndexName(parsedIndexName) {
|
|
829
824
|
const fullName = `${parsedIndexName}_namespace_vector_id_idx`;
|
|
830
825
|
if (fullName.length <= 63) return fullName;
|
|
831
826
|
const suffix = `_ns_${createHash("sha256").update(parsedIndexName).digest("hex").slice(0, 32)}_idx`;
|
|
832
827
|
return `${parsedIndexName.slice(0, 63 - suffix.length)}${suffix}`;
|
|
833
828
|
}
|
|
829
|
+
async getNamespaceSchemaState(tableName, client) {
|
|
830
|
+
return (await client.query(`SELECT
|
|
831
|
+
EXISTS (SELECT 1 FROM pg_attribute WHERE attrelid = to_regclass($1)
|
|
832
|
+
AND attname = 'vector_id' AND attnum > 0 AND NOT attisdropped) AS vector_id,
|
|
833
|
+
EXISTS (SELECT 1 FROM pg_attribute WHERE attrelid = to_regclass($1)
|
|
834
|
+
AND attname = 'namespace' AND attnum > 0 AND NOT attisdropped) AS namespace,
|
|
835
|
+
EXISTS (
|
|
836
|
+
SELECT 1 FROM pg_index i
|
|
837
|
+
WHERE i.indrelid = to_regclass($1)
|
|
838
|
+
AND i.indisunique AND i.indisvalid AND i.indisready AND i.indimmediate
|
|
839
|
+
AND i.indpred IS NULL AND i.indexprs IS NULL AND i.indnkeyatts = 2
|
|
840
|
+
AND (SELECT array_agg(a.attname::text ORDER BY a.attname)
|
|
841
|
+
FROM unnest(i.indkey) WITH ORDINALITY AS k(attnum, position)
|
|
842
|
+
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = k.attnum
|
|
843
|
+
WHERE k.position <= i.indnkeyatts) = ARRAY['namespace', 'vector_id']
|
|
844
|
+
) AS composite_index,
|
|
845
|
+
EXISTS (SELECT 1 FROM pg_constraint WHERE conrelid = to_regclass($1)
|
|
846
|
+
AND contype = 'u' AND pg_get_constraintdef(oid) = 'UNIQUE (vector_id)') AS legacy_constraint`, [tableName])).rows[0];
|
|
847
|
+
}
|
|
848
|
+
async reconcileNamespace(indexName, client) {
|
|
849
|
+
const { tableName } = this.getTableName(indexName);
|
|
850
|
+
await client.query("BEGIN");
|
|
851
|
+
try {
|
|
852
|
+
await client.query("SELECT pg_advisory_xact_lock((1936876916::bigint << 32) | to_regclass($1)::oid::bigint)", [tableName]);
|
|
853
|
+
const state = await this.getNamespaceSchemaState(tableName, client);
|
|
854
|
+
if (!state.vector_id) {
|
|
855
|
+
await client.query("ROLLBACK");
|
|
856
|
+
return false;
|
|
857
|
+
}
|
|
858
|
+
if (!state.namespace || !state.composite_index || state.legacy_constraint) {
|
|
859
|
+
if (this.disableInit || process.env.MASTRA_DISABLE_STORAGE_INIT === "true") throw new MastraError({
|
|
860
|
+
id: createVectorErrorId("PG", "ENSURE_NAMESPACE", "MIGRATION_REQUIRED"),
|
|
861
|
+
domain: ErrorDomain.MASTRA_VECTOR,
|
|
862
|
+
category: ErrorCategory.USER,
|
|
863
|
+
text: `Vector index "${indexName}" requires namespace migration and schema changes are disabled. Call createIndex({ indexName: "${indexName}", dimension }) with init enabled, or apply the namespace migration SQL from the @mastra/pg changelog.`,
|
|
864
|
+
details: { indexName }
|
|
865
|
+
});
|
|
866
|
+
await this.ensureNamespaceSchema(indexName, client);
|
|
867
|
+
const migrated = await this.getNamespaceSchemaState(tableName, client);
|
|
868
|
+
if (!migrated.namespace || !migrated.composite_index || migrated.legacy_constraint) throw new MastraError({
|
|
869
|
+
id: createVectorErrorId("PG", "ENSURE_NAMESPACE", "MIGRATION_REQUIRED"),
|
|
870
|
+
domain: ErrorDomain.MASTRA_VECTOR,
|
|
871
|
+
category: ErrorCategory.USER,
|
|
872
|
+
text: `Vector index "${indexName}" requires a valid unique (namespace, vector_id) index. Resolve conflicting index names and retry the namespace migration.`,
|
|
873
|
+
details: { indexName }
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
await client.query("COMMIT");
|
|
877
|
+
return true;
|
|
878
|
+
} catch (error) {
|
|
879
|
+
await client.query("ROLLBACK");
|
|
880
|
+
throw error;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Every data path filters on `namespace`, but tables created before that column existed are
|
|
885
|
+
* only migrated by `createIndex()`, which callers are not required to invoke before reading.
|
|
886
|
+
* Run the migration lazily instead, once per index per process.
|
|
887
|
+
*/
|
|
888
|
+
ensureNamespaceReady(indexName) {
|
|
889
|
+
if (this.namespaceReadyIndexes.has(indexName)) return Promise.resolve();
|
|
890
|
+
return this.memoize(this.namespaceReadyCache, indexName, () => this.getMutexByName(`create-${indexName}`).runExclusive(async () => {
|
|
891
|
+
if (this.namespaceReadyIndexes.has(indexName)) return;
|
|
892
|
+
const client = await this.pool.connect();
|
|
893
|
+
try {
|
|
894
|
+
if (await this.reconcileNamespace(indexName, client)) this.namespaceReadyIndexes.add(indexName);
|
|
895
|
+
else this.namespaceReadyCache.delete(indexName);
|
|
896
|
+
} finally {
|
|
897
|
+
client.release();
|
|
898
|
+
}
|
|
899
|
+
}));
|
|
900
|
+
}
|
|
834
901
|
transformFilter(filter) {
|
|
835
902
|
return new PGFilterTranslator().translate(filter);
|
|
836
903
|
}
|
|
@@ -888,8 +955,10 @@ var PgVector = class extends MastraVector {
|
|
|
888
955
|
throw mastraError;
|
|
889
956
|
}
|
|
890
957
|
if (queryVector === void 0) {
|
|
891
|
-
|
|
958
|
+
let client;
|
|
892
959
|
try {
|
|
960
|
+
await this.ensureNamespaceReady(indexName);
|
|
961
|
+
client = await this.pool.connect();
|
|
893
962
|
const { sql: filterQuery, values: filterValues } = buildDeleteFilterQuery(this.transformFilter(filter));
|
|
894
963
|
const { tableName } = this.getTableName(indexName);
|
|
895
964
|
const filterClause = filterQuery.trim().replace(/^WHERE\s+/i, "");
|
|
@@ -915,6 +984,10 @@ var PgVector = class extends MastraVector {
|
|
|
915
984
|
...includeVector && embedding && { vector: JSON.parse(embedding) }
|
|
916
985
|
}));
|
|
917
986
|
} catch (error) {
|
|
987
|
+
if (error instanceof MastraError) {
|
|
988
|
+
this.logger?.trackException(error);
|
|
989
|
+
throw error;
|
|
990
|
+
}
|
|
918
991
|
const mastraError = new MastraError({
|
|
919
992
|
id: createVectorErrorId("PG", "QUERY", "FAILED"),
|
|
920
993
|
domain: ErrorDomain.MASTRA_VECTOR,
|
|
@@ -924,12 +997,14 @@ var PgVector = class extends MastraVector {
|
|
|
924
997
|
this.logger?.trackException(mastraError);
|
|
925
998
|
throw mastraError;
|
|
926
999
|
} finally {
|
|
927
|
-
client
|
|
1000
|
+
client?.release();
|
|
928
1001
|
}
|
|
929
1002
|
}
|
|
930
|
-
|
|
931
|
-
const client = await this.pool.connect();
|
|
1003
|
+
let client;
|
|
932
1004
|
try {
|
|
1005
|
+
await this.ensureNamespaceReady(indexName);
|
|
1006
|
+
const indexInfo = await this.getIndexMetadata({ indexName });
|
|
1007
|
+
client = await this.pool.connect();
|
|
933
1008
|
await this.ensureSearchPath(client);
|
|
934
1009
|
await client.query("BEGIN");
|
|
935
1010
|
const { sql: filterQuery, values: filterValues } = buildFilterQuery(this.transformFilter(filter), minScore, topK);
|
|
@@ -991,7 +1066,11 @@ var PgVector = class extends MastraVector {
|
|
|
991
1066
|
...includeVector && embedding && { vector: ops.parseEmbedding(embedding) }
|
|
992
1067
|
}));
|
|
993
1068
|
} catch (error) {
|
|
994
|
-
await client
|
|
1069
|
+
await client?.query("ROLLBACK");
|
|
1070
|
+
if (error instanceof MastraError) {
|
|
1071
|
+
this.logger?.trackException(error);
|
|
1072
|
+
throw error;
|
|
1073
|
+
}
|
|
995
1074
|
const mastraError = new MastraError({
|
|
996
1075
|
id: createVectorErrorId("PG", "QUERY", "FAILED"),
|
|
997
1076
|
domain: ErrorDomain.MASTRA_VECTOR,
|
|
@@ -1001,15 +1080,17 @@ var PgVector = class extends MastraVector {
|
|
|
1001
1080
|
this.logger?.trackException(mastraError);
|
|
1002
1081
|
throw mastraError;
|
|
1003
1082
|
} finally {
|
|
1004
|
-
client
|
|
1083
|
+
client?.release();
|
|
1005
1084
|
}
|
|
1006
1085
|
}
|
|
1007
1086
|
async upsert({ indexName, vectors, metadata, ids, deleteFilter, namespace = DEFAULT_NAMESPACE }) {
|
|
1008
1087
|
validateUpsertInput("PG", vectors, metadata, ids);
|
|
1009
1088
|
const { tableName } = this.getTableName(indexName);
|
|
1010
|
-
|
|
1011
|
-
const client = await this.pool.connect();
|
|
1089
|
+
let client;
|
|
1012
1090
|
try {
|
|
1091
|
+
const indexInfo = await this.getIndexMetadata({ indexName });
|
|
1092
|
+
await this.ensureNamespaceReady(indexName);
|
|
1093
|
+
client = await this.pool.connect();
|
|
1013
1094
|
await this.ensureSearchPath(client);
|
|
1014
1095
|
await client.query("BEGIN");
|
|
1015
1096
|
if (deleteFilter) {
|
|
@@ -1075,7 +1156,11 @@ var PgVector = class extends MastraVector {
|
|
|
1075
1156
|
});
|
|
1076
1157
|
return vectorIds;
|
|
1077
1158
|
} catch (error) {
|
|
1078
|
-
await client
|
|
1159
|
+
await client?.query("ROLLBACK");
|
|
1160
|
+
if (error instanceof MastraError) {
|
|
1161
|
+
this.logger?.trackException(error);
|
|
1162
|
+
throw error;
|
|
1163
|
+
}
|
|
1079
1164
|
if (error instanceof Error && error.message?.includes("expected") && error.message?.includes("dimensions")) {
|
|
1080
1165
|
const match = error.message.match(/expected (\d+) dimensions, not (\d+)/);
|
|
1081
1166
|
if (match) {
|
|
@@ -1104,7 +1189,7 @@ var PgVector = class extends MastraVector {
|
|
|
1104
1189
|
this.logger?.trackException(mastraError);
|
|
1105
1190
|
throw mastraError;
|
|
1106
1191
|
} finally {
|
|
1107
|
-
client
|
|
1192
|
+
client?.release();
|
|
1108
1193
|
}
|
|
1109
1194
|
}
|
|
1110
1195
|
hasher = xxhash();
|
|
@@ -1232,9 +1317,8 @@ var PgVector = class extends MastraVector {
|
|
|
1232
1317
|
namespace VARCHAR(255) NOT NULL DEFAULT '${DEFAULT_NAMESPACE}'
|
|
1233
1318
|
);
|
|
1234
1319
|
`);
|
|
1235
|
-
await this.
|
|
1320
|
+
if (await this.reconcileNamespace(indexName, client)) this.namespaceReadyIndexes.add(indexName);
|
|
1236
1321
|
this.createdIndexes.set(indexName, indexCacheKey);
|
|
1237
|
-
this.namespaceReadyIndexes.add(indexName);
|
|
1238
1322
|
this.indexVectorTypes.set(indexName, vectorType);
|
|
1239
1323
|
if (buildIndex) await this.setupIndex({
|
|
1240
1324
|
indexName,
|
|
@@ -1246,6 +1330,7 @@ var PgVector = class extends MastraVector {
|
|
|
1246
1330
|
} catch (error) {
|
|
1247
1331
|
this.createdIndexes.delete(indexName);
|
|
1248
1332
|
this.namespaceReadyIndexes.delete(indexName);
|
|
1333
|
+
this.namespaceReadyCache.delete(indexName);
|
|
1249
1334
|
this.indexVectorTypes.delete(indexName);
|
|
1250
1335
|
throw error;
|
|
1251
1336
|
} finally {
|
|
@@ -1620,27 +1705,30 @@ var PgVector = class extends MastraVector {
|
|
|
1620
1705
|
}
|
|
1621
1706
|
}
|
|
1622
1707
|
async deleteIndex({ indexName }) {
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1708
|
+
await this.getMutexByName(`create-${indexName}`).runExclusive(async () => {
|
|
1709
|
+
const client = await this.pool.connect();
|
|
1710
|
+
try {
|
|
1711
|
+
const { tableName } = this.getTableName(indexName);
|
|
1712
|
+
await client.query(`DROP TABLE IF EXISTS ${tableName} CASCADE`);
|
|
1713
|
+
this.createdIndexes.delete(indexName);
|
|
1714
|
+
this.namespaceReadyIndexes.delete(indexName);
|
|
1715
|
+
this.namespaceReadyCache.delete(indexName);
|
|
1716
|
+
this.indexVectorTypes.delete(indexName);
|
|
1717
|
+
this.invalidateIndexCaches(indexName);
|
|
1718
|
+
} catch (error) {
|
|
1719
|
+
await client.query("ROLLBACK");
|
|
1720
|
+
const mastraError = new MastraError({
|
|
1721
|
+
id: createVectorErrorId("PG", "DELETE_INDEX", "FAILED"),
|
|
1722
|
+
domain: ErrorDomain.MASTRA_VECTOR,
|
|
1723
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1724
|
+
details: { indexName }
|
|
1725
|
+
}, error);
|
|
1726
|
+
this.logger?.trackException(mastraError);
|
|
1727
|
+
throw mastraError;
|
|
1728
|
+
} finally {
|
|
1729
|
+
client.release();
|
|
1730
|
+
}
|
|
1731
|
+
});
|
|
1644
1732
|
}
|
|
1645
1733
|
async truncateIndex({ indexName }) {
|
|
1646
1734
|
const client = await this.pool.connect();
|
|
@@ -1696,6 +1784,7 @@ var PgVector = class extends MastraVector {
|
|
|
1696
1784
|
details: { indexName }
|
|
1697
1785
|
});
|
|
1698
1786
|
const indexInfo = await this.getIndexMetadata({ indexName });
|
|
1787
|
+
await this.ensureNamespaceReady(indexName);
|
|
1699
1788
|
client = await this.pool.connect();
|
|
1700
1789
|
await this.ensureSearchPath(client);
|
|
1701
1790
|
const { tableName } = this.getTableName(indexName);
|
|
@@ -1789,6 +1878,7 @@ var PgVector = class extends MastraVector {
|
|
|
1789
1878
|
async deleteVector({ indexName, id, namespace = DEFAULT_NAMESPACE }) {
|
|
1790
1879
|
let client;
|
|
1791
1880
|
try {
|
|
1881
|
+
await this.ensureNamespaceReady(indexName);
|
|
1792
1882
|
client = await this.pool.connect();
|
|
1793
1883
|
const { tableName } = this.getTableName(indexName);
|
|
1794
1884
|
const query = `
|
|
@@ -1797,6 +1887,7 @@ var PgVector = class extends MastraVector {
|
|
|
1797
1887
|
`;
|
|
1798
1888
|
await client.query(query, [id, namespace]);
|
|
1799
1889
|
} catch (error) {
|
|
1890
|
+
if (error instanceof MastraError) throw error;
|
|
1800
1891
|
const mastraError = new MastraError({
|
|
1801
1892
|
id: createVectorErrorId("PG", "DELETE_VECTOR", "FAILED"),
|
|
1802
1893
|
domain: ErrorDomain.MASTRA_VECTOR,
|
|
@@ -1823,6 +1914,7 @@ var PgVector = class extends MastraVector {
|
|
|
1823
1914
|
let client;
|
|
1824
1915
|
const effectiveNamespace = namespace ?? DEFAULT_NAMESPACE;
|
|
1825
1916
|
try {
|
|
1917
|
+
await this.ensureNamespaceReady(indexName);
|
|
1826
1918
|
client = await this.pool.connect();
|
|
1827
1919
|
const { tableName } = this.getTableName(indexName);
|
|
1828
1920
|
if (!filter && !ids && namespace === void 0) throw new MastraError({
|
|
@@ -5553,6 +5645,17 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
|
|
|
5553
5645
|
function jsonbArg(value) {
|
|
5554
5646
|
return value === void 0 || value === null ? null : JSON.stringify(value);
|
|
5555
5647
|
}
|
|
5648
|
+
function parseStoredJSON(value) {
|
|
5649
|
+
if (typeof value === "string") try {
|
|
5650
|
+
return JSON.parse(value);
|
|
5651
|
+
} catch {
|
|
5652
|
+
return value;
|
|
5653
|
+
}
|
|
5654
|
+
return value;
|
|
5655
|
+
}
|
|
5656
|
+
function parseOptionalJSON(value, emptyValue) {
|
|
5657
|
+
return value === null || value === void 0 ? emptyValue : parseStoredJSON(value);
|
|
5658
|
+
}
|
|
5556
5659
|
var DatasetsPG = class DatasetsPG extends DatasetsStorage {
|
|
5557
5660
|
#db;
|
|
5558
5661
|
#schema;
|
|
@@ -5729,6 +5832,8 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
|
|
|
5729
5832
|
};
|
|
5730
5833
|
}
|
|
5731
5834
|
transformItemRow(row) {
|
|
5835
|
+
const metadata = parseOptionalJSON(row.metadata, void 0);
|
|
5836
|
+
const emptyValue = metadata?.__purged === true ? null : void 0;
|
|
5732
5837
|
return {
|
|
5733
5838
|
id: row.id,
|
|
5734
5839
|
datasetId: row.datasetId,
|
|
@@ -5736,20 +5841,22 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
|
|
|
5736
5841
|
externalId: row.externalId ?? null,
|
|
5737
5842
|
organizationId: row.organizationId ?? null,
|
|
5738
5843
|
projectId: row.projectId ?? null,
|
|
5739
|
-
input:
|
|
5740
|
-
groundTruth: row.groundTruth
|
|
5741
|
-
expectedTrajectory: row.expectedTrajectory
|
|
5742
|
-
toolMocks: row.toolMocks
|
|
5743
|
-
unmockedToolPolicy: row.unmockedToolPolicy ??
|
|
5744
|
-
scorerIds: row.scorerIds
|
|
5745
|
-
requestContext: row.requestContext
|
|
5746
|
-
metadata
|
|
5747
|
-
source: row.source
|
|
5844
|
+
input: row.input === null ? null : parseStoredJSON(row.input),
|
|
5845
|
+
groundTruth: parseOptionalJSON(row.groundTruth, emptyValue),
|
|
5846
|
+
expectedTrajectory: parseOptionalJSON(row.expectedTrajectory, emptyValue),
|
|
5847
|
+
toolMocks: parseOptionalJSON(row.toolMocks, emptyValue),
|
|
5848
|
+
unmockedToolPolicy: row.unmockedToolPolicy ?? emptyValue,
|
|
5849
|
+
scorerIds: parseOptionalJSON(row.scorerIds, emptyValue),
|
|
5850
|
+
requestContext: parseOptionalJSON(row.requestContext, emptyValue),
|
|
5851
|
+
metadata,
|
|
5852
|
+
source: parseOptionalJSON(row.source, emptyValue),
|
|
5748
5853
|
createdAt: ensureDate(row.createdAtZ || row.createdAt),
|
|
5749
5854
|
updatedAt: ensureDate(row.updatedAtZ || row.updatedAt)
|
|
5750
5855
|
};
|
|
5751
5856
|
}
|
|
5752
5857
|
transformItemRowFull(row) {
|
|
5858
|
+
const metadata = parseOptionalJSON(row.metadata, void 0);
|
|
5859
|
+
const emptyValue = metadata?.__purged === true ? null : void 0;
|
|
5753
5860
|
return {
|
|
5754
5861
|
id: row.id,
|
|
5755
5862
|
datasetId: row.datasetId,
|
|
@@ -5759,15 +5866,15 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
|
|
|
5759
5866
|
projectId: row.projectId ?? null,
|
|
5760
5867
|
validTo: row.validTo,
|
|
5761
5868
|
isDeleted: Boolean(row.isDeleted),
|
|
5762
|
-
input:
|
|
5763
|
-
groundTruth: row.groundTruth
|
|
5764
|
-
expectedTrajectory: row.expectedTrajectory
|
|
5765
|
-
toolMocks: row.toolMocks
|
|
5766
|
-
unmockedToolPolicy: row.unmockedToolPolicy ??
|
|
5767
|
-
scorerIds: row.scorerIds
|
|
5768
|
-
requestContext: row.requestContext
|
|
5769
|
-
metadata
|
|
5770
|
-
source: row.source
|
|
5869
|
+
input: row.input === null ? null : parseStoredJSON(row.input),
|
|
5870
|
+
groundTruth: parseOptionalJSON(row.groundTruth, emptyValue),
|
|
5871
|
+
expectedTrajectory: parseOptionalJSON(row.expectedTrajectory, emptyValue),
|
|
5872
|
+
toolMocks: parseOptionalJSON(row.toolMocks, emptyValue),
|
|
5873
|
+
unmockedToolPolicy: row.unmockedToolPolicy ?? emptyValue,
|
|
5874
|
+
scorerIds: parseOptionalJSON(row.scorerIds, emptyValue),
|
|
5875
|
+
requestContext: parseOptionalJSON(row.requestContext, emptyValue),
|
|
5876
|
+
metadata,
|
|
5877
|
+
source: parseOptionalJSON(row.source, emptyValue),
|
|
5771
5878
|
createdAt: ensureDate(row.createdAtZ || row.createdAt),
|
|
5772
5879
|
updatedAt: ensureDate(row.updatedAtZ || row.updatedAt)
|
|
5773
5880
|
};
|
|
@@ -6343,6 +6450,52 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
|
|
|
6343
6450
|
}, error);
|
|
6344
6451
|
}
|
|
6345
6452
|
}
|
|
6453
|
+
async _doPurgeItem({ id, datasetId }) {
|
|
6454
|
+
try {
|
|
6455
|
+
const datasetsTable = getTableName$5({
|
|
6456
|
+
indexName: TABLE_DATASETS,
|
|
6457
|
+
schemaName: getSchemaName$5(this.#schema)
|
|
6458
|
+
});
|
|
6459
|
+
const itemsTable = getTableName$5({
|
|
6460
|
+
indexName: TABLE_DATASET_ITEMS,
|
|
6461
|
+
schemaName: getSchemaName$5(this.#schema)
|
|
6462
|
+
});
|
|
6463
|
+
const experimentsTable = getTableName$5({
|
|
6464
|
+
indexName: TABLE_EXPERIMENTS,
|
|
6465
|
+
schemaName: getSchemaName$5(this.#schema)
|
|
6466
|
+
});
|
|
6467
|
+
const experimentResultsTable = getTableName$5({
|
|
6468
|
+
indexName: TABLE_EXPERIMENT_RESULTS,
|
|
6469
|
+
schemaName: getSchemaName$5(this.#schema)
|
|
6470
|
+
});
|
|
6471
|
+
const purgedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
6472
|
+
const purgedMetadata = JSON.stringify({
|
|
6473
|
+
__purged: true,
|
|
6474
|
+
purgedAt
|
|
6475
|
+
});
|
|
6476
|
+
await this.#db.client.tx(async (t) => {
|
|
6477
|
+
if (!await t.oneOrNone(`SELECT "id" FROM ${datasetsTable} WHERE "id" = $1 FOR UPDATE`, [datasetId])) return;
|
|
6478
|
+
if (!await t.oneOrNone(`SELECT "id" FROM ${itemsTable} WHERE "id" = $1 AND "datasetId" = $2 LIMIT 1 FOR UPDATE`, [id, datasetId])) return;
|
|
6479
|
+
await t.none(`UPDATE ${itemsTable} SET "input" = 'null'::jsonb, "groundTruth" = NULL, "expectedTrajectory" = NULL, "toolMocks" = NULL, "unmockedToolPolicy" = NULL, "scorerIds" = NULL, "requestContext" = NULL, "metadata" = $2::jsonb, "source" = NULL WHERE "id" = $1 AND "datasetId" = $3`, [
|
|
6480
|
+
id,
|
|
6481
|
+
purgedMetadata,
|
|
6482
|
+
datasetId
|
|
6483
|
+
]);
|
|
6484
|
+
if ((await t.one(`SELECT to_regclass($1) IS NOT NULL AND to_regclass($2) IS NOT NULL AS exists`, [experimentResultsTable, experimentsTable])).exists) await t.none(`UPDATE ${experimentResultsTable} SET "input" = 'null'::jsonb, "output" = NULL, "groundTruth" = NULL, "error" = NULL, "toolMockReport" = NULL, "tags" = NULL, "comment" = NULL, "metadata" = $2::jsonb WHERE "itemId" = $1 AND "experimentId" IN (SELECT "id" FROM ${experimentsTable} WHERE "datasetId" = $3)`, [
|
|
6485
|
+
id,
|
|
6486
|
+
purgedMetadata,
|
|
6487
|
+
datasetId
|
|
6488
|
+
]);
|
|
6489
|
+
});
|
|
6490
|
+
} catch (error) {
|
|
6491
|
+
if (error instanceof MastraError) throw error;
|
|
6492
|
+
throw new MastraError({
|
|
6493
|
+
id: createStorageErrorId("PG", "PURGE_ITEM", "FAILED"),
|
|
6494
|
+
domain: ErrorDomain.STORAGE,
|
|
6495
|
+
category: ErrorCategory.THIRD_PARTY
|
|
6496
|
+
}, error);
|
|
6497
|
+
}
|
|
6498
|
+
}
|
|
6346
6499
|
async _doBatchInsertItems(input) {
|
|
6347
6500
|
try {
|
|
6348
6501
|
if (input.items.length === 0) return [];
|
|
@@ -6994,7 +7147,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
|
|
|
6994
7147
|
itemDatasetVersion: row.itemDatasetVersion != null ? row.itemDatasetVersion : null,
|
|
6995
7148
|
organizationId: row.organizationId ?? null,
|
|
6996
7149
|
projectId: row.projectId ?? null,
|
|
6997
|
-
input: safelyParseJSON(row.input),
|
|
7150
|
+
input: row.input === null ? null : safelyParseJSON(row.input),
|
|
6998
7151
|
output: row.output ? safelyParseJSON(row.output) : null,
|
|
6999
7152
|
groundTruth: row.groundTruth ? safelyParseJSON(row.groundTruth) : null,
|
|
7000
7153
|
metadata: row.metadata ? safelyParseJSON(row.metadata) : null,
|
|
@@ -7296,58 +7449,65 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
|
|
|
7296
7449
|
}, error);
|
|
7297
7450
|
}
|
|
7298
7451
|
}
|
|
7452
|
+
async #resolvePurgeMetadata(t, datasetId, itemId) {
|
|
7453
|
+
if (!datasetId) return null;
|
|
7454
|
+
const datasetsTable = getTableName$5({
|
|
7455
|
+
indexName: TABLE_DATASETS,
|
|
7456
|
+
schemaName: getSchemaName$5(this.#schema)
|
|
7457
|
+
});
|
|
7458
|
+
const itemsTable = getTableName$5({
|
|
7459
|
+
indexName: TABLE_DATASET_ITEMS,
|
|
7460
|
+
schemaName: getSchemaName$5(this.#schema)
|
|
7461
|
+
});
|
|
7462
|
+
if (!await t.oneOrNone(`SELECT "id" FROM ${datasetsTable} WHERE "id" = $1 FOR UPDATE`, [datasetId])) return null;
|
|
7463
|
+
return (await t.oneOrNone(`SELECT "metadata" FROM ${itemsTable}
|
|
7464
|
+
WHERE "id" = $1 AND "datasetId" = $2 AND "metadata"->>'__purged' = 'true'
|
|
7465
|
+
LIMIT 1`, [itemId, datasetId]))?.metadata ?? null;
|
|
7466
|
+
}
|
|
7299
7467
|
async addExperimentResult(input) {
|
|
7300
7468
|
try {
|
|
7301
7469
|
const id = input.id ?? crypto.randomUUID();
|
|
7302
|
-
const
|
|
7303
|
-
|
|
7304
|
-
|
|
7305
|
-
|
|
7306
|
-
|
|
7470
|
+
const resultsTable = getTableName$5({
|
|
7471
|
+
indexName: TABLE_EXPERIMENT_RESULTS,
|
|
7472
|
+
schemaName: getSchemaName$5(this.#schema)
|
|
7473
|
+
});
|
|
7474
|
+
const experimentsTable = getTableName$5({
|
|
7475
|
+
indexName: TABLE_EXPERIMENTS,
|
|
7476
|
+
schemaName: getSchemaName$5(this.#schema)
|
|
7477
|
+
});
|
|
7478
|
+
const row = await this.#db.client.tx(async (t) => {
|
|
7479
|
+
const owner = await t.oneOrNone(`SELECT "datasetId" FROM ${experimentsTable} WHERE "id" = $1`, [input.experimentId]);
|
|
7480
|
+
const purgeMetadata = await this.#resolvePurgeMetadata(t, owner?.datasetId, input.itemId);
|
|
7481
|
+
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
7482
|
+
return t.one(`INSERT INTO ${resultsTable} (
|
|
7483
|
+
"id", "experimentId", "itemId", "itemDatasetVersion", "organizationId", "projectId",
|
|
7484
|
+
"input", "output", "groundTruth", "metadata", "error", "startedAt", "completedAt",
|
|
7485
|
+
"retryCount", "attempt", "traceId", "status", "tags", "toolMockReport", "createdAt"
|
|
7486
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)
|
|
7487
|
+
RETURNING *`, [
|
|
7307
7488
|
id,
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7489
|
+
input.experimentId,
|
|
7490
|
+
input.itemId,
|
|
7491
|
+
input.itemDatasetVersion ?? null,
|
|
7492
|
+
input.organizationId ?? null,
|
|
7493
|
+
input.projectId ?? null,
|
|
7494
|
+
JSON.stringify(purgeMetadata ? null : input.input),
|
|
7495
|
+
purgeMetadata || input.output == null ? null : JSON.stringify(input.output),
|
|
7496
|
+
purgeMetadata || input.groundTruth == null ? null : JSON.stringify(input.groundTruth),
|
|
7497
|
+
JSON.stringify(purgeMetadata ?? input.metadata ?? null),
|
|
7498
|
+
purgeMetadata || input.error == null ? null : JSON.stringify(input.error),
|
|
7499
|
+
input.startedAt.toISOString(),
|
|
7500
|
+
input.completedAt.toISOString(),
|
|
7501
|
+
input.retryCount,
|
|
7502
|
+
input.attempt ?? 0,
|
|
7503
|
+
input.traceId ?? null,
|
|
7504
|
+
input.status ?? null,
|
|
7505
|
+
purgeMetadata || input.tags == null ? null : JSON.stringify(input.tags),
|
|
7506
|
+
purgeMetadata || input.toolMockReport == null ? null : JSON.stringify(input.toolMockReport),
|
|
7507
|
+
nowIso
|
|
7508
|
+
]);
|
|
7328
7509
|
});
|
|
7329
|
-
return
|
|
7330
|
-
id,
|
|
7331
|
-
experimentId: input.experimentId,
|
|
7332
|
-
itemId: input.itemId,
|
|
7333
|
-
itemDatasetVersion: input.itemDatasetVersion ?? null,
|
|
7334
|
-
organizationId: input.organizationId ?? null,
|
|
7335
|
-
projectId: input.projectId ?? null,
|
|
7336
|
-
input: input.input,
|
|
7337
|
-
output: input.output ?? null,
|
|
7338
|
-
groundTruth: input.groundTruth ?? null,
|
|
7339
|
-
metadata: input.metadata ?? null,
|
|
7340
|
-
error: input.error ?? null,
|
|
7341
|
-
startedAt: input.startedAt,
|
|
7342
|
-
completedAt: input.completedAt,
|
|
7343
|
-
retryCount: input.retryCount,
|
|
7344
|
-
attempt: input.attempt ?? 0,
|
|
7345
|
-
traceId: input.traceId ?? null,
|
|
7346
|
-
status: input.status ?? null,
|
|
7347
|
-
tags: input.tags ?? null,
|
|
7348
|
-
toolMockReport: input.toolMockReport ?? null,
|
|
7349
|
-
createdAt: now
|
|
7350
|
-
};
|
|
7510
|
+
return this.transformExperimentResultRow(row);
|
|
7351
7511
|
} catch (error) {
|
|
7352
7512
|
throw new MastraError({
|
|
7353
7513
|
id: createStorageErrorId("PG", "ADD_EXPERIMENT_RESULT", "FAILED"),
|
|
@@ -7362,8 +7522,14 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
|
|
|
7362
7522
|
indexName: TABLE_EXPERIMENT_RESULTS,
|
|
7363
7523
|
schemaName: getSchemaName$5(this.#schema)
|
|
7364
7524
|
});
|
|
7525
|
+
const experimentsTable = getTableName$5({
|
|
7526
|
+
indexName: TABLE_EXPERIMENTS,
|
|
7527
|
+
schemaName: getSchemaName$5(this.#schema)
|
|
7528
|
+
});
|
|
7365
7529
|
const attempt = input.attempt ?? 0;
|
|
7366
7530
|
const row = await this.#db.client.tx(async (t) => {
|
|
7531
|
+
const owner = await t.oneOrNone(`SELECT "datasetId" FROM ${experimentsTable} WHERE "id" = $1`, [input.experimentId]);
|
|
7532
|
+
const purgeMetadata = await this.#resolvePurgeMetadata(t, owner?.datasetId, input.itemId);
|
|
7367
7533
|
const existing = await t.oneOrNone(`SELECT "id" FROM ${tableName} WHERE "experimentId" = $1 AND "itemId" = $2 AND COALESCE("attempt", 0) = $3 FOR UPDATE`, [
|
|
7368
7534
|
input.experimentId,
|
|
7369
7535
|
input.itemId,
|
|
@@ -7383,19 +7549,19 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
|
|
|
7383
7549
|
input.itemDatasetVersion ?? null,
|
|
7384
7550
|
input.organizationId ?? null,
|
|
7385
7551
|
input.projectId ?? null,
|
|
7386
|
-
JSON.stringify(input.input),
|
|
7387
|
-
input.output
|
|
7388
|
-
input.groundTruth
|
|
7389
|
-
|
|
7390
|
-
input.error
|
|
7552
|
+
JSON.stringify(purgeMetadata ? null : input.input),
|
|
7553
|
+
purgeMetadata || input.output == null ? null : JSON.stringify(input.output),
|
|
7554
|
+
purgeMetadata || input.groundTruth == null ? null : JSON.stringify(input.groundTruth),
|
|
7555
|
+
JSON.stringify(purgeMetadata ?? input.metadata ?? null),
|
|
7556
|
+
purgeMetadata || input.error == null ? null : JSON.stringify(input.error),
|
|
7391
7557
|
input.startedAt.toISOString(),
|
|
7392
7558
|
input.completedAt.toISOString(),
|
|
7393
7559
|
input.retryCount,
|
|
7394
7560
|
attempt,
|
|
7395
7561
|
input.traceId ?? null,
|
|
7396
7562
|
input.status ?? null,
|
|
7397
|
-
input.tags
|
|
7398
|
-
input.toolMockReport
|
|
7563
|
+
purgeMetadata || input.tags == null ? null : JSON.stringify(input.tags),
|
|
7564
|
+
purgeMetadata || input.toolMockReport == null ? null : JSON.stringify(input.toolMockReport),
|
|
7399
7565
|
(/* @__PURE__ */ new Date()).toISOString()
|
|
7400
7566
|
]);
|
|
7401
7567
|
}
|
|
@@ -7409,19 +7575,19 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
|
|
|
7409
7575
|
input.itemDatasetVersion ?? null,
|
|
7410
7576
|
input.organizationId ?? null,
|
|
7411
7577
|
input.projectId ?? null,
|
|
7412
|
-
JSON.stringify(input.input),
|
|
7413
|
-
input.output
|
|
7414
|
-
input.groundTruth
|
|
7415
|
-
|
|
7416
|
-
input.error
|
|
7578
|
+
JSON.stringify(purgeMetadata ? null : input.input),
|
|
7579
|
+
purgeMetadata || input.output == null ? null : JSON.stringify(input.output),
|
|
7580
|
+
purgeMetadata || input.groundTruth == null ? null : JSON.stringify(input.groundTruth),
|
|
7581
|
+
JSON.stringify(purgeMetadata ?? input.metadata ?? null),
|
|
7582
|
+
purgeMetadata || input.error == null ? null : JSON.stringify(input.error),
|
|
7417
7583
|
input.startedAt.toISOString(),
|
|
7418
7584
|
input.completedAt.toISOString(),
|
|
7419
7585
|
input.retryCount,
|
|
7420
7586
|
attempt,
|
|
7421
7587
|
input.traceId ?? null,
|
|
7422
7588
|
input.status ?? null,
|
|
7423
|
-
input.tags
|
|
7424
|
-
input.toolMockReport
|
|
7589
|
+
purgeMetadata || input.tags == null ? null : JSON.stringify(input.tags),
|
|
7590
|
+
purgeMetadata || input.toolMockReport == null ? null : JSON.stringify(input.toolMockReport)
|
|
7425
7591
|
]);
|
|
7426
7592
|
});
|
|
7427
7593
|
return this.transformExperimentResultRow(row);
|
|
@@ -7439,39 +7605,34 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
|
|
|
7439
7605
|
indexName: TABLE_EXPERIMENT_RESULTS,
|
|
7440
7606
|
schemaName: getSchemaName$5(this.#schema)
|
|
7441
7607
|
});
|
|
7442
|
-
const
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
paramIndex++;
|
|
7471
|
-
values.push(input.experimentId);
|
|
7472
|
-
whereClause += ` AND "experimentId" = $${paramIndex}`;
|
|
7473
|
-
}
|
|
7474
|
-
const row = await this.#db.client.oneOrNone(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE ${whereClause} RETURNING *`, values);
|
|
7608
|
+
const experimentsTable = getTableName$5({
|
|
7609
|
+
indexName: TABLE_EXPERIMENTS,
|
|
7610
|
+
schemaName: getSchemaName$5(this.#schema)
|
|
7611
|
+
});
|
|
7612
|
+
const row = await this.#db.client.tx(async (t) => {
|
|
7613
|
+
const owner = await t.oneOrNone(`SELECT e."datasetId", r."itemId"
|
|
7614
|
+
FROM ${tableName} r
|
|
7615
|
+
JOIN ${experimentsTable} e ON e."id" = r."experimentId"
|
|
7616
|
+
WHERE r."id" = $1${input.experimentId !== void 0 ? " AND r.\"experimentId\" = $2" : ""}`, input.experimentId !== void 0 ? [input.id, input.experimentId] : [input.id]);
|
|
7617
|
+
if (!owner) return null;
|
|
7618
|
+
const purgeMetadata = await this.#resolvePurgeMetadata(t, owner.datasetId, owner.itemId);
|
|
7619
|
+
return t.oneOrNone(`UPDATE ${tableName}
|
|
7620
|
+
SET "status" = CASE WHEN $2 THEN $3 ELSE "status" END,
|
|
7621
|
+
"tags" = CASE WHEN $4 THEN NULL WHEN $5 THEN $6::jsonb ELSE "tags" END,
|
|
7622
|
+
"comment" = CASE WHEN $4 THEN NULL WHEN $7 THEN $8 ELSE "comment" END
|
|
7623
|
+
WHERE "id" = $1${input.experimentId !== void 0 ? " AND \"experimentId\" = $9" : ""}
|
|
7624
|
+
RETURNING *`, [
|
|
7625
|
+
input.id,
|
|
7626
|
+
input.status !== void 0,
|
|
7627
|
+
input.status ?? null,
|
|
7628
|
+
Boolean(purgeMetadata),
|
|
7629
|
+
input.tags !== void 0,
|
|
7630
|
+
input.tags === void 0 ? null : JSON.stringify(input.tags),
|
|
7631
|
+
input.comment !== void 0,
|
|
7632
|
+
input.comment ?? null,
|
|
7633
|
+
...input.experimentId !== void 0 ? [input.experimentId] : []
|
|
7634
|
+
]);
|
|
7635
|
+
});
|
|
7475
7636
|
if (!row) throw new MastraError({
|
|
7476
7637
|
id: createStorageErrorId("PG", "UPDATE_EXPERIMENT_RESULT", "NOT_FOUND"),
|
|
7477
7638
|
domain: ErrorDomain.STORAGE,
|
|
@@ -10871,12 +11032,13 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
|
|
|
10871
11032
|
/**
|
|
10872
11033
|
* Reads one page of messages together with the total row count.
|
|
10873
11034
|
*
|
|
10874
|
-
*
|
|
10875
|
-
*
|
|
10876
|
-
*
|
|
10877
|
-
*
|
|
10878
|
-
*
|
|
10879
|
-
*
|
|
11035
|
+
* Every page query carries a skinny scalar `(SELECT COUNT(*) ...)` subquery that
|
|
11036
|
+
* reports the total over the whole WHERE result on the same statement as the page,
|
|
11037
|
+
* so the page costs one database round-trip instead of two. The page and the count
|
|
11038
|
+
* also come from one snapshot, so the count always describes the returned rows. A
|
|
11039
|
+
* separate `COUNT(*)` runs only as a fallback when the page is empty and the caller
|
|
11040
|
+
* asked for a page after the last row, because there is then no row to carry the
|
|
11041
|
+
* count on.
|
|
10880
11042
|
*/
|
|
10881
11043
|
async #fetchMessagePage({ selectStatement, tableName, whereClause, orderByStatement, queryParams, perPageInput, perPage, offset }) {
|
|
10882
11044
|
const limitClause = perPageInput === false ? "" : ` LIMIT $${queryParams.length + 1} OFFSET $${queryParams.length + 2}`;
|
|
@@ -10885,7 +11047,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
|
|
|
10885
11047
|
perPage,
|
|
10886
11048
|
offset
|
|
10887
11049
|
];
|
|
10888
|
-
const rows = await this.#db.readClient.manyOrNone(`${selectStatement}, COUNT(*)
|
|
11050
|
+
const rows = await this.#db.readClient.manyOrNone(`${selectStatement}, (SELECT COUNT(*) FROM ${tableName} ${whereClause}) AS "__total" FROM ${tableName} ${whereClause} ${orderByStatement}${limitClause}`, dataParams) || [];
|
|
10889
11051
|
if (rows.length > 0) return {
|
|
10890
11052
|
total: Number(rows[0].__total),
|
|
10891
11053
|
messages: rows
|
|
@@ -10924,7 +11086,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
|
|
|
10924
11086
|
const metadataFilter = validateStorageMetadataFilter(filter?.metadata);
|
|
10925
11087
|
try {
|
|
10926
11088
|
const { field, direction } = this.parseOrderBy(orderBy, "ASC");
|
|
10927
|
-
const orderByStatement = `ORDER BY
|
|
11089
|
+
const orderByStatement = `ORDER BY "${field}" ${direction}`;
|
|
10928
11090
|
const selectStatement = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId"`;
|
|
10929
11091
|
const tableName = getTableName$3({
|
|
10930
11092
|
indexName: TABLE_MESSAGES,
|
|
@@ -11072,7 +11234,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
|
|
|
11072
11234
|
const metadataFilter = validateStorageMetadataFilter(filter?.metadata);
|
|
11073
11235
|
try {
|
|
11074
11236
|
const { field, direction } = this.parseOrderBy(orderBy, "ASC");
|
|
11075
|
-
const orderByStatement = `ORDER BY
|
|
11237
|
+
const orderByStatement = `ORDER BY "${field}" ${direction}`;
|
|
11076
11238
|
const selectStatement = `SELECT id, content, role, type, "createdAt", "createdAtZ", thread_id AS "threadId", "resourceId"`;
|
|
11077
11239
|
const tableName = getTableName$3({
|
|
11078
11240
|
indexName: TABLE_MESSAGES,
|