@mastra/pg 1.25.0 → 1.25.1-alpha.0

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
@@ -2460,6 +2460,7 @@ async function loadSchemaSnapshot(client, schemaName) {
2460
2460
  }
2461
2461
  //#endregion
2462
2462
  //#region src/storage/db/index.ts
2463
+ const POSTGRES_MAX_BIND_PARAMETERS$1 = 65535;
2463
2464
  /**
2464
2465
  * Resolves PgDomainConfig to a database client and schema.
2465
2466
  * Handles creating a new pool if config is provided.
@@ -3013,6 +3014,90 @@ var PgDB = class extends MastraBase {
3013
3014
  ON CONFLICT ("traceId", "spanId") DO NOTHING`, values);
3014
3015
  } else await client.none(`INSERT INTO ${fullTableName} (${columnList}) VALUES (${placeholders})`, values);
3015
3016
  }
3017
+ getChunkRowLimit(columnCount) {
3018
+ if (columnCount === 0) return 0;
3019
+ return Math.max(1, Math.floor(POSTGRES_MAX_BIND_PARAMETERS$1 / columnCount));
3020
+ }
3021
+ getSpanConflictIdentifier(record) {
3022
+ const traceId = record.traceId;
3023
+ const spanId = record.spanId;
3024
+ if (traceId === void 0 || spanId === void 0) return;
3025
+ return `${String(traceId)}|${String(spanId)}`;
3026
+ }
3027
+ async normalizeForInsert(tableName, record) {
3028
+ this.addTimestampZColumns(record);
3029
+ const filteredRecord = await this.filterRecordToKnownColumns(tableName, record);
3030
+ return {
3031
+ columns: Object.keys(filteredRecord).map((column) => parseSqlIdentifier(column, "column name")),
3032
+ values: this.prepareValuesForInsert(filteredRecord, tableName),
3033
+ conflictKey: tableName === TABLE_SPANS ? this.getSpanConflictIdentifier(filteredRecord) : void 0
3034
+ };
3035
+ }
3036
+ buildMultiRowInsertStatement({ tableName, columns, rows }) {
3037
+ const fullTableName = getTableName$6({
3038
+ indexName: tableName,
3039
+ schemaName: getSchemaName$6(this.schemaName)
3040
+ });
3041
+ const columnList = columns.map((column) => `"${column}"`).join(", ");
3042
+ const bindParams = [];
3043
+ const values = [];
3044
+ let bindIndex = 1;
3045
+ for (const rowValues of rows) {
3046
+ const placeholders = rowValues.map(() => `$${bindIndex++}`);
3047
+ bindParams.push(`(${placeholders.join(", ")})`);
3048
+ values.push(...rowValues);
3049
+ }
3050
+ let query = `INSERT INTO ${fullTableName} (${columnList}) VALUES ${bindParams.join(", ")}`;
3051
+ if (tableName === TABLE_SPANS) {
3052
+ const updateColumns = columns.filter((column) => column !== "traceId" && column !== "spanId");
3053
+ if (updateColumns.length > 0) {
3054
+ const updateClause = updateColumns.map((column) => `"${column}" = EXCLUDED."${column}"`).join(", ");
3055
+ query += ` ON CONFLICT ("traceId", "spanId") DO UPDATE SET ${updateClause}`;
3056
+ } else query += ` ON CONFLICT ("traceId", "spanId") DO NOTHING`;
3057
+ }
3058
+ return {
3059
+ query,
3060
+ values
3061
+ };
3062
+ }
3063
+ async executeBatchInsert(client, { tableName, records }) {
3064
+ const preparedRecords = [];
3065
+ for (const record of records) preparedRecords.push(await this.normalizeForInsert(tableName, record));
3066
+ let pendingColumns;
3067
+ let pendingConflictKeys = /* @__PURE__ */ new Set();
3068
+ let pendingRows = [];
3069
+ let pendingLimit = 0;
3070
+ const flush = async () => {
3071
+ if (!pendingColumns || pendingRows.length === 0) return;
3072
+ const statement = this.buildMultiRowInsertStatement({
3073
+ tableName,
3074
+ columns: pendingColumns,
3075
+ rows: pendingRows
3076
+ });
3077
+ await client.none(statement.query, statement.values);
3078
+ pendingColumns = void 0;
3079
+ pendingRows = [];
3080
+ pendingConflictKeys = /* @__PURE__ */ new Set();
3081
+ pendingLimit = 0;
3082
+ };
3083
+ for (const { columns, values, conflictKey } of preparedRecords) {
3084
+ if (columns.length === 0) continue;
3085
+ const columnsSignature = columns.join("\0");
3086
+ const currentPendingColumns = pendingColumns;
3087
+ const isSpans = tableName === TABLE_SPANS;
3088
+ const conflictDuplicate = isSpans && conflictKey !== void 0 && pendingConflictKeys.has(conflictKey);
3089
+ const exceedsLimit = pendingRows.length >= pendingLimit;
3090
+ if (currentPendingColumns === void 0 || columnsSignature !== currentPendingColumns.join("\0") || conflictDuplicate || exceedsLimit) {
3091
+ await flush();
3092
+ pendingColumns = columns;
3093
+ pendingLimit = this.getChunkRowLimit(columns.length);
3094
+ pendingRows = [values];
3095
+ pendingConflictKeys = /* @__PURE__ */ new Set();
3096
+ } else pendingRows.push(values);
3097
+ if (isSpans && conflictKey !== void 0) pendingConflictKeys.add(conflictKey);
3098
+ }
3099
+ await flush();
3100
+ }
3016
3101
  async insert({ tableName, record }) {
3017
3102
  try {
3018
3103
  await this.executeInsert(this.client, {
@@ -3461,9 +3546,9 @@ MIGRATION REQUIRED: Duplicate spans detected in ${duplicateInfo.tableName}\n====
3461
3546
  async batchInsert({ tableName, records }) {
3462
3547
  try {
3463
3548
  await this.client.tx(async (tx) => {
3464
- for (const record of records) await this.executeInsert(tx, {
3549
+ await this.executeBatchInsert(tx, {
3465
3550
  tableName,
3466
- record
3551
+ records
3467
3552
  });
3468
3553
  });
3469
3554
  } catch (error) {
@@ -23406,7 +23491,12 @@ var PgFactoryStorageOps = class {
23406
23491
  const assignments = columns.map((column, i) => `"${column}" = $${i + 1}`).join(", ");
23407
23492
  const filter = this.#buildWhere(schema, where, columns.length + 1);
23408
23493
  const args = [...columns.map((column) => this.#serialize(this.#column(schema, column), set[column])), ...filter.args];
23409
- return (await queryable.query(`UPDATE "${schema.name}" SET ${assignments} WHERE ${filter.sql}`, args)).rowCount ?? 0;
23494
+ try {
23495
+ return (await queryable.query(`UPDATE "${schema.name}" SET ${assignments} WHERE ${filter.sql}`, args)).rowCount ?? 0;
23496
+ } catch (error) {
23497
+ if (isUniqueViolation(error)) throw new UniqueViolationError(collection, { cause: error });
23498
+ throw error;
23499
+ }
23410
23500
  }
23411
23501
  async deleteMany(collection, where) {
23412
23502
  const schema = this.#schema(collection);