@mastra/pg 1.20.1-alpha.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 +9 -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 +4 -4
- package/dist/docs/references/docs-memory-working-memory.md +1 -1
- package/dist/docs/references/{docs-storage-overview.md → docs-storage.md} +1 -1
- package/dist/docs/references/integrations-databases-postgresql.md +1 -0
- package/dist/index.cjs +96 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +96 -2
- 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.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -2152,7 +2152,7 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2152
2152
|
const schema = schemaName || "public";
|
|
2153
2153
|
const [tableRows, columnRows, indexRows] = await Promise.all([
|
|
2154
2154
|
client.manyOrNone(`SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = $1`, [schema]),
|
|
2155
|
-
client.manyOrNone(`SELECT c.relname AS table_name, a.attname AS column_name
|
|
2155
|
+
client.manyOrNone(`SELECT c.relname AS table_name, a.attname AS column_name, format_type(a.atttypid, a.atttypmod) AS data_type
|
|
2156
2156
|
FROM pg_catalog.pg_class c
|
|
2157
2157
|
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
2158
2158
|
JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
|
|
@@ -2167,6 +2167,7 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2167
2167
|
WHERE n.nspname = $1`, [schema])
|
|
2168
2168
|
]);
|
|
2169
2169
|
const columns = /* @__PURE__ */ new Map();
|
|
2170
|
+
const columnTypes = /* @__PURE__ */ new Map();
|
|
2170
2171
|
for (const row of columnRows) {
|
|
2171
2172
|
let set = columns.get(row.table_name);
|
|
2172
2173
|
if (!set) {
|
|
@@ -2174,6 +2175,12 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2174
2175
|
columns.set(row.table_name, set);
|
|
2175
2176
|
}
|
|
2176
2177
|
set.add(row.column_name);
|
|
2178
|
+
let types = columnTypes.get(row.table_name);
|
|
2179
|
+
if (!types) {
|
|
2180
|
+
types = /* @__PURE__ */ new Map();
|
|
2181
|
+
columnTypes.set(row.table_name, types);
|
|
2182
|
+
}
|
|
2183
|
+
types.set(row.column_name, row.data_type);
|
|
2177
2184
|
}
|
|
2178
2185
|
const indexes = /* @__PURE__ */ new Set();
|
|
2179
2186
|
const replicaIdentityIndexes = /* @__PURE__ */ new Set();
|
|
@@ -2187,6 +2194,7 @@ async function loadSchemaSnapshot(client, schemaName) {
|
|
|
2187
2194
|
schemaName: schema,
|
|
2188
2195
|
tables: new Set(tableRows.map((r) => r.tablename)),
|
|
2189
2196
|
columns,
|
|
2197
|
+
columnTypes,
|
|
2190
2198
|
indexes,
|
|
2191
2199
|
replicaIdentityIndexes,
|
|
2192
2200
|
primaryKeyIndexes
|
|
@@ -2440,6 +2448,8 @@ var PgDB = class extends MastraBase {
|
|
|
2440
2448
|
skipDefaultIndexes;
|
|
2441
2449
|
/** Cache of actual table columns: tableName -> Set<columnName> */
|
|
2442
2450
|
tableColumnsCache = /* @__PURE__ */ new Map();
|
|
2451
|
+
/** Cache of column Postgres data types: tableName -> columnName -> data_type */
|
|
2452
|
+
columnTypeCache = /* @__PURE__ */ new Map();
|
|
2443
2453
|
constructor(config) {
|
|
2444
2454
|
super({
|
|
2445
2455
|
component: "STORAGE",
|
|
@@ -2514,7 +2524,9 @@ var PgDB = class extends MastraBase {
|
|
|
2514
2524
|
}
|
|
2515
2525
|
}
|
|
2516
2526
|
this.tableColumnsCache.delete(oldName);
|
|
2527
|
+
this.columnTypeCache.delete(oldName);
|
|
2517
2528
|
this.tableColumnsCache.delete(newName);
|
|
2529
|
+
this.columnTypeCache.delete(newName);
|
|
2518
2530
|
}
|
|
2519
2531
|
/**
|
|
2520
2532
|
* Records an out-of-band `DROP TABLE` in the init snapshot. See
|
|
@@ -2530,8 +2542,10 @@ var PgDB = class extends MastraBase {
|
|
|
2530
2542
|
if (snapshot) {
|
|
2531
2543
|
snapshot.tables.delete(tableName);
|
|
2532
2544
|
snapshot.columns.delete(tableName);
|
|
2545
|
+
snapshot.columnTypes.delete(tableName);
|
|
2533
2546
|
}
|
|
2534
2547
|
this.tableColumnsCache.delete(tableName);
|
|
2548
|
+
this.columnTypeCache.delete(tableName);
|
|
2535
2549
|
}
|
|
2536
2550
|
/**
|
|
2537
2551
|
* Records an out-of-band `ALTER TABLE … ADD COLUMN` in the init snapshot.
|
|
@@ -2541,6 +2555,7 @@ var PgDB = class extends MastraBase {
|
|
|
2541
2555
|
const snapshot = this.schemaSnapshot;
|
|
2542
2556
|
if (snapshot) this.snapshotColumns(snapshot, tableName).add(column);
|
|
2543
2557
|
this.tableColumnsCache.delete(tableName);
|
|
2558
|
+
this.columnTypeCache.delete(tableName);
|
|
2544
2559
|
}
|
|
2545
2560
|
/**
|
|
2546
2561
|
* Gets the set of column names that actually exist in the database table.
|
|
@@ -2583,6 +2598,50 @@ var PgDB = class extends MastraBase {
|
|
|
2583
2598
|
]);
|
|
2584
2599
|
}
|
|
2585
2600
|
/**
|
|
2601
|
+
* Returns the Postgres data type of a column (e.g. `jsonb`, `json`, `text`),
|
|
2602
|
+
* or null when the table or column does not exist.
|
|
2603
|
+
*
|
|
2604
|
+
* Answered from the init snapshot when one is installed, so a warm `init()`
|
|
2605
|
+
* issues no catalog probe. Outside init, results are cached per instance and
|
|
2606
|
+
* the cache is invalidated alongside {@link tableColumnsCache} whenever DDL
|
|
2607
|
+
* changes a table.
|
|
2608
|
+
*/
|
|
2609
|
+
async getColumnType(table, column) {
|
|
2610
|
+
const snapshot = this.schemaSnapshot;
|
|
2611
|
+
if (snapshot) {
|
|
2612
|
+
const types = snapshot.columnTypes.get(table);
|
|
2613
|
+
const known = types?.get(column) ?? types?.get(column.toLowerCase());
|
|
2614
|
+
if (known) return known;
|
|
2615
|
+
if (types) return null;
|
|
2616
|
+
}
|
|
2617
|
+
const cached = this.columnTypeCache.get(table)?.get(column);
|
|
2618
|
+
if (cached !== void 0) return cached;
|
|
2619
|
+
const schema = this.schemaName || "public";
|
|
2620
|
+
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)`, [
|
|
2621
|
+
schema,
|
|
2622
|
+
table,
|
|
2623
|
+
column,
|
|
2624
|
+
column.toLowerCase()
|
|
2625
|
+
]))?.data_type ?? null;
|
|
2626
|
+
if (dataType) {
|
|
2627
|
+
if (snapshot) {
|
|
2628
|
+
let snapshotTypes = snapshot.columnTypes.get(table);
|
|
2629
|
+
if (!snapshotTypes) {
|
|
2630
|
+
snapshotTypes = /* @__PURE__ */ new Map();
|
|
2631
|
+
snapshot.columnTypes.set(table, snapshotTypes);
|
|
2632
|
+
}
|
|
2633
|
+
snapshotTypes.set(column, dataType);
|
|
2634
|
+
}
|
|
2635
|
+
let types = this.columnTypeCache.get(table);
|
|
2636
|
+
if (!types) {
|
|
2637
|
+
types = /* @__PURE__ */ new Map();
|
|
2638
|
+
this.columnTypeCache.set(table, types);
|
|
2639
|
+
}
|
|
2640
|
+
types.set(column, dataType);
|
|
2641
|
+
}
|
|
2642
|
+
return dataType;
|
|
2643
|
+
}
|
|
2644
|
+
/**
|
|
2586
2645
|
* Prepares values for insertion, handling JSONB columns by stringifying them
|
|
2587
2646
|
*/
|
|
2588
2647
|
prepareValuesForInsert(record, tableName) {
|
|
@@ -2781,6 +2840,7 @@ MIGRATION REQUIRED: Duplicate spans detected in ${duplicateInfo.tableName}\n====
|
|
|
2781
2840
|
}, error);
|
|
2782
2841
|
} finally {
|
|
2783
2842
|
this.tableColumnsCache.delete(tableName);
|
|
2843
|
+
this.columnTypeCache.delete(tableName);
|
|
2784
2844
|
}
|
|
2785
2845
|
}
|
|
2786
2846
|
async setupTimestampTriggers(tableName) {
|
|
@@ -3103,6 +3163,7 @@ MIGRATION REQUIRED: Duplicate spans detected in ${duplicateInfo.tableName}\n====
|
|
|
3103
3163
|
}, error);
|
|
3104
3164
|
} finally {
|
|
3105
3165
|
this.tableColumnsCache.delete(tableName);
|
|
3166
|
+
this.columnTypeCache.delete(tableName);
|
|
3106
3167
|
}
|
|
3107
3168
|
}
|
|
3108
3169
|
async load({ tableName, keys }) {
|
|
@@ -3166,6 +3227,7 @@ MIGRATION REQUIRED: Duplicate spans detected in ${duplicateInfo.tableName}\n====
|
|
|
3166
3227
|
}, error);
|
|
3167
3228
|
} finally {
|
|
3168
3229
|
this.tableColumnsCache.delete(tableName);
|
|
3230
|
+
this.columnTypeCache.delete(tableName);
|
|
3169
3231
|
}
|
|
3170
3232
|
}
|
|
3171
3233
|
async createIndex(options) {
|
|
@@ -19298,6 +19360,29 @@ function getTableName({ indexName, schemaName }) {
|
|
|
19298
19360
|
const quotedIndexName = `"${indexName}"`;
|
|
19299
19361
|
return schemaName ? `${schemaName}.${quotedIndexName}` : quotedIndexName;
|
|
19300
19362
|
}
|
|
19363
|
+
/** Base name (before any schema prefix) of the expression index backing the status filter. */
|
|
19364
|
+
const WORKFLOW_SNAPSHOT_STATUS_INDEX = "mastra_workflow_snapshot_name_status_createdat_idx";
|
|
19365
|
+
/**
|
|
19366
|
+
* Schema-prefixed name of the status index, lowercased and truncated the same way Postgres
|
|
19367
|
+
* stores it, so the init snapshot's index set answers "does it exist?" without a probe or a
|
|
19368
|
+
* no-op `CREATE INDEX` (schema-prefixed names routinely exceed the 63-byte limit).
|
|
19369
|
+
*/
|
|
19370
|
+
function workflowSnapshotStatusIndexName(schemaName) {
|
|
19371
|
+
return buildConstraintName({
|
|
19372
|
+
baseName: WORKFLOW_SNAPSHOT_STATUS_INDEX,
|
|
19373
|
+
schemaName: schemaName && schemaName !== "public" ? schemaName : void 0
|
|
19374
|
+
});
|
|
19375
|
+
}
|
|
19376
|
+
/**
|
|
19377
|
+
* Expression index on `(workflow_name, snapshot->>'status', "createdAt" DESC)` so
|
|
19378
|
+
* listWorkflowRuns() status filters can use an index instead of scanning every snapshot.
|
|
19379
|
+
*/
|
|
19380
|
+
function workflowSnapshotStatusIndexSQL(indexName, schemaName) {
|
|
19381
|
+
return `CREATE INDEX IF NOT EXISTS "${indexName}" ON ${getTableName({
|
|
19382
|
+
indexName: TABLE_WORKFLOW_SNAPSHOT,
|
|
19383
|
+
schemaName: getSchemaName(schemaName)
|
|
19384
|
+
})} (workflow_name, (snapshot ->> 'status'), "createdAt" DESC)`;
|
|
19385
|
+
}
|
|
19301
19386
|
/**
|
|
19302
19387
|
* Sanitizes JSON string for PostgreSQL jsonb:
|
|
19303
19388
|
* - Removes problematic Unicode sequences:
|
|
@@ -19380,6 +19465,7 @@ var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
|
|
|
19380
19465
|
includeAllConstraints: true
|
|
19381
19466
|
}));
|
|
19382
19467
|
for (const idx of WorkflowsPG.getDefaultIndexDefs(schemaPrefix)) statements.push(generateIndexSQL(idx, schemaName));
|
|
19468
|
+
statements.push(`${workflowSnapshotStatusIndexSQL(workflowSnapshotStatusIndexName(parsedSchema), schemaName)};`);
|
|
19383
19469
|
return statements;
|
|
19384
19470
|
}
|
|
19385
19471
|
/**
|
|
@@ -19399,6 +19485,13 @@ var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
|
|
|
19399
19485
|
} catch (error) {
|
|
19400
19486
|
this.logger?.warn?.(`Failed to create index ${indexDef.name}:`, error);
|
|
19401
19487
|
}
|
|
19488
|
+
if (await this.#db.getColumnType(TABLE_WORKFLOW_SNAPSHOT, "snapshot") !== "jsonb") return;
|
|
19489
|
+
const indexName = workflowSnapshotStatusIndexName(this.#schema);
|
|
19490
|
+
try {
|
|
19491
|
+
await this.#db.createIndexFromStatement(indexName, workflowSnapshotStatusIndexSQL(indexName, this.#schema));
|
|
19492
|
+
} catch (error) {
|
|
19493
|
+
this.logger?.warn?.(`Failed to create index ${indexName}:`, error);
|
|
19494
|
+
}
|
|
19402
19495
|
}
|
|
19403
19496
|
async init() {
|
|
19404
19497
|
await this.#db.createTable({
|
|
@@ -19688,7 +19781,8 @@ var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
|
|
|
19688
19781
|
paramIndex++;
|
|
19689
19782
|
}
|
|
19690
19783
|
if (status) {
|
|
19691
|
-
|
|
19784
|
+
const statusExpr = await this.#db.getColumnType(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'`;
|
|
19785
|
+
conditions.push(`${statusExpr} = $${paramIndex}`);
|
|
19692
19786
|
values.push(status);
|
|
19693
19787
|
paramIndex++;
|
|
19694
19788
|
}
|