@mastra/pg 0.3.4 → 0.4.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.
package/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var utils = require('@mastra/core/utils');
3
4
  var vector = require('@mastra/core/vector');
4
5
  var asyncMutex = require('async-mutex');
5
6
  var pg = require('pg');
@@ -81,22 +82,26 @@ var PGFilterTranslator = class extends filter.BaseFilterTranslator {
81
82
  return { $regex: flags ? `(?${flags})${pattern}` : pattern };
82
83
  }
83
84
  };
84
-
85
- // src/vector/sql-builder.ts
86
85
  var createBasicOperator = (symbol) => {
87
- return (key, paramIndex) => ({
88
- sql: `CASE
89
- WHEN $${paramIndex}::text IS NULL THEN metadata#>>'{${handleKey(key)}}' IS ${symbol === "=" ? "" : "NOT"} NULL
90
- ELSE metadata#>>'{${handleKey(key)}}' ${symbol} $${paramIndex}::text
91
- END`,
92
- needsValue: true
93
- });
86
+ return (key, paramIndex) => {
87
+ const jsonPathKey = parseJsonPathKey(key);
88
+ return {
89
+ sql: `CASE
90
+ WHEN $${paramIndex}::text IS NULL THEN metadata#>>'{${jsonPathKey}}' IS ${symbol === "=" ? "" : "NOT"} NULL
91
+ ELSE metadata#>>'{${jsonPathKey}}' ${symbol} $${paramIndex}::text
92
+ END`,
93
+ needsValue: true
94
+ };
95
+ };
94
96
  };
95
97
  var createNumericOperator = (symbol) => {
96
- return (key, paramIndex) => ({
97
- sql: `(metadata#>>'{${handleKey(key)}}')::numeric ${symbol} $${paramIndex}`,
98
- needsValue: true
99
- });
98
+ return (key, paramIndex) => {
99
+ const jsonPathKey = parseJsonPathKey(key);
100
+ return {
101
+ sql: `(metadata#>>'{${jsonPathKey}}')::numeric ${symbol} $${paramIndex}`,
102
+ needsValue: true
103
+ };
104
+ };
100
105
  };
101
106
  function buildElemMatchConditions(value, paramIndex) {
102
107
  if (typeof value !== "object" || Array.isArray(value)) {
@@ -147,46 +152,56 @@ var FILTER_OPERATORS = {
147
152
  $lt: createNumericOperator("<"),
148
153
  $lte: createNumericOperator("<="),
149
154
  // Array Operators
150
- $in: (key, paramIndex) => ({
151
- sql: `(
152
- CASE
153
- WHEN jsonb_typeof(metadata->'${handleKey(key)}') = 'array' THEN
154
- EXISTS (
155
- SELECT 1 FROM jsonb_array_elements_text(metadata->'${handleKey(key)}') as elem
156
- WHERE elem = ANY($${paramIndex}::text[])
157
- )
158
- ELSE metadata#>>'{${handleKey(key)}}' = ANY($${paramIndex}::text[])
159
- END
160
- )`,
161
- needsValue: true
162
- }),
163
- $nin: (key, paramIndex) => ({
164
- sql: `(
165
- CASE
166
- WHEN jsonb_typeof(metadata->'${handleKey(key)}') = 'array' THEN
167
- NOT EXISTS (
168
- SELECT 1 FROM jsonb_array_elements_text(metadata->'${handleKey(key)}') as elem
169
- WHERE elem = ANY($${paramIndex}::text[])
170
- )
171
- ELSE metadata#>>'{${handleKey(key)}}' != ALL($${paramIndex}::text[])
172
- END
173
- )`,
174
- needsValue: true
175
- }),
176
- $all: (key, paramIndex) => ({
177
- sql: `CASE WHEN array_length($${paramIndex}::text[], 1) IS NULL THEN false
178
- ELSE (metadata#>'{${handleKey(key)}}')::jsonb ?& $${paramIndex}::text[] END`,
179
- needsValue: true
180
- }),
155
+ $in: (key, paramIndex) => {
156
+ const jsonPathKey = parseJsonPathKey(key);
157
+ return {
158
+ sql: `(
159
+ CASE
160
+ WHEN jsonb_typeof(metadata->'${jsonPathKey}') = 'array' THEN
161
+ EXISTS (
162
+ SELECT 1 FROM jsonb_array_elements_text(metadata->'${jsonPathKey}') as elem
163
+ WHERE elem = ANY($${paramIndex}::text[])
164
+ )
165
+ ELSE metadata#>>'{${jsonPathKey}}' = ANY($${paramIndex}::text[])
166
+ END
167
+ )`,
168
+ needsValue: true
169
+ };
170
+ },
171
+ $nin: (key, paramIndex) => {
172
+ const jsonPathKey = parseJsonPathKey(key);
173
+ return {
174
+ sql: `(
175
+ CASE
176
+ WHEN jsonb_typeof(metadata->'${jsonPathKey}') = 'array' THEN
177
+ NOT EXISTS (
178
+ SELECT 1 FROM jsonb_array_elements_text(metadata->'${jsonPathKey}') as elem
179
+ WHERE elem = ANY($${paramIndex}::text[])
180
+ )
181
+ ELSE metadata#>>'{${jsonPathKey}}' != ALL($${paramIndex}::text[])
182
+ END
183
+ )`,
184
+ needsValue: true
185
+ };
186
+ },
187
+ $all: (key, paramIndex) => {
188
+ const jsonPathKey = parseJsonPathKey(key);
189
+ return {
190
+ sql: `CASE WHEN array_length($${paramIndex}::text[], 1) IS NULL THEN false
191
+ ELSE (metadata#>'{${jsonPathKey}}')::jsonb ?& $${paramIndex}::text[] END`,
192
+ needsValue: true
193
+ };
194
+ },
181
195
  $elemMatch: (key, paramIndex, value) => {
182
196
  const { sql, values } = buildElemMatchConditions(value, paramIndex);
197
+ const jsonPathKey = parseJsonPathKey(key);
183
198
  return {
184
199
  sql: `(
185
200
  CASE
186
- WHEN jsonb_typeof(metadata->'${handleKey(key)}') = 'array' THEN
201
+ WHEN jsonb_typeof(metadata->'${jsonPathKey}') = 'array' THEN
187
202
  EXISTS (
188
203
  SELECT 1
189
- FROM jsonb_array_elements(metadata->'${handleKey(key)}') as elem
204
+ FROM jsonb_array_elements(metadata->'${jsonPathKey}') as elem
190
205
  WHERE ${sql}
191
206
  )
192
207
  ELSE FALSE
@@ -197,33 +212,40 @@ var FILTER_OPERATORS = {
197
212
  };
198
213
  },
199
214
  // Element Operators
200
- $exists: (key) => ({
201
- sql: `metadata ? '${key}'`,
202
- needsValue: false
203
- }),
215
+ $exists: (key) => {
216
+ const jsonPathKey = parseJsonPathKey(key);
217
+ return {
218
+ sql: `metadata ? '${jsonPathKey}'`,
219
+ needsValue: false
220
+ };
221
+ },
204
222
  // Logical Operators
205
223
  $and: (key) => ({ sql: `(${key})`, needsValue: false }),
206
224
  $or: (key) => ({ sql: `(${key})`, needsValue: false }),
207
225
  $not: (key) => ({ sql: `NOT (${key})`, needsValue: false }),
208
226
  $nor: (key) => ({ sql: `NOT (${key})`, needsValue: false }),
209
227
  // Regex Operators
210
- $regex: (key, paramIndex) => ({
211
- sql: `metadata#>>'{${handleKey(key)}}' ~ $${paramIndex}`,
212
- needsValue: true
213
- }),
228
+ $regex: (key, paramIndex) => {
229
+ const jsonPathKey = parseJsonPathKey(key);
230
+ return {
231
+ sql: `metadata#>>'{${jsonPathKey}}' ~ $${paramIndex}`,
232
+ needsValue: true
233
+ };
234
+ },
214
235
  $contains: (key, paramIndex, value) => {
236
+ const jsonPathKey = parseJsonPathKey(key);
215
237
  let sql;
216
238
  if (Array.isArray(value)) {
217
- sql = `(metadata->'${handleKey(key)}') ?& $${paramIndex}`;
239
+ sql = `(metadata->'${jsonPathKey}') ?& $${paramIndex}`;
218
240
  } else if (typeof value === "string") {
219
- sql = `metadata->>'${handleKey(key)}' ILIKE '%' || $${paramIndex} || '%'`;
241
+ sql = `metadata->>'${jsonPathKey}' ILIKE '%' || $${paramIndex} || '%' ESCAPE '\\'`;
220
242
  } else {
221
- sql = `metadata->>'${handleKey(key)}' = $${paramIndex}`;
243
+ sql = `metadata->>'${jsonPathKey}' = $${paramIndex}`;
222
244
  }
223
245
  return {
224
246
  sql,
225
247
  needsValue: true,
226
- transformValue: () => Array.isArray(value) ? value.map(String) : value
248
+ transformValue: () => Array.isArray(value) ? value.map(String) : typeof value === "string" ? escapeLikePattern(value) : value
227
249
  };
228
250
  },
229
251
  /**
@@ -238,29 +260,36 @@ var FILTER_OPERATORS = {
238
260
  // return JSON.stringify(parts.reduceRight((value, key) => ({ [key]: value }), value));
239
261
  // },
240
262
  // }),
241
- $size: (key, paramIndex) => ({
242
- sql: `(
263
+ $size: (key, paramIndex) => {
264
+ const jsonPathKey = parseJsonPathKey(key);
265
+ return {
266
+ sql: `(
243
267
  CASE
244
- WHEN jsonb_typeof(metadata#>'{${handleKey(key)}}') = 'array' THEN
245
- jsonb_array_length(metadata#>'{${handleKey(key)}}') = $${paramIndex}
268
+ WHEN jsonb_typeof(metadata#>'{${jsonPathKey}}') = 'array' THEN
269
+ jsonb_array_length(metadata#>'{${jsonPathKey}}') = $${paramIndex}
246
270
  ELSE FALSE
247
271
  END
248
272
  )`,
249
- needsValue: true
250
- })
273
+ needsValue: true
274
+ };
275
+ }
251
276
  };
252
- var handleKey = (key) => {
253
- return key.replace(/\./g, ",");
277
+ var parseJsonPathKey = (key) => {
278
+ const parsedKey = key !== "" ? utils.parseFieldKey(key) : "";
279
+ return parsedKey.replace(/\./g, ",");
254
280
  };
255
- function buildFilterQuery(filter, minScore) {
256
- const values = [minScore];
281
+ function escapeLikePattern(str) {
282
+ return str.replace(/([%_\\])/g, "\\$1");
283
+ }
284
+ function buildFilterQuery(filter, minScore, topK) {
285
+ const values = [minScore, topK];
257
286
  function buildCondition(key, value, parentPath) {
258
287
  if (["$and", "$or", "$not", "$nor"].includes(key)) {
259
288
  return handleLogicalOperator(key, value);
260
289
  }
261
290
  if (!value || typeof value !== "object") {
262
291
  values.push(value);
263
- return `metadata#>>'{${handleKey(key)}}' = $${values.length}`;
292
+ return `metadata#>>'{${parseJsonPathKey(key)}}' = $${values.length}`;
264
293
  }
265
294
  const [[operator, operatorValue] = []] = Object.entries(value);
266
295
  if (operator === "$not") {
@@ -270,7 +299,7 @@ function buildFilterQuery(filter, minScore) {
270
299
  throw new Error(`Invalid operator in $not condition: ${nestedOp}`);
271
300
  }
272
301
  const operatorFn2 = FILTER_OPERATORS[nestedOp];
273
- const operatorResult2 = operatorFn2(key, values.length + 1);
302
+ const operatorResult2 = operatorFn2(key, values.length + 1, nestedValue);
274
303
  if (operatorResult2.needsValue) {
275
304
  values.push(nestedValue);
276
305
  }
@@ -341,27 +370,11 @@ var PgVector = class extends vector.MastraVector {
341
370
  installVectorExtensionPromise = null;
342
371
  vectorExtensionInstalled = void 0;
343
372
  schemaSetupComplete = void 0;
344
- constructor(config) {
345
- let connectionString;
346
- let pgPoolOptions;
347
- let schemaName;
348
- if (typeof config === "string") {
349
- console.warn(
350
- `DEPRECATION WARNING: Passing connectionString as a string to PgVector constructor is deprecated.
351
-
352
- Please use an object parameter instead:
353
- new PgVector({ connectionString })
354
-
355
- The string signature will be removed on May 20th, 2025.`
356
- );
357
- connectionString = config;
358
- schemaName = void 0;
359
- pgPoolOptions = void 0;
360
- } else {
361
- connectionString = config.connectionString;
362
- schemaName = config.schemaName;
363
- pgPoolOptions = config.pgPoolOptions;
364
- }
373
+ constructor({
374
+ connectionString,
375
+ schemaName,
376
+ pgPoolOptions
377
+ }) {
365
378
  if (!connectionString || connectionString.trim() === "") {
366
379
  throw new Error(
367
380
  "PgVector: connectionString must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults."
@@ -389,7 +402,7 @@ var PgVector = class extends vector.MastraVector {
389
402
  void (async () => {
390
403
  const existingIndexes = await this.listIndexes();
391
404
  void existingIndexes.map(async (indexName) => {
392
- const info = await this.getIndexInfo(indexName);
405
+ const info = await this.getIndexInfo({ indexName });
393
406
  const key = await this.getIndexCacheKey({
394
407
  indexName,
395
408
  metric: info.metric,
@@ -405,31 +418,42 @@ var PgVector = class extends vector.MastraVector {
405
418
  return this.mutexesByName.get(indexName);
406
419
  }
407
420
  getTableName(indexName) {
408
- return this.schema ? `${this.schema}.${indexName}` : indexName;
421
+ const parsedIndexName = utils.parseSqlIdentifier(indexName, "index name");
422
+ const parsedSchemaName = this.schema ? utils.parseSqlIdentifier(this.schema, "schema name") : void 0;
423
+ return parsedSchemaName ? `${parsedSchemaName}.${parsedIndexName}` : parsedIndexName;
409
424
  }
410
425
  transformFilter(filter) {
411
426
  const translator = new PGFilterTranslator();
412
427
  return translator.translate(filter);
413
428
  }
414
- async getIndexInfo(indexName) {
429
+ async getIndexInfo({ indexName }) {
415
430
  if (!this.describeIndexCache.has(indexName)) {
416
- this.describeIndexCache.set(indexName, await this.describeIndex(indexName));
431
+ this.describeIndexCache.set(indexName, await this.describeIndex({ indexName }));
417
432
  }
418
433
  return this.describeIndexCache.get(indexName);
419
434
  }
420
- async query(...args) {
421
- const params = this.normalizeArgs("query", args, [
422
- "minScore",
423
- "ef",
424
- "probes"
425
- ]);
426
- const { indexName, queryVector, topK = 10, filter, includeVector = false, minScore = 0, ef, probes } = params;
435
+ async query({
436
+ indexName,
437
+ queryVector,
438
+ topK = 10,
439
+ filter,
440
+ includeVector = false,
441
+ minScore = 0,
442
+ ef,
443
+ probes
444
+ }) {
445
+ if (!Number.isInteger(topK) || topK <= 0) {
446
+ throw new Error("topK must be a positive integer");
447
+ }
448
+ if (!Array.isArray(queryVector) || !queryVector.every((x) => typeof x === "number" && Number.isFinite(x))) {
449
+ throw new Error("queryVector must be an array of finite numbers");
450
+ }
427
451
  const client = await this.pool.connect();
428
452
  try {
429
453
  const vectorStr = `[${queryVector.join(",")}]`;
430
454
  const translatedFilter = this.transformFilter(filter);
431
- const { sql: filterQuery, values: filterValues } = buildFilterQuery(translatedFilter, minScore);
432
- const indexInfo = await this.getIndexInfo(indexName);
455
+ const { sql: filterQuery, values: filterValues } = buildFilterQuery(translatedFilter, minScore, topK);
456
+ const indexInfo = await this.getIndexInfo({ indexName });
433
457
  if (indexInfo.type === "hnsw") {
434
458
  const calculatedEf = ef ?? Math.max(topK, (indexInfo?.config?.m ?? 16) * topK);
435
459
  const searchEf = Math.min(1e3, Math.max(1, calculatedEf));
@@ -453,7 +477,7 @@ var PgVector = class extends vector.MastraVector {
453
477
  FROM vector_scores
454
478
  WHERE score > $1
455
479
  ORDER BY score DESC
456
- LIMIT ${topK}`;
480
+ LIMIT $2`;
457
481
  const result = await client.query(query, filterValues);
458
482
  return result.rows.map(({ id, score, metadata, embedding }) => ({
459
483
  id,
@@ -465,9 +489,7 @@ var PgVector = class extends vector.MastraVector {
465
489
  client.release();
466
490
  }
467
491
  }
468
- async upsert(...args) {
469
- const params = this.normalizeArgs("upsert", args);
470
- const { indexName, vectors, metadata, ids } = params;
492
+ async upsert({ indexName, vectors, metadata, ids }) {
471
493
  const tableName = this.getTableName(indexName);
472
494
  const client = await this.pool.connect();
473
495
  try {
@@ -494,7 +516,7 @@ var PgVector = class extends vector.MastraVector {
494
516
  if (match) {
495
517
  const [, expected, actual] = match;
496
518
  throw new Error(
497
- `Vector dimension mismatch: Index "${params.indexName}" expects ${expected} dimensions but got ${actual} dimensions. Either use a matching embedding model or delete and recreate the index with the new dimension.`
519
+ `Vector dimension mismatch: Index "${indexName}" expects ${expected} dimensions but got ${actual} dimensions. Either use a matching embedding model or delete and recreate the index with the new dimension.`
498
520
  );
499
521
  }
500
522
  }
@@ -504,8 +526,13 @@ var PgVector = class extends vector.MastraVector {
504
526
  }
505
527
  }
506
528
  hasher = xxhash__default.default();
507
- async getIndexCacheKey(params) {
508
- const input = params.indexName + params.dimension + params.metric + (params.type || "ivfflat");
529
+ async getIndexCacheKey({
530
+ indexName,
531
+ dimension,
532
+ metric,
533
+ type
534
+ }) {
535
+ const input = indexName + dimension + metric + (type || "ivfflat");
509
536
  return (await this.hasher).h32(input);
510
537
  }
511
538
  cachedIndexExists(indexName, newKey) {
@@ -553,12 +580,13 @@ var PgVector = class extends vector.MastraVector {
553
580
  }
554
581
  await this.setupSchemaPromise;
555
582
  }
556
- async createIndex(...args) {
557
- const params = this.normalizeArgs("createIndex", args, [
558
- "indexConfig",
559
- "buildIndex"
560
- ]);
561
- const { indexName, dimension, metric = "cosine", indexConfig = {}, buildIndex = true } = params;
583
+ async createIndex({
584
+ indexName,
585
+ dimension,
586
+ metric = "cosine",
587
+ indexConfig = {},
588
+ buildIndex = true
589
+ }) {
562
590
  const tableName = this.getTableName(indexName);
563
591
  if (!indexName.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)) {
564
592
  throw new Error("Invalid index name format");
@@ -599,20 +627,7 @@ var PgVector = class extends vector.MastraVector {
599
627
  }
600
628
  });
601
629
  }
602
- /**
603
- * @deprecated This function is deprecated. Use buildIndex instead
604
- * This function will be removed on May 20th, 2025
605
- */
606
- async defineIndex(indexName, metric = "cosine", indexConfig) {
607
- console.warn("defineIndex is deprecated. Use buildIndex instead. This function will be removed on May 20th, 2025");
608
- return this.buildIndex({ indexName, metric, indexConfig });
609
- }
610
- async buildIndex(...args) {
611
- const params = this.normalizeArgs("buildIndex", args, [
612
- "metric",
613
- "indexConfig"
614
- ]);
615
- const { indexName, metric = "cosine", indexConfig } = params;
630
+ async buildIndex({ indexName, metric = "cosine", indexConfig }) {
616
631
  const client = await this.pool.connect();
617
632
  try {
618
633
  await this.setupIndex({ indexName, metric, indexConfig }, client);
@@ -716,7 +731,13 @@ var PgVector = class extends vector.MastraVector {
716
731
  client.release();
717
732
  }
718
733
  }
719
- async describeIndex(indexName) {
734
+ /**
735
+ * Retrieves statistics about a vector index.
736
+ *
737
+ * @param {string} indexName - The name of the index to describe
738
+ * @returns A promise that resolves to the index statistics including dimension, count and metric
739
+ */
740
+ async describeIndex({ indexName }) {
720
741
  const client = await this.pool.connect();
721
742
  try {
722
743
  const tableName = this.getTableName(indexName);
@@ -790,7 +811,7 @@ var PgVector = class extends vector.MastraVector {
790
811
  client.release();
791
812
  }
792
813
  }
793
- async deleteIndex(indexName) {
814
+ async deleteIndex({ indexName }) {
794
815
  const client = await this.pool.connect();
795
816
  try {
796
817
  const tableName = this.getTableName(indexName);
@@ -803,7 +824,7 @@ var PgVector = class extends vector.MastraVector {
803
824
  client.release();
804
825
  }
805
826
  }
806
- async truncateIndex(indexName) {
827
+ async truncateIndex({ indexName }) {
807
828
  const client = await this.pool.connect();
808
829
  try {
809
830
  const tableName = this.getTableName(indexName);
@@ -819,8 +840,6 @@ var PgVector = class extends vector.MastraVector {
819
840
  await this.pool.end();
820
841
  }
821
842
  /**
822
- * @deprecated Use {@link updateVector} instead. This method will be removed on May 20th, 2025.
823
- *
824
843
  * Updates a vector by its ID with the provided vector and/or metadata.
825
844
  * @param indexName - The name of the index containing the vector.
826
845
  * @param id - The ID of the vector to update.
@@ -830,25 +849,7 @@ var PgVector = class extends vector.MastraVector {
830
849
  * @returns A promise that resolves when the update is complete.
831
850
  * @throws Will throw an error if no updates are provided or if the update operation fails.
832
851
  */
833
- async updateIndexById(indexName, id, update) {
834
- this.logger.warn(
835
- `Deprecation Warning: updateIndexById() is deprecated.
836
- Please use updateVector() instead.
837
- updateIndexById() will be removed on May 20th, 2025.`
838
- );
839
- await this.updateVector(indexName, id, update);
840
- }
841
- /**
842
- * Updates a vector by its ID with the provided vector and/or metadata.
843
- * @param indexName - The name of the index containing the vector.
844
- * @param id - The ID of the vector to update.
845
- * @param update - An object containing the vector and/or metadata to update.
846
- * @param update.vector - An optional array of numbers representing the new vector.
847
- * @param update.metadata - An optional record containing the new metadata.
848
- * @returns A promise that resolves when the update is complete.
849
- * @throws Will throw an error if no updates are provided or if the update operation fails.
850
- */
851
- async updateVector(indexName, id, update) {
852
+ async updateVector({ indexName, id, update }) {
852
853
  if (!update.vector && !update.metadata) {
853
854
  throw new Error("No updates provided");
854
855
  }
@@ -882,23 +883,6 @@ var PgVector = class extends vector.MastraVector {
882
883
  client.release();
883
884
  }
884
885
  }
885
- /**
886
- * @deprecated Use {@link deleteVector} instead. This method will be removed on May 20th, 2025.
887
- *
888
- * Deletes a vector by its ID.
889
- * @param indexName - The name of the index containing the vector.
890
- * @param id - The ID of the vector to delete.
891
- * @returns A promise that resolves when the deletion is complete.
892
- * @throws Will throw an error if the deletion operation fails.
893
- */
894
- async deleteIndexById(indexName, id) {
895
- this.logger.warn(
896
- `Deprecation Warning: deleteIndexById() is deprecated.
897
- Please use deleteVector() instead.
898
- deleteIndexById() will be removed on May 20th, 2025.`
899
- );
900
- await this.deleteVector(indexName, id);
901
- }
902
886
  /**
903
887
  * Deletes a vector by its ID.
904
888
  * @param indexName - The name of the index containing the vector.
@@ -906,7 +890,7 @@ var PgVector = class extends vector.MastraVector {
906
890
  * @returns A promise that resolves when the deletion is complete.
907
891
  * @throws Will throw an error if the deletion operation fails.
908
892
  */
909
- async deleteVector(indexName, id) {
893
+ async deleteVector({ indexName, id }) {
910
894
  const client = await this.pool.connect();
911
895
  try {
912
896
  const tableName = this.getTableName(indexName);
@@ -947,12 +931,7 @@ var PostgresStore = class extends storage.MastraStorage {
947
931
  }
948
932
  super({ name: "PostgresStore" });
949
933
  this.pgp = pgPromise__default.default();
950
- if ("schema" in config && config.schema) {
951
- console.warn(
952
- '[DEPRECATION NOTICE] The "schema" option in PostgresStore is deprecated. Please use "schemaName" instead. Support for "schema" will be removed on May 20th, 2025.'
953
- );
954
- }
955
- this.schema = config.schemaName ?? config.schema;
934
+ this.schema = config.schemaName;
956
935
  this.db = this.pgp(
957
936
  `connectionString` in config ? { connectionString: config.connectionString } : {
958
937
  host: config.host,
@@ -965,7 +944,9 @@ var PostgresStore = class extends storage.MastraStorage {
965
944
  );
966
945
  }
967
946
  getTableName(indexName) {
968
- return this.schema ? `${this.schema}."${indexName}"` : `"${indexName}"`;
947
+ const parsedIndexName = utils.parseSqlIdentifier(indexName, "table name");
948
+ const parsedSchemaName = this.schema ? utils.parseSqlIdentifier(this.schema, "schema name") : void 0;
949
+ return parsedSchemaName ? `${parsedSchemaName}."${parsedIndexName}"` : `"${parsedIndexName}"`;
969
950
  }
970
951
  async getEvalsByAgentName(agentName, type) {
971
952
  try {
@@ -1040,12 +1021,14 @@ var PostgresStore = class extends storage.MastraStorage {
1040
1021
  }
1041
1022
  if (attributes) {
1042
1023
  Object.keys(attributes).forEach((key) => {
1043
- conditions.push(`attributes->>'${key}' = $${idx++}`);
1024
+ const parsedKey = utils.parseSqlIdentifier(key, "attribute key");
1025
+ conditions.push(`attributes->>'${parsedKey}' = $${idx++}`);
1044
1026
  });
1045
1027
  }
1046
1028
  if (filters) {
1047
1029
  Object.entries(filters).forEach(([key]) => {
1048
- conditions.push(`${key} = $${idx++}`);
1030
+ const parsedKey = utils.parseSqlIdentifier(key, "filter key");
1031
+ conditions.push(`${parsedKey} = $${idx++}`);
1049
1032
  });
1050
1033
  }
1051
1034
  if (fromDate) {
@@ -1147,10 +1130,11 @@ var PostgresStore = class extends storage.MastraStorage {
1147
1130
  }) {
1148
1131
  try {
1149
1132
  const columns = Object.entries(schema).map(([name, def]) => {
1133
+ const parsedName = utils.parseSqlIdentifier(name, "column name");
1150
1134
  const constraints = [];
1151
1135
  if (def.primaryKey) constraints.push("PRIMARY KEY");
1152
1136
  if (!def.nullable) constraints.push("NOT NULL");
1153
- return `"${name}" ${def.type.toUpperCase()} ${constraints.join(" ")}`;
1137
+ return `"${parsedName}" ${def.type.toUpperCase()} ${constraints.join(" ")}`;
1154
1138
  }).join(",\n");
1155
1139
  if (this.schema) {
1156
1140
  await this.setupSchema();
@@ -1187,7 +1171,7 @@ var PostgresStore = class extends storage.MastraStorage {
1187
1171
  }
1188
1172
  async insert({ tableName, record }) {
1189
1173
  try {
1190
- const columns = Object.keys(record);
1174
+ const columns = Object.keys(record).map((col) => utils.parseSqlIdentifier(col, "column name"));
1191
1175
  const values = Object.values(record);
1192
1176
  const placeholders = values.map((_, i) => `$${i + 1}`).join(", ");
1193
1177
  await this.db.none(
@@ -1201,7 +1185,7 @@ var PostgresStore = class extends storage.MastraStorage {
1201
1185
  }
1202
1186
  async load({ tableName, keys }) {
1203
1187
  try {
1204
- const keyEntries = Object.entries(keys);
1188
+ const keyEntries = Object.entries(keys).map(([key, value]) => [utils.parseSqlIdentifier(key, "column name"), value]);
1205
1189
  const conditions = keyEntries.map(([key], index) => `"${key}" = $${index + 1}`).join(" AND ");
1206
1190
  const values = keyEntries.map(([_, value]) => value);
1207
1191
  const result = await this.db.oneOrNone(