@mastra/pg 1.20.0 → 1.20.1-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.
- package/CHANGELOG.md +18 -0
- package/dist/docs/SKILL.md +2 -2
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-deployment-workers.md +253 -7
- package/dist/docs/references/docs-memory-semantic-recall.md +1 -1
- package/dist/docs/references/docs-memory-working-memory.md +3 -3
- package/dist/docs/references/{docs-storage-overview.md → docs-storage.md} +8 -7
- package/dist/docs/references/integrations-databases-postgresql.md +11 -9
- package/dist/docs/references/reference-rag-chunking-and-embedding.md +1 -1
- package/dist/docs/references/reference-rag-metadata-filters.md +1 -1
- package/dist/docs/references/reference-storage-retention.md +1 -1
- package/dist/docs/references/reference-tools-vector-query-tool.md +1 -1
- package/dist/docs/references/reference-vectors-pg.md +1 -1
- package/dist/index.cjs +113 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +113 -5
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +12 -0
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/db/schema-snapshot.d.ts +2 -0
- package/dist/storage/db/schema-snapshot.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +1 -2
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -2176,7 +2176,7 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2176
2176
|
const schema = schemaName || "public";
|
|
2177
2177
|
const [tableRows, columnRows, indexRows] = await Promise.all([
|
|
2178
2178
|
client.manyOrNone(`SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = $1`, [schema]),
|
|
2179
|
-
client.manyOrNone(`SELECT c.relname AS table_name, a.attname AS column_name
|
|
2179
|
+
client.manyOrNone(`SELECT c.relname AS table_name, a.attname AS column_name, format_type(a.atttypid, a.atttypmod) AS data_type
|
|
2180
2180
|
FROM pg_catalog.pg_class c
|
|
2181
2181
|
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
2182
2182
|
JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
|
|
@@ -2191,6 +2191,7 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2191
2191
|
WHERE n.nspname = $1`, [schema])
|
|
2192
2192
|
]);
|
|
2193
2193
|
const columns = /* @__PURE__ */ new Map();
|
|
2194
|
+
const columnTypes = /* @__PURE__ */ new Map();
|
|
2194
2195
|
for (const row of columnRows) {
|
|
2195
2196
|
let set = columns.get(row.table_name);
|
|
2196
2197
|
if (!set) {
|
|
@@ -2198,6 +2199,12 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2198
2199
|
columns.set(row.table_name, set);
|
|
2199
2200
|
}
|
|
2200
2201
|
set.add(row.column_name);
|
|
2202
|
+
let types = columnTypes.get(row.table_name);
|
|
2203
|
+
if (!types) {
|
|
2204
|
+
types = /* @__PURE__ */ new Map();
|
|
2205
|
+
columnTypes.set(row.table_name, types);
|
|
2206
|
+
}
|
|
2207
|
+
types.set(row.column_name, row.data_type);
|
|
2201
2208
|
}
|
|
2202
2209
|
const indexes = /* @__PURE__ */ new Set();
|
|
2203
2210
|
const replicaIdentityIndexes = /* @__PURE__ */ new Set();
|
|
@@ -2211,6 +2218,7 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2211
2218
|
schemaName: schema,
|
|
2212
2219
|
tables: new Set(tableRows.map((r) => r.tablename)),
|
|
2213
2220
|
columns,
|
|
2221
|
+
columnTypes,
|
|
2214
2222
|
indexes,
|
|
2215
2223
|
replicaIdentityIndexes,
|
|
2216
2224
|
primaryKeyIndexes
|
|
@@ -2464,6 +2472,8 @@ var PgDB = class extends _mastra_core_base.MastraBase {
|
|
|
2464
2472
|
skipDefaultIndexes;
|
|
2465
2473
|
/** Cache of actual table columns: tableName -> Set<columnName> */
|
|
2466
2474
|
tableColumnsCache = /* @__PURE__ */ new Map();
|
|
2475
|
+
/** Cache of column Postgres data types: tableName -> columnName -> data_type */
|
|
2476
|
+
columnTypeCache = /* @__PURE__ */ new Map();
|
|
2467
2477
|
constructor(config) {
|
|
2468
2478
|
super({
|
|
2469
2479
|
component: "STORAGE",
|
|
@@ -2538,7 +2548,9 @@ var PgDB = class extends _mastra_core_base.MastraBase {
|
|
|
2538
2548
|
}
|
|
2539
2549
|
}
|
|
2540
2550
|
this.tableColumnsCache.delete(oldName);
|
|
2551
|
+
this.columnTypeCache.delete(oldName);
|
|
2541
2552
|
this.tableColumnsCache.delete(newName);
|
|
2553
|
+
this.columnTypeCache.delete(newName);
|
|
2542
2554
|
}
|
|
2543
2555
|
/**
|
|
2544
2556
|
* Records an out-of-band `DROP TABLE` in the init snapshot. See
|
|
@@ -2554,8 +2566,10 @@ var PgDB = class extends _mastra_core_base.MastraBase {
|
|
|
2554
2566
|
if (snapshot) {
|
|
2555
2567
|
snapshot.tables.delete(tableName);
|
|
2556
2568
|
snapshot.columns.delete(tableName);
|
|
2569
|
+
snapshot.columnTypes.delete(tableName);
|
|
2557
2570
|
}
|
|
2558
2571
|
this.tableColumnsCache.delete(tableName);
|
|
2572
|
+
this.columnTypeCache.delete(tableName);
|
|
2559
2573
|
}
|
|
2560
2574
|
/**
|
|
2561
2575
|
* Records an out-of-band `ALTER TABLE … ADD COLUMN` in the init snapshot.
|
|
@@ -2565,6 +2579,7 @@ var PgDB = class extends _mastra_core_base.MastraBase {
|
|
|
2565
2579
|
const snapshot = this.schemaSnapshot;
|
|
2566
2580
|
if (snapshot) this.snapshotColumns(snapshot, tableName).add(column);
|
|
2567
2581
|
this.tableColumnsCache.delete(tableName);
|
|
2582
|
+
this.columnTypeCache.delete(tableName);
|
|
2568
2583
|
}
|
|
2569
2584
|
/**
|
|
2570
2585
|
* Gets the set of column names that actually exist in the database table.
|
|
@@ -2607,6 +2622,50 @@ var PgDB = class extends _mastra_core_base.MastraBase {
|
|
|
2607
2622
|
]);
|
|
2608
2623
|
}
|
|
2609
2624
|
/**
|
|
2625
|
+
* Returns the Postgres data type of a column (e.g. `jsonb`, `json`, `text`),
|
|
2626
|
+
* or null when the table or column does not exist.
|
|
2627
|
+
*
|
|
2628
|
+
* Answered from the init snapshot when one is installed, so a warm `init()`
|
|
2629
|
+
* issues no catalog probe. Outside init, results are cached per instance and
|
|
2630
|
+
* the cache is invalidated alongside {@link tableColumnsCache} whenever DDL
|
|
2631
|
+
* changes a table.
|
|
2632
|
+
*/
|
|
2633
|
+
async getColumnType(table, column) {
|
|
2634
|
+
const snapshot = this.schemaSnapshot;
|
|
2635
|
+
if (snapshot) {
|
|
2636
|
+
const types = snapshot.columnTypes.get(table);
|
|
2637
|
+
const known = types?.get(column) ?? types?.get(column.toLowerCase());
|
|
2638
|
+
if (known) return known;
|
|
2639
|
+
if (types) return null;
|
|
2640
|
+
}
|
|
2641
|
+
const cached = this.columnTypeCache.get(table)?.get(column);
|
|
2642
|
+
if (cached !== void 0) return cached;
|
|
2643
|
+
const schema = this.schemaName || "public";
|
|
2644
|
+
const dataType = (await this.client.oneOrNone(`SELECT data_type FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND (column_name = $3 OR column_name = $4)`, [
|
|
2645
|
+
schema,
|
|
2646
|
+
table,
|
|
2647
|
+
column,
|
|
2648
|
+
column.toLowerCase()
|
|
2649
|
+
]))?.data_type ?? null;
|
|
2650
|
+
if (dataType) {
|
|
2651
|
+
if (snapshot) {
|
|
2652
|
+
let snapshotTypes = snapshot.columnTypes.get(table);
|
|
2653
|
+
if (!snapshotTypes) {
|
|
2654
|
+
snapshotTypes = /* @__PURE__ */ new Map();
|
|
2655
|
+
snapshot.columnTypes.set(table, snapshotTypes);
|
|
2656
|
+
}
|
|
2657
|
+
snapshotTypes.set(column, dataType);
|
|
2658
|
+
}
|
|
2659
|
+
let types = this.columnTypeCache.get(table);
|
|
2660
|
+
if (!types) {
|
|
2661
|
+
types = /* @__PURE__ */ new Map();
|
|
2662
|
+
this.columnTypeCache.set(table, types);
|
|
2663
|
+
}
|
|
2664
|
+
types.set(column, dataType);
|
|
2665
|
+
}
|
|
2666
|
+
return dataType;
|
|
2667
|
+
}
|
|
2668
|
+
/**
|
|
2610
2669
|
* Prepares values for insertion, handling JSONB columns by stringifying them
|
|
2611
2670
|
*/
|
|
2612
2671
|
prepareValuesForInsert(record, tableName) {
|
|
@@ -2805,6 +2864,7 @@ MIGRATION REQUIRED: Duplicate spans detected in ${duplicateInfo.tableName}\n====
|
|
|
2805
2864
|
}, error);
|
|
2806
2865
|
} finally {
|
|
2807
2866
|
this.tableColumnsCache.delete(tableName);
|
|
2867
|
+
this.columnTypeCache.delete(tableName);
|
|
2808
2868
|
}
|
|
2809
2869
|
}
|
|
2810
2870
|
async setupTimestampTriggers(tableName) {
|
|
@@ -3127,6 +3187,7 @@ MIGRATION REQUIRED: Duplicate spans detected in ${duplicateInfo.tableName}\n====
|
|
|
3127
3187
|
}, error);
|
|
3128
3188
|
} finally {
|
|
3129
3189
|
this.tableColumnsCache.delete(tableName);
|
|
3190
|
+
this.columnTypeCache.delete(tableName);
|
|
3130
3191
|
}
|
|
3131
3192
|
}
|
|
3132
3193
|
async load({ tableName, keys }) {
|
|
@@ -3190,6 +3251,7 @@ MIGRATION REQUIRED: Duplicate spans detected in ${duplicateInfo.tableName}\n====
|
|
|
3190
3251
|
}, error);
|
|
3191
3252
|
} finally {
|
|
3192
3253
|
this.tableColumnsCache.delete(tableName);
|
|
3254
|
+
this.columnTypeCache.delete(tableName);
|
|
3193
3255
|
}
|
|
3194
3256
|
}
|
|
3195
3257
|
async createIndex(options) {
|
|
@@ -19322,6 +19384,29 @@ function getTableName({ indexName, schemaName }) {
|
|
|
19322
19384
|
const quotedIndexName = `"${indexName}"`;
|
|
19323
19385
|
return schemaName ? `${schemaName}.${quotedIndexName}` : quotedIndexName;
|
|
19324
19386
|
}
|
|
19387
|
+
/** Base name (before any schema prefix) of the expression index backing the status filter. */
|
|
19388
|
+
const WORKFLOW_SNAPSHOT_STATUS_INDEX = "mastra_workflow_snapshot_name_status_createdat_idx";
|
|
19389
|
+
/**
|
|
19390
|
+
* Schema-prefixed name of the status index, lowercased and truncated the same way Postgres
|
|
19391
|
+
* stores it, so the init snapshot's index set answers "does it exist?" without a probe or a
|
|
19392
|
+
* no-op `CREATE INDEX` (schema-prefixed names routinely exceed the 63-byte limit).
|
|
19393
|
+
*/
|
|
19394
|
+
function workflowSnapshotStatusIndexName(schemaName) {
|
|
19395
|
+
return buildConstraintName({
|
|
19396
|
+
baseName: WORKFLOW_SNAPSHOT_STATUS_INDEX,
|
|
19397
|
+
schemaName: schemaName && schemaName !== "public" ? schemaName : void 0
|
|
19398
|
+
});
|
|
19399
|
+
}
|
|
19400
|
+
/**
|
|
19401
|
+
* Expression index on `(workflow_name, snapshot->>'status', "createdAt" DESC)` so
|
|
19402
|
+
* listWorkflowRuns() status filters can use an index instead of scanning every snapshot.
|
|
19403
|
+
*/
|
|
19404
|
+
function workflowSnapshotStatusIndexSQL(indexName, schemaName) {
|
|
19405
|
+
return `CREATE INDEX IF NOT EXISTS "${indexName}" ON ${getTableName({
|
|
19406
|
+
indexName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
19407
|
+
schemaName: getSchemaName(schemaName)
|
|
19408
|
+
})} (workflow_name, (snapshot ->> 'status'), "createdAt" DESC)`;
|
|
19409
|
+
}
|
|
19325
19410
|
/**
|
|
19326
19411
|
* Sanitizes JSON string for PostgreSQL jsonb:
|
|
19327
19412
|
* - Removes problematic Unicode sequences:
|
|
@@ -19382,33 +19467,55 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
19382
19467
|
updatedAt: new Date(row.updatedAtZ || row.updatedAt)
|
|
19383
19468
|
};
|
|
19384
19469
|
}
|
|
19470
|
+
static getDefaultIndexDefs(schemaPrefix) {
|
|
19471
|
+
return [{
|
|
19472
|
+
name: `${schemaPrefix}mastra_workflow_snapshot_name_createdat_idx`,
|
|
19473
|
+
table: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
19474
|
+
columns: ["workflow_name", "createdAt DESC"]
|
|
19475
|
+
}];
|
|
19476
|
+
}
|
|
19385
19477
|
/**
|
|
19386
19478
|
* Returns all DDL statements for this domain: table with unique constraint.
|
|
19387
19479
|
* Used by exportSchemas to produce a complete, reproducible schema export.
|
|
19388
19480
|
*/
|
|
19389
19481
|
static getExportDDL(schemaName) {
|
|
19390
19482
|
const statements = [];
|
|
19483
|
+
const parsedSchema = schemaName ? (0, _mastra_core_utils.parseSqlIdentifier)(schemaName, "schema name") : "";
|
|
19484
|
+
const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
|
|
19391
19485
|
statements.push(generateTableSQL({
|
|
19392
19486
|
tableName: _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
19393
19487
|
schema: _mastra_core_storage.TABLE_SCHEMAS[_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT],
|
|
19394
19488
|
schemaName,
|
|
19395
19489
|
includeAllConstraints: true
|
|
19396
19490
|
}));
|
|
19491
|
+
for (const idx of WorkflowsPG.getDefaultIndexDefs(schemaPrefix)) statements.push(generateIndexSQL(idx, schemaName));
|
|
19492
|
+
statements.push(`${workflowSnapshotStatusIndexSQL(workflowSnapshotStatusIndexName(parsedSchema), schemaName)};`);
|
|
19397
19493
|
return statements;
|
|
19398
19494
|
}
|
|
19399
19495
|
/**
|
|
19400
19496
|
* Returns default index definitions for the workflows domain tables.
|
|
19401
|
-
* Currently no default indexes are defined for workflows.
|
|
19402
19497
|
*/
|
|
19403
19498
|
getDefaultIndexDefinitions() {
|
|
19404
|
-
|
|
19499
|
+
const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
|
|
19500
|
+
return WorkflowsPG.getDefaultIndexDefs(schemaPrefix);
|
|
19405
19501
|
}
|
|
19406
19502
|
/**
|
|
19407
19503
|
* Creates default indexes for optimal query performance.
|
|
19408
|
-
* Currently no default indexes are defined for workflows.
|
|
19409
19504
|
*/
|
|
19410
19505
|
async createDefaultIndexes() {
|
|
19411
19506
|
if (this.#skipDefaultIndexes) return;
|
|
19507
|
+
for (const indexDef of this.getDefaultIndexDefinitions()) try {
|
|
19508
|
+
await this.#db.createIndex(indexDef);
|
|
19509
|
+
} catch (error) {
|
|
19510
|
+
this.logger?.warn?.(`Failed to create index ${indexDef.name}:`, error);
|
|
19511
|
+
}
|
|
19512
|
+
if (await this.#db.getColumnType(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT, "snapshot") !== "jsonb") return;
|
|
19513
|
+
const indexName = workflowSnapshotStatusIndexName(this.#schema);
|
|
19514
|
+
try {
|
|
19515
|
+
await this.#db.createIndexFromStatement(indexName, workflowSnapshotStatusIndexSQL(indexName, this.#schema));
|
|
19516
|
+
} catch (error) {
|
|
19517
|
+
this.logger?.warn?.(`Failed to create index ${indexName}:`, error);
|
|
19518
|
+
}
|
|
19412
19519
|
}
|
|
19413
19520
|
async init() {
|
|
19414
19521
|
await this.#db.createTable({
|
|
@@ -19698,7 +19805,8 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
19698
19805
|
paramIndex++;
|
|
19699
19806
|
}
|
|
19700
19807
|
if (status) {
|
|
19701
|
-
|
|
19808
|
+
const statusExpr = await this.#db.getColumnType(_mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT, "snapshot") === "jsonb" ? `snapshot ->> 'status'` : `regexp_replace(snapshot::text, '\\\\u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})', '', 'g')::jsonb ->> 'status'`;
|
|
19809
|
+
conditions.push(`${statusExpr} = $${paramIndex}`);
|
|
19702
19810
|
values.push(status);
|
|
19703
19811
|
paramIndex++;
|
|
19704
19812
|
}
|