@mastra/pg 0.2.6-alpha.2 → 0.2.6-alpha.4

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.
@@ -1,23 +1,23 @@
1
1
 
2
- > @mastra/pg@0.2.6-alpha.2 build /home/runner/work/mastra/mastra/stores/pg
2
+ > @mastra/pg@0.2.6-alpha.4 build /home/runner/work/mastra/mastra/stores/pg
3
3
  > tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.4.0
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 10254ms
9
+ TSC ⚡️ Build success in 10085ms
10
10
  DTS Build start
11
11
  CLI Target: es2022
12
12
  Analysis will use the bundled TypeScript version 5.8.2
13
13
  Writing package typings: /home/runner/work/mastra/mastra/stores/pg/dist/_tsup-dts-rollup.d.ts
14
14
  Analysis will use the bundled TypeScript version 5.8.2
15
15
  Writing package typings: /home/runner/work/mastra/mastra/stores/pg/dist/_tsup-dts-rollup.d.cts
16
- DTS ⚡️ Build success in 12251ms
16
+ DTS ⚡️ Build success in 10753ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- ESM dist/index.js 34.40 KB
21
- ESM ⚡️ Build success in 1257ms
22
- CJS dist/index.cjs 34.80 KB
23
- CJS ⚡️ Build success in 1259ms
20
+ ESM dist/index.js 36.43 KB
21
+ ESM ⚡️ Build success in 1230ms
22
+ CJS dist/index.cjs 36.85 KB
23
+ CJS ⚡️ Build success in 1230ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @mastra/pg
2
2
 
3
+ ## 0.2.6-alpha.4
4
+
5
+ ### Patch Changes
6
+
7
+ - e91bee7: Added helper method for both createindex and buildIndex
8
+
9
+ ## 0.2.6-alpha.3
10
+
11
+ ### Patch Changes
12
+
13
+ - 7172059: Update PG Vector to use handle concurrent createIndex
14
+ - Updated dependencies [b3b34f5]
15
+ - Updated dependencies [a4686e8]
16
+ - @mastra/core@0.7.0-alpha.3
17
+
3
18
  ## 0.2.6-alpha.2
4
19
 
5
20
  ### Patch Changes
@@ -211,6 +211,7 @@ declare class PgVector extends MastraVector {
211
211
  */
212
212
  defineIndex(indexName: string, metric: "cosine" | "euclidean" | "dotproduct" | undefined, indexConfig: IndexConfig): Promise<void>;
213
213
  buildIndex(...args: ParamsToArgs<PgDefineIndexParams> | PgDefineIndexArgs): Promise<void>;
214
+ private setupIndex;
214
215
  listIndexes(): Promise<string[]>;
215
216
  describeIndex(indexName: string): Promise<PGIndexStats>;
216
217
  deleteIndex(indexName: string): Promise<void>;
@@ -211,6 +211,7 @@ declare class PgVector extends MastraVector {
211
211
  */
212
212
  defineIndex(indexName: string, metric: "cosine" | "euclidean" | "dotproduct" | undefined, indexConfig: IndexConfig): Promise<void>;
213
213
  buildIndex(...args: ParamsToArgs<PgDefineIndexParams> | PgDefineIndexArgs): Promise<void>;
214
+ private setupIndex;
214
215
  listIndexes(): Promise<string[]>;
215
216
  describeIndex(indexName: string): Promise<PGIndexStats>;
216
217
  deleteIndex(indexName: string): Promise<void>;
package/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var crypto$1 = require('crypto');
3
4
  var vector = require('@mastra/core/vector');
4
5
  var pg = require('pg');
5
6
  var filter = require('@mastra/core/vector/filter');
@@ -420,8 +421,28 @@ var PgVector = class extends vector.MastraVector {
420
421
  if (!extensionCheck.rows[0].exists) {
421
422
  throw new Error("PostgreSQL vector extension is not available. Please install it first.");
422
423
  }
423
- await client.query("CREATE EXTENSION IF NOT EXISTS vector");
424
- await client.query(`
424
+ const hash = crypto$1.createHash("sha256").update(indexName).digest("hex");
425
+ const lockId = BigInt("0x" + hash.slice(0, 8)) % BigInt(2 ** 31);
426
+ const acquired = await client.query("SELECT pg_try_advisory_lock($1)", [lockId]);
427
+ if (!acquired.rows[0].pg_try_advisory_lock) {
428
+ const exists = await client.query(
429
+ `
430
+ SELECT 1 FROM pg_class c
431
+ JOIN pg_namespace n ON n.oid = c.relnamespace
432
+ WHERE c.relname = $1
433
+ AND n.nspname = 'public'
434
+ `,
435
+ [indexName]
436
+ );
437
+ if (exists.rows.length > 0) {
438
+ console.log(`Table ${indexName} already exists, skipping creation`);
439
+ return;
440
+ }
441
+ await client.query("SELECT pg_advisory_lock($1)", [lockId]);
442
+ }
443
+ try {
444
+ await client.query("CREATE EXTENSION IF NOT EXISTS vector");
445
+ await client.query(`
425
446
  CREATE TABLE IF NOT EXISTS ${indexName} (
426
447
  id SERIAL PRIMARY KEY,
427
448
  vector_id TEXT UNIQUE NOT NULL,
@@ -429,8 +450,11 @@ var PgVector = class extends vector.MastraVector {
429
450
  metadata JSONB DEFAULT '{}'::jsonb
430
451
  );
431
452
  `);
453
+ } finally {
454
+ await client.query("SELECT pg_advisory_unlock($1)", [lockId]);
455
+ }
432
456
  if (buildIndex) {
433
- await this.buildIndex({ indexName, metric, indexConfig });
457
+ await this.setupIndex({ indexName, metric, indexConfig }, client);
434
458
  }
435
459
  } catch (error) {
436
460
  console.error("Failed to create vector table:", error);
@@ -452,16 +476,46 @@ var PgVector = class extends vector.MastraVector {
452
476
  ]);
453
477
  const { indexName, metric = "cosine", indexConfig } = params;
454
478
  const client = await this.pool.connect();
479
+ try {
480
+ await this.setupIndex({ indexName, metric, indexConfig }, client);
481
+ } finally {
482
+ client.release();
483
+ }
484
+ }
485
+ async setupIndex({ indexName, metric, indexConfig }, client) {
486
+ const hash = crypto$1.createHash("sha256").update("build:" + indexName).digest("hex");
487
+ const lockId = BigInt("0x" + hash.slice(0, 8)) % BigInt(2 ** 31);
488
+ const acquired = await client.query("SELECT pg_try_advisory_lock($1)", [lockId]);
489
+ if (!acquired.rows[0].pg_try_advisory_lock) {
490
+ const exists = await client.query(
491
+ `
492
+ SELECT 1 FROM pg_class c
493
+ JOIN pg_namespace n ON n.oid = c.relnamespace
494
+ WHERE c.relname = $1
495
+ AND n.nspname = 'public'
496
+ `,
497
+ [`${indexName}_vector_idx`]
498
+ );
499
+ if (exists.rows.length > 0) {
500
+ console.log(`Index ${indexName}_vector_idx already exists, skipping creation`);
501
+ this.indexCache.delete(indexName);
502
+ return;
503
+ }
504
+ await client.query("SELECT pg_advisory_lock($1)", [lockId]);
505
+ }
455
506
  try {
456
507
  await client.query(`DROP INDEX IF EXISTS ${indexName}_vector_idx`);
457
- if (indexConfig.type === "flat") return;
508
+ if (indexConfig.type === "flat") {
509
+ this.indexCache.delete(indexName);
510
+ return;
511
+ }
458
512
  const metricOp = metric === "cosine" ? "vector_cosine_ops" : metric === "euclidean" ? "vector_l2_ops" : "vector_ip_ops";
459
513
  let indexSQL;
460
514
  if (indexConfig.type === "hnsw") {
461
515
  const m = indexConfig.hnsw?.m ?? 8;
462
516
  const efConstruction = indexConfig.hnsw?.efConstruction ?? 32;
463
517
  indexSQL = `
464
- CREATE INDEX ${indexName}_vector_idx
518
+ CREATE INDEX IF NOT EXISTS ${indexName}_vector_idx
465
519
  ON ${indexName}
466
520
  USING hnsw (embedding ${metricOp})
467
521
  WITH (
@@ -478,7 +532,7 @@ var PgVector = class extends vector.MastraVector {
478
532
  lists = Math.max(100, Math.min(4e3, Math.floor(Math.sqrt(size) * 2)));
479
533
  }
480
534
  indexSQL = `
481
- CREATE INDEX ${indexName}_vector_idx
535
+ CREATE INDEX IF NOT EXISTS ${indexName}_vector_idx
482
536
  ON ${indexName}
483
537
  USING ivfflat (embedding ${metricOp})
484
538
  WITH (lists = ${lists});
@@ -487,7 +541,7 @@ var PgVector = class extends vector.MastraVector {
487
541
  await client.query(indexSQL);
488
542
  this.indexCache.delete(indexName);
489
543
  } finally {
490
- client.release();
544
+ await client.query("SELECT pg_advisory_unlock($1)", [lockId]);
491
545
  }
492
546
  }
493
547
  async listIndexes() {
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createHash } from 'crypto';
1
2
  import { MastraVector } from '@mastra/core/vector';
2
3
  import pg from 'pg';
3
4
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
@@ -413,8 +414,28 @@ var PgVector = class extends MastraVector {
413
414
  if (!extensionCheck.rows[0].exists) {
414
415
  throw new Error("PostgreSQL vector extension is not available. Please install it first.");
415
416
  }
416
- await client.query("CREATE EXTENSION IF NOT EXISTS vector");
417
- await client.query(`
417
+ const hash = createHash("sha256").update(indexName).digest("hex");
418
+ const lockId = BigInt("0x" + hash.slice(0, 8)) % BigInt(2 ** 31);
419
+ const acquired = await client.query("SELECT pg_try_advisory_lock($1)", [lockId]);
420
+ if (!acquired.rows[0].pg_try_advisory_lock) {
421
+ const exists = await client.query(
422
+ `
423
+ SELECT 1 FROM pg_class c
424
+ JOIN pg_namespace n ON n.oid = c.relnamespace
425
+ WHERE c.relname = $1
426
+ AND n.nspname = 'public'
427
+ `,
428
+ [indexName]
429
+ );
430
+ if (exists.rows.length > 0) {
431
+ console.log(`Table ${indexName} already exists, skipping creation`);
432
+ return;
433
+ }
434
+ await client.query("SELECT pg_advisory_lock($1)", [lockId]);
435
+ }
436
+ try {
437
+ await client.query("CREATE EXTENSION IF NOT EXISTS vector");
438
+ await client.query(`
418
439
  CREATE TABLE IF NOT EXISTS ${indexName} (
419
440
  id SERIAL PRIMARY KEY,
420
441
  vector_id TEXT UNIQUE NOT NULL,
@@ -422,8 +443,11 @@ var PgVector = class extends MastraVector {
422
443
  metadata JSONB DEFAULT '{}'::jsonb
423
444
  );
424
445
  `);
446
+ } finally {
447
+ await client.query("SELECT pg_advisory_unlock($1)", [lockId]);
448
+ }
425
449
  if (buildIndex) {
426
- await this.buildIndex({ indexName, metric, indexConfig });
450
+ await this.setupIndex({ indexName, metric, indexConfig }, client);
427
451
  }
428
452
  } catch (error) {
429
453
  console.error("Failed to create vector table:", error);
@@ -445,16 +469,46 @@ var PgVector = class extends MastraVector {
445
469
  ]);
446
470
  const { indexName, metric = "cosine", indexConfig } = params;
447
471
  const client = await this.pool.connect();
472
+ try {
473
+ await this.setupIndex({ indexName, metric, indexConfig }, client);
474
+ } finally {
475
+ client.release();
476
+ }
477
+ }
478
+ async setupIndex({ indexName, metric, indexConfig }, client) {
479
+ const hash = createHash("sha256").update("build:" + indexName).digest("hex");
480
+ const lockId = BigInt("0x" + hash.slice(0, 8)) % BigInt(2 ** 31);
481
+ const acquired = await client.query("SELECT pg_try_advisory_lock($1)", [lockId]);
482
+ if (!acquired.rows[0].pg_try_advisory_lock) {
483
+ const exists = await client.query(
484
+ `
485
+ SELECT 1 FROM pg_class c
486
+ JOIN pg_namespace n ON n.oid = c.relnamespace
487
+ WHERE c.relname = $1
488
+ AND n.nspname = 'public'
489
+ `,
490
+ [`${indexName}_vector_idx`]
491
+ );
492
+ if (exists.rows.length > 0) {
493
+ console.log(`Index ${indexName}_vector_idx already exists, skipping creation`);
494
+ this.indexCache.delete(indexName);
495
+ return;
496
+ }
497
+ await client.query("SELECT pg_advisory_lock($1)", [lockId]);
498
+ }
448
499
  try {
449
500
  await client.query(`DROP INDEX IF EXISTS ${indexName}_vector_idx`);
450
- if (indexConfig.type === "flat") return;
501
+ if (indexConfig.type === "flat") {
502
+ this.indexCache.delete(indexName);
503
+ return;
504
+ }
451
505
  const metricOp = metric === "cosine" ? "vector_cosine_ops" : metric === "euclidean" ? "vector_l2_ops" : "vector_ip_ops";
452
506
  let indexSQL;
453
507
  if (indexConfig.type === "hnsw") {
454
508
  const m = indexConfig.hnsw?.m ?? 8;
455
509
  const efConstruction = indexConfig.hnsw?.efConstruction ?? 32;
456
510
  indexSQL = `
457
- CREATE INDEX ${indexName}_vector_idx
511
+ CREATE INDEX IF NOT EXISTS ${indexName}_vector_idx
458
512
  ON ${indexName}
459
513
  USING hnsw (embedding ${metricOp})
460
514
  WITH (
@@ -471,7 +525,7 @@ var PgVector = class extends MastraVector {
471
525
  lists = Math.max(100, Math.min(4e3, Math.floor(Math.sqrt(size) * 2)));
472
526
  }
473
527
  indexSQL = `
474
- CREATE INDEX ${indexName}_vector_idx
528
+ CREATE INDEX IF NOT EXISTS ${indexName}_vector_idx
475
529
  ON ${indexName}
476
530
  USING ivfflat (embedding ${metricOp})
477
531
  WITH (lists = ${lists});
@@ -480,7 +534,7 @@ var PgVector = class extends MastraVector {
480
534
  await client.query(indexSQL);
481
535
  this.indexCache.delete(indexName);
482
536
  } finally {
483
- client.release();
537
+ await client.query("SELECT pg_advisory_unlock($1)", [lockId]);
484
538
  }
485
539
  }
486
540
  async listIndexes() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/pg",
3
- "version": "0.2.6-alpha.2",
3
+ "version": "0.2.6-alpha.4",
4
4
  "description": "Postgres provider for Mastra - includes both vector and db storage capabilities",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "dependencies": {
22
22
  "pg": "^8.13.3",
23
23
  "pg-promise": "^11.11.0",
24
- "@mastra/core": "^0.7.0-alpha.2"
24
+ "@mastra/core": "^0.7.0-alpha.3"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@microsoft/api-extractor": "^7.52.1",
@@ -1,7 +1,7 @@
1
+ import type { QueryResult } from '@mastra/core';
1
2
  import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach, vi } from 'vitest';
2
3
 
3
4
  import { PgVector } from '.';
4
- import { type QueryResult } from '@mastra/core';
5
5
 
6
6
  describe('PgVector', () => {
7
7
  let vectorDB: PgVector;
@@ -1812,4 +1812,47 @@ describe('PgVector', () => {
1812
1812
  await expect(vectorDB.buildIndex(indexName, 'cosine', { type: 'flat' })).resolves.not.toThrow();
1813
1813
  });
1814
1814
  });
1815
+
1816
+ describe('Concurrent Operations', () => {
1817
+ it('should handle concurrent index creation attempts', async () => {
1818
+ const indexName = 'concurrent_test_index';
1819
+ const dimension = 384;
1820
+
1821
+ // Create multiple promises trying to create the same index
1822
+ const promises = Array(5)
1823
+ .fill(null)
1824
+ .map(() => vectorDB.createIndex({ indexName, dimension }));
1825
+
1826
+ // All should resolve without error - subsequent attempts should be no-ops
1827
+ await expect(Promise.all(promises)).resolves.not.toThrow();
1828
+
1829
+ // Verify only one index was actually created
1830
+ const stats = await vectorDB.describeIndex(indexName);
1831
+ expect(stats.dimension).toBe(dimension);
1832
+
1833
+ await vectorDB.deleteIndex(indexName);
1834
+ });
1835
+
1836
+ it('should handle concurrent buildIndex attempts', async () => {
1837
+ const indexName = 'concurrent_build_test';
1838
+ await vectorDB.createIndex({ indexName, dimension: 384 });
1839
+
1840
+ const promises = Array(5)
1841
+ .fill(null)
1842
+ .map(() =>
1843
+ vectorDB.buildIndex({
1844
+ indexName,
1845
+ metric: 'cosine',
1846
+ indexConfig: { type: 'ivfflat', ivf: { lists: 100 } },
1847
+ }),
1848
+ );
1849
+
1850
+ await expect(Promise.all(promises)).resolves.not.toThrow();
1851
+
1852
+ const stats = await vectorDB.describeIndex(indexName);
1853
+ expect(stats.type).toBe('ivfflat');
1854
+
1855
+ await vectorDB.deleteIndex(indexName);
1856
+ });
1857
+ });
1815
1858
  });
@@ -1,3 +1,4 @@
1
+ import { createHash } from 'crypto';
1
2
  import { MastraVector } from '@mastra/core/vector';
2
3
  import type {
3
4
  IndexStats,
@@ -215,11 +216,39 @@ export class PgVector extends MastraVector {
215
216
  throw new Error('PostgreSQL vector extension is not available. Please install it first.');
216
217
  }
217
218
 
218
- // Try to create extension
219
- await client.query('CREATE EXTENSION IF NOT EXISTS vector');
219
+ // Get advisory lock using hash of index name
220
+ const hash = createHash('sha256').update(indexName).digest('hex');
221
+ const lockId = BigInt('0x' + hash.slice(0, 8)) % BigInt(2 ** 31); // Take first 8 chars and convert to number
222
+ const acquired = await client.query('SELECT pg_try_advisory_lock($1)', [lockId]);
223
+
224
+ if (!acquired.rows[0].pg_try_advisory_lock) {
225
+ // Check if table already exists
226
+ const exists = await client.query(
227
+ `
228
+ SELECT 1 FROM pg_class c
229
+ JOIN pg_namespace n ON n.oid = c.relnamespace
230
+ WHERE c.relname = $1
231
+ AND n.nspname = 'public'
232
+ `,
233
+ [indexName],
234
+ );
235
+
236
+ if (exists.rows.length > 0) {
237
+ // Table exists so return early
238
+ console.log(`Table ${indexName} already exists, skipping creation`);
239
+ return;
240
+ }
241
+
242
+ // Table doesn't exist, wait for lock
243
+ await client.query('SELECT pg_advisory_lock($1)', [lockId]);
244
+ }
245
+
246
+ try {
247
+ // Try to create extension
248
+ await client.query('CREATE EXTENSION IF NOT EXISTS vector');
220
249
 
221
- // Create the table with explicit schema
222
- await client.query(`
250
+ // Create the table with explicit schema
251
+ await client.query(`
223
252
  CREATE TABLE IF NOT EXISTS ${indexName} (
224
253
  id SERIAL PRIMARY KEY,
225
254
  vector_id TEXT UNIQUE NOT NULL,
@@ -227,9 +256,13 @@ export class PgVector extends MastraVector {
227
256
  metadata JSONB DEFAULT '{}'::jsonb
228
257
  );
229
258
  `);
259
+ } finally {
260
+ // Always release lock
261
+ await client.query('SELECT pg_advisory_unlock($1)', [lockId]);
262
+ }
230
263
 
231
264
  if (buildIndex) {
232
- await this.buildIndex({ indexName, metric, indexConfig });
265
+ await this.setupIndex({ indexName, metric, indexConfig }, client);
233
266
  }
234
267
  } catch (error: any) {
235
268
  console.error('Failed to create vector table:', error);
@@ -259,10 +292,50 @@ export class PgVector extends MastraVector {
259
292
  const { indexName, metric = 'cosine', indexConfig } = params;
260
293
 
261
294
  const client = await this.pool.connect();
295
+ try {
296
+ await this.setupIndex({ indexName, metric, indexConfig }, client);
297
+ } finally {
298
+ client.release();
299
+ }
300
+ }
301
+
302
+ private async setupIndex({ indexName, metric, indexConfig }: PgDefineIndexParams, client: pg.PoolClient) {
303
+ // Use a different hash prefix for buildIndex locks to avoid conflicts with createIndex
304
+ const hash = createHash('sha256')
305
+ .update('build:' + indexName)
306
+ .digest('hex');
307
+ const lockId = BigInt('0x' + hash.slice(0, 8)) % BigInt(2 ** 31);
308
+ const acquired = await client.query('SELECT pg_try_advisory_lock($1)', [lockId]);
309
+
310
+ if (!acquired.rows[0].pg_try_advisory_lock) {
311
+ // Check if index already exists
312
+ const exists = await client.query(
313
+ `
314
+ SELECT 1 FROM pg_class c
315
+ JOIN pg_namespace n ON n.oid = c.relnamespace
316
+ WHERE c.relname = $1
317
+ AND n.nspname = 'public'
318
+ `,
319
+ [`${indexName}_vector_idx`],
320
+ );
321
+
322
+ if (exists.rows.length > 0) {
323
+ console.log(`Index ${indexName}_vector_idx already exists, skipping creation`);
324
+ this.indexCache.delete(indexName); // Still clear cache since we checked
325
+ return;
326
+ }
327
+
328
+ // Index doesn't exist, wait for lock
329
+ await client.query('SELECT pg_advisory_lock($1)', [lockId]);
330
+ }
331
+
262
332
  try {
263
333
  await client.query(`DROP INDEX IF EXISTS ${indexName}_vector_idx`);
264
334
 
265
- if (indexConfig.type === 'flat') return;
335
+ if (indexConfig.type === 'flat') {
336
+ this.indexCache.delete(indexName);
337
+ return;
338
+ }
266
339
 
267
340
  const metricOp =
268
341
  metric === 'cosine' ? 'vector_cosine_ops' : metric === 'euclidean' ? 'vector_l2_ops' : 'vector_ip_ops';
@@ -273,7 +346,7 @@ export class PgVector extends MastraVector {
273
346
  const efConstruction = indexConfig.hnsw?.efConstruction ?? 32;
274
347
 
275
348
  indexSQL = `
276
- CREATE INDEX ${indexName}_vector_idx
349
+ CREATE INDEX IF NOT EXISTS ${indexName}_vector_idx
277
350
  ON ${indexName}
278
351
  USING hnsw (embedding ${metricOp})
279
352
  WITH (
@@ -290,7 +363,7 @@ export class PgVector extends MastraVector {
290
363
  lists = Math.max(100, Math.min(4000, Math.floor(Math.sqrt(size) * 2)));
291
364
  }
292
365
  indexSQL = `
293
- CREATE INDEX ${indexName}_vector_idx
366
+ CREATE INDEX IF NOT EXISTS ${indexName}_vector_idx
294
367
  ON ${indexName}
295
368
  USING ivfflat (embedding ${metricOp})
296
369
  WITH (lists = ${lists});
@@ -300,7 +373,7 @@ export class PgVector extends MastraVector {
300
373
  await client.query(indexSQL);
301
374
  this.indexCache.delete(indexName);
302
375
  } finally {
303
- client.release();
376
+ await client.query('SELECT pg_advisory_unlock($1)', [lockId]);
304
377
  }
305
378
  }
306
379