@nicia-ai/typegraph 0.38.0 → 0.39.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.
Files changed (95) hide show
  1. package/dist/backend/postgres/index.cjs +16 -16
  2. package/dist/backend/postgres/index.js +3 -3
  3. package/dist/backend/postgres/pglite-store.cjs +11 -11
  4. package/dist/backend/postgres/pglite-store.d.cts +1 -1
  5. package/dist/backend/postgres/pglite-store.d.ts +1 -1
  6. package/dist/backend/postgres/pglite-store.js +8 -8
  7. package/dist/backend/postgres/pglite.cjs +5 -5
  8. package/dist/backend/postgres/pglite.js +4 -4
  9. package/dist/backend/sqlite/index.cjs +6 -6
  10. package/dist/backend/sqlite/index.js +3 -3
  11. package/dist/backend/sqlite/libsql.cjs +5 -5
  12. package/dist/backend/sqlite/libsql.js +3 -3
  13. package/dist/backend/sqlite/local-store.cjs +11 -11
  14. package/dist/backend/sqlite/local-store.d.cts +1 -1
  15. package/dist/backend/sqlite/local-store.d.ts +1 -1
  16. package/dist/backend/sqlite/local-store.js +9 -9
  17. package/dist/backend/sqlite/local.cjs +6 -6
  18. package/dist/backend/sqlite/local.js +4 -4
  19. package/dist/{chunk-UPXDVI3T.js → chunk-3SK4SVTW.js} +3 -3
  20. package/dist/{chunk-UPXDVI3T.js.map → chunk-3SK4SVTW.js.map} +1 -1
  21. package/dist/{chunk-NU23DUSJ.cjs → chunk-3YFDFOYB.cjs} +7 -7
  22. package/dist/{chunk-NU23DUSJ.cjs.map → chunk-3YFDFOYB.cjs.map} +1 -1
  23. package/dist/{chunk-NWYCOFEZ.cjs → chunk-5ELKD2FQ.cjs} +4 -4
  24. package/dist/chunk-5ELKD2FQ.cjs.map +1 -0
  25. package/dist/{chunk-2SL7OGPR.cjs → chunk-6SRLCSAV.cjs} +478 -338
  26. package/dist/chunk-6SRLCSAV.cjs.map +1 -0
  27. package/dist/{chunk-A2FGSWMQ.js → chunk-CBK2IVI2.js} +167 -27
  28. package/dist/chunk-CBK2IVI2.js.map +1 -0
  29. package/dist/{chunk-TE5ZA4VX.js → chunk-DOKUXLFH.js} +14 -10
  30. package/dist/chunk-DOKUXLFH.js.map +1 -0
  31. package/dist/{chunk-KCLZHYPU.cjs → chunk-E2Q7SP2K.cjs} +52 -52
  32. package/dist/{chunk-KCLZHYPU.cjs.map → chunk-E2Q7SP2K.cjs.map} +1 -1
  33. package/dist/{chunk-YLINFV7Z.cjs → chunk-GKQU44SQ.cjs} +67 -63
  34. package/dist/chunk-GKQU44SQ.cjs.map +1 -0
  35. package/dist/{chunk-O5H62ZWJ.cjs → chunk-HP6LWBLB.cjs} +14 -2
  36. package/dist/chunk-HP6LWBLB.cjs.map +1 -0
  37. package/dist/{chunk-7VLCN3JB.cjs → chunk-HTQOBY75.cjs} +59 -59
  38. package/dist/{chunk-7VLCN3JB.cjs.map → chunk-HTQOBY75.cjs.map} +1 -1
  39. package/dist/{chunk-RQPRCEIO.js → chunk-IFDXG2YJ.js} +3 -3
  40. package/dist/chunk-IFDXG2YJ.js.map +1 -0
  41. package/dist/{chunk-YJDSPA5E.js → chunk-IFRPHG7O.js} +4 -4
  42. package/dist/{chunk-YJDSPA5E.js.map → chunk-IFRPHG7O.js.map} +1 -1
  43. package/dist/{chunk-LZ3TVJY4.cjs → chunk-JD2YC62H.cjs} +17 -17
  44. package/dist/{chunk-LZ3TVJY4.cjs.map → chunk-JD2YC62H.cjs.map} +1 -1
  45. package/dist/{chunk-XD6X7O5R.js → chunk-KAFXPB2L.js} +4 -4
  46. package/dist/{chunk-XD6X7O5R.js.map → chunk-KAFXPB2L.js.map} +1 -1
  47. package/dist/{chunk-ZHX4KEM7.cjs → chunk-KIZSHRUI.cjs} +7 -7
  48. package/dist/{chunk-ZHX4KEM7.cjs.map → chunk-KIZSHRUI.cjs.map} +1 -1
  49. package/dist/{chunk-G32AO634.js → chunk-KXFUQNF2.js} +3 -3
  50. package/dist/{chunk-G32AO634.js.map → chunk-KXFUQNF2.js.map} +1 -1
  51. package/dist/{chunk-E6YZRKMM.js → chunk-NQBYTLPW.js} +4 -4
  52. package/dist/{chunk-E6YZRKMM.js.map → chunk-NQBYTLPW.js.map} +1 -1
  53. package/dist/{chunk-VBH7ZXSZ.js → chunk-SU7VQOJ3.js} +3 -3
  54. package/dist/{chunk-VBH7ZXSZ.js.map → chunk-SU7VQOJ3.js.map} +1 -1
  55. package/dist/{chunk-KFLXWVUJ.js → chunk-UUIBACKJ.js} +14 -3
  56. package/dist/chunk-UUIBACKJ.js.map +1 -0
  57. package/dist/{chunk-CQC6VBAF.cjs → chunk-VXAFOF6Z.cjs} +5 -5
  58. package/dist/{chunk-CQC6VBAF.cjs.map → chunk-VXAFOF6Z.cjs.map} +1 -1
  59. package/dist/{chunk-XFY73JWD.cjs → chunk-Y6UA55YS.cjs} +5 -5
  60. package/dist/{chunk-XFY73JWD.cjs.map → chunk-Y6UA55YS.cjs.map} +1 -1
  61. package/dist/{chunk-6G5CQ6JX.js → chunk-YPUNPG2T.js} +4 -4
  62. package/dist/{chunk-6G5CQ6JX.js.map → chunk-YPUNPG2T.js.map} +1 -1
  63. package/dist/graph-merge/index.cjs +30 -32
  64. package/dist/graph-merge/index.cjs.map +1 -1
  65. package/dist/graph-merge/index.d.cts +10 -5
  66. package/dist/graph-merge/index.d.ts +10 -5
  67. package/dist/graph-merge/index.js +9 -11
  68. package/dist/graph-merge/index.js.map +1 -1
  69. package/dist/index.cjs +68 -68
  70. package/dist/index.d.cts +2 -2
  71. package/dist/index.d.ts +2 -2
  72. package/dist/index.js +5 -5
  73. package/dist/interchange/index.cjs +23 -23
  74. package/dist/interchange/index.d.cts +1 -1
  75. package/dist/interchange/index.d.ts +1 -1
  76. package/dist/interchange/index.js +4 -4
  77. package/dist/profiler/index.d.cts +1 -1
  78. package/dist/profiler/index.d.ts +1 -1
  79. package/dist/provenance/index.cjs +11 -11
  80. package/dist/provenance/index.d.cts +1 -1
  81. package/dist/provenance/index.d.ts +1 -1
  82. package/dist/provenance/index.js +2 -2
  83. package/dist/schema/index.cjs +22 -22
  84. package/dist/schema/index.js +3 -3
  85. package/dist/{store-view-BoHqdHjB.d.cts → store-view-BJd6Vwpt.d.cts} +39 -17
  86. package/dist/{store-view-Ctq-3OHy.d.ts → store-view-CLIhwMMX.d.ts} +39 -17
  87. package/package.json +1 -1
  88. package/dist/chunk-2SL7OGPR.cjs.map +0 -1
  89. package/dist/chunk-A2FGSWMQ.js.map +0 -1
  90. package/dist/chunk-KFLXWVUJ.js.map +0 -1
  91. package/dist/chunk-NWYCOFEZ.cjs.map +0 -1
  92. package/dist/chunk-O5H62ZWJ.cjs.map +0 -1
  93. package/dist/chunk-RQPRCEIO.js.map +0 -1
  94. package/dist/chunk-TE5ZA4VX.js.map +0 -1
  95. package/dist/chunk-YLINFV7Z.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/backend/drizzle/execution/postgres-execution.ts","../src/backend/drizzle/execution/statement-queue.ts","../src/backend/drizzle/postgres.ts"],"names":["sql","tables","backend","options","chunk"],"mappings":"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","file":"chunk-YJDSPA5E.js","sourcesContent":["import { type SQL as DrizzleSql } from \"drizzle-orm\";\nimport {\n type PgDatabase,\n type PgQueryResultHKT,\n type PgTransaction,\n} from \"drizzle-orm/pg-core\";\nimport { type ExtractTablesWithRelations } from \"drizzle-orm/relations\";\n\nimport { isSqlFragment } from \"../../../query/sql-fragment\";\nimport { shouldForceCustomPlan } from \"../../../query/sql-intent\";\nimport { getOrCreateLru } from \"./lru\";\nimport {\n type CompiledSqlQuery,\n compileQueryWithDialect,\n type ExecutableSql,\n type PreparedSqlStatement,\n type SqlExecutionAdapter,\n toDrizzleSql,\n} from \"./types\";\n\n/**\n * Edge-safe: this module is loaded on Cloudflare Workers / Vercel Edge\n * via `@neondatabase/serverless`, so it must not statically import any\n * `node:*` module. Use only platform-neutral primitives.\n */\n\ntype PgQueryResult = Readonly<{\n rows: readonly unknown[];\n}>;\n\n/**\n * The wire-protocol-shaped client the fast path calls. Both the wrapped\n * node-postgres and postgres-js clients normalize to this signature; what\n * differs is whether the underlying driver gets a server-side prepared\n * statement (node-postgres path) or relies on its own internal preparation\n * (postgres-js).\n */\ntype PgQueryClient = Readonly<{\n query: (\n sqlText: string,\n params: readonly unknown[],\n ) => Promise<PgQueryResult>;\n /**\n * Executes WITHOUT a named server-side prepared statement, so the\n * server plans against the actual parameter values on every call.\n * Used for statements marked `markForceCustomPlan` (see sql-intent).\n */\n queryUnnamed: (\n sqlText: string,\n params: readonly unknown[],\n ) => Promise<PgQueryResult>;\n}>;\n\n/**\n * Minimal shape of the node-postgres / @neondatabase/serverless client\n * we rely on. Both accept either positional `query(text, values)`\n * (unnamed) or the configuration-object form `query({name, text, values})`\n * which uses a server-side prepared statement keyed by `name`.\n */\ntype NodePgQueryConfig = Readonly<{\n name: string;\n text: string;\n values: readonly unknown[];\n}>;\n\ntype NodePgClient = Readonly<{\n query: ((\n sqlText: string,\n params?: readonly unknown[],\n ) => Promise<PgQueryResult>) &\n ((config: NodePgQueryConfig) => Promise<PgQueryResult>);\n}>;\n\n/**\n * Minimal shape of the postgres-js tagged-template `Sql` client we rely on\n * for the raw fast path. `unsafe(sqlText, params)` is postgres-js's\n * parameterized-raw-SQL entry point and resolves to a row array.\n */\ntype PostgresJsClient = ((...args: readonly unknown[]) => unknown) &\n Readonly<{\n unsafe: (\n sqlText: string,\n params?: readonly unknown[],\n queryOptions?: Readonly<{ prepare?: boolean }>,\n ) => PromiseLike<readonly unknown[]>;\n }>;\n\ntype PgSessionCarrier = Readonly<{\n client?: unknown;\n constructor?: Readonly<{ name?: string }>;\n}>;\n\ntype PgClientCarrier = Readonly<{\n $client?: unknown;\n /** Drizzle's transaction handle keeps the pinned driver here. */\n session?: PgSessionCarrier;\n /** Defensive fallback for Drizzle builds exposing only the internal bag. */\n _?: Readonly<{\n session?: PgSessionCarrier;\n }>;\n}>;\n\nexport type AnyPgDatabase = PgDatabase<\n PgQueryResultHKT,\n Record<string, unknown>\n>;\n\n/**\n * A driver-agnostic Drizzle PostgreSQL transaction handle.\n *\n * Unlike {@link AnyPgDatabase}, this type cannot be satisfied by a root\n * database. It is the native handle exposed to adapter-aware stores and\n * accepted when adopting a caller-owned PostgreSQL transaction.\n */\nexport type AnyPgTransaction = PgTransaction<\n PgQueryResultHKT,\n Record<string, unknown>,\n ExtractTablesWithRelations<Record<string, unknown>>\n>;\n\nexport type PostgresExecutionAdapter = SqlExecutionAdapter;\n\nfunction hasFunctionProperty<K extends string>(\n value: unknown,\n property: K,\n): value is Readonly<Record<K, (...args: readonly unknown[]) => unknown>> {\n if (value === undefined || value === null) {\n return false;\n }\n const candidate = value as Readonly<Record<K, unknown>>;\n return typeof candidate[property] === \"function\";\n}\n\nfunction isPgNativeClient(candidate: unknown): candidate is NodePgClient {\n // pg `Pool` / `Client` and @neondatabase/serverless `Pool` / `Client`\n // are object instances with a `.query` method. We require non-callable\n // here so we don't accidentally swallow the postgres-js or neon-http\n // tagged-template clients (both callable, both also expose `.query`).\n return (\n typeof candidate === \"object\" && hasFunctionProperty(candidate, \"query\")\n );\n}\n\nfunction isPgliteClient(candidate: unknown): candidate is NodePgClient {\n // PGlite (Postgres-in-WASM) exposes `.query(sql, params, options)` like\n // node-postgres and so also satisfies `isPgNativeClient` — but it does NOT\n // accept the `{name, text, values}` named-statement config form. Passing\n // that object doesn't merely fail the call: it desyncs PGlite's single\n // wire connection, so every subsequent query errors with `08P01`. Detect\n // PGlite structurally via `dumpDataDir` (a PGlite-specific method absent on\n // pg `Pool`/`Client`) so `resolvePgClient` can route it to the unnamed\n // positional wrapper regardless of `prepareStatements`. Duck-typed with no\n // static import, keeping this module dependency-free and edge-safe.\n return (\n typeof candidate === \"object\" &&\n hasFunctionProperty(candidate, \"query\") &&\n hasFunctionProperty(candidate, \"dumpDataDir\")\n );\n}\n\nfunction transactionSession(\n carrier: PgClientCarrier,\n): PgSessionCarrier | undefined {\n return carrier.session ?? carrier._?.session;\n}\n\nfunction hasPgliteSession(carrier: PgClientCarrier): boolean {\n return transactionSession(carrier)?.constructor?.name === \"PgliteSession\";\n}\n\nfunction isPostgresJsClient(candidate: unknown): candidate is PostgresJsClient {\n // postgres-js's tagged-template Sql is callable, has `.unsafe` (raw\n // parameterized executor), and has `.begin` (transaction starter). The\n // transaction-scoped `TransactionSql` replaces `.begin` with `.savepoint`;\n // accept either so a Drizzle transaction keeps the fast path pinned.\n // Neon HTTP is also callable + has `.unsafe`, but that `.unsafe` is a\n // fragment builder rather than a query executor, so we discriminate\n // on `.begin` / `.savepoint` (postgres-js only).\n return (\n typeof candidate === \"function\" &&\n hasFunctionProperty(candidate, \"unsafe\") &&\n (hasFunctionProperty(candidate, \"begin\") ||\n hasFunctionProperty(candidate, \"savepoint\"))\n );\n}\n\n/**\n * @neondatabase/serverless's `neon(url)` HTTP-only tagged-template\n * function. Distinguishing markers vs postgres-js: `.transaction`\n * (an HTTP-batch transaction submitter) instead of `.begin`. Its\n * `.query`/`.unsafe` methods have different signatures from pg's, so\n * the fast path can't drive them safely — Drizzle's neon-http session\n * handles them correctly via the `db.execute` slow path.\n *\n * Exported so the backend factory can auto-disable the `transactions`\n * capability when this driver is detected (HTTP can't hold a session,\n * so multi-statement transactions are not available regardless).\n */\nexport function isNeonHttpClient(db: AnyPgDatabase): boolean {\n const candidate = (db as PgClientCarrier).$client;\n return (\n typeof candidate === \"function\" &&\n hasFunctionProperty(candidate, \"transaction\") &&\n !hasFunctionProperty(candidate, \"begin\")\n );\n}\n\n/**\n * Default cap on the number of distinct SQL strings tracked for\n * server-side prepared statements. Mirrors the SQLite adapter's\n * `DEFAULT_PREPARED_STATEMENT_CACHE_MAX`. High-cardinality SQL text —\n * variable-length IN-list expansions, generated aliases, custom\n * `backend.execute()` calls — would otherwise grow this map (and the\n * matching per-session prepared-statement memory inside PostgreSQL)\n * without bound.\n */\nconst DEFAULT_POSTGRES_STATEMENT_CACHE_MAX = 256;\n\n/**\n * Module-scope cache mapping each unique SQL text to a stable\n * prepared-statement name. PostgreSQL only requires statement names to\n * be unique per session, so a monotonic counter is sufficient — and\n * avoids depending on a hash primitive (`node:crypto` doesn't exist on\n * Cloudflare Workers, Web Crypto's digest is async).\n *\n * The cache is module-scope on purpose: pg `Pool` reuses connections,\n * and the same SQL text needs the same statement name across every\n * adapter that might end up driving the same connection. Without\n * shared naming, two adapters could try to register two different\n * statements under the same name on a recycled connection.\n *\n * Bounded by `cacheMax` per call (LRU eviction). The counter is\n * deliberately independent of the cache size so eviction never\n * recycles a name — a recycled name could collide with a still-cached\n * statement on a long-lived pg connection (\"prepared statement\n * already exists\" error with different text).\n */\nconst STATEMENT_NAME_CACHE = new Map<string, string>();\nlet nextStatementId = 0;\n\nfunction statementNameFor(sqlText: string, cacheMax: number): string {\n return getOrCreateLru(STATEMENT_NAME_CACHE, sqlText, cacheMax, () => {\n const name = `tg_${nextStatementId}`;\n nextStatementId += 1;\n return name;\n });\n}\n\n/**\n * Test-only: reset the module-scope statement-name state. Used to\n * isolate tests that assert on counter values or eviction behavior.\n */\nexport function resetStatementNameCacheForTests(): void {\n STATEMENT_NAME_CACHE.clear();\n nextStatementId = 0;\n}\n\n/**\n * Walks a row and replaces any `Date` instance with its ISO-string\n * equivalent. Used to normalize node-postgres / neon-serverless output\n * when we bypass Drizzle's session: pg's default type parsers return\n * `Date` objects for `timestamptz` / `timestamp` / `date` columns, but\n * TypeGraph's row contract everywhere downstream is \"timestamps come\n * back as ISO strings.\" Drizzle's session installs a per-query type\n * override that does the same thing; this is the dependency-free,\n * edge-safe equivalent.\n *\n * O(columns × rows) — negligible for the row counts TypeGraph queries\n * return (typical: 1–100 rows × 5–30 columns).\n */\nfunction normalizeRow(row: unknown): unknown {\n if (row === null || typeof row !== \"object\") return row;\n let mutated: Record<string, unknown> | undefined;\n for (const key of Object.keys(row)) {\n const value = (row as Record<string, unknown>)[key];\n if (value instanceof Date) {\n mutated ??= { ...(row as Record<string, unknown>) };\n mutated[key] = value.toISOString();\n }\n }\n return mutated ?? row;\n}\n\nfunction normalizeRows(rows: readonly unknown[]): readonly unknown[] {\n // Single-pass scan; only allocate a new array if any row contained a\n // Date that needed normalizing. Most rows on most queries don't.\n let mutated: unknown[] | undefined;\n for (let index = 0; index < rows.length; index += 1) {\n const original = rows[index];\n const normalized = normalizeRow(original);\n if (normalized !== original) {\n mutated ??= [...rows] as unknown[];\n mutated[index] = normalized;\n }\n }\n return mutated ?? rows;\n}\n\n/**\n * Wraps a node-postgres / neon-serverless client so every call goes\n * through a server-side prepared statement keyed by a stable name. The\n * first call on each connection parses + plans + executes; subsequent\n * calls with the same statement name reuse the cached plan and skip\n * both parse and plan phases. Measurable on multi-CTE TypeGraph\n * queries: 3-hop drops from ~7-12ms (parse + plan + execute every call)\n * to ~0.8ms median (execute only).\n *\n * Returned rows are normalized so that `Date` objects from default pg\n * type parsers become ISO strings, matching the row shape Drizzle's\n * session would produce. Without this, `ctx.<alias>.meta.createdAt`\n * style accessors in the SELECT-result path return Date instances,\n * breaking user code that expects strings.\n */\nfunction wrapNodePgClient(\n client: NodePgClient,\n cacheMax: number,\n): PgQueryClient {\n return {\n async query(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<PgQueryResult> {\n const result = await client.query({\n name: statementNameFor(sqlText, cacheMax),\n text: sqlText,\n values: params,\n });\n return { rows: normalizeRows(result.rows) };\n },\n async queryUnnamed(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<PgQueryResult> {\n const result = await client.query(sqlText, params);\n return { rows: normalizeRows(result.rows) };\n },\n };\n}\n\n/**\n * Variant that bypasses server-side prepared statements entirely.\n * Required for pgbouncer in transaction-pool mode (named statements\n * registered on one backend connection aren't visible on the next),\n * and useful when memory-sensitive workloads can't afford to keep\n * prepared statements warm across the pool.\n *\n * Same Date→ISO normalization as `wrapNodePgClient` so the row contract\n * downstream stays identical.\n */\nfunction wrapNodePgClientUnnamed(client: NodePgClient): PgQueryClient {\n async function queryUnnamed(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<PgQueryResult> {\n const result = await client.query(sqlText, params);\n return { rows: normalizeRows(result.rows) };\n }\n return {\n query: queryUnnamed,\n queryUnnamed,\n };\n}\n\nfunction adaptPostgresJsClient(sql: PostgresJsClient): PgQueryClient {\n async function query(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<PgQueryResult> {\n // postgres-js handles its own statement preparation internally\n // (controlled by the `prepare` connection option, default true),\n // so we don't need to name statements here ourselves.\n const rows = await sql.unsafe(sqlText, params);\n return { rows };\n }\n return {\n query,\n async queryUnnamed(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<PgQueryResult> {\n // Per-call opt-out of postgres-js's internal preparation\n // (verified: `unsafe(text, params, { prepare: false })` leaves\n // pg_prepared_statements empty), so custom-plan-preferring\n // statements are re-planned against their actual parameters on\n // every call — same contract as the node-postgres unnamed path.\n const rows = await sql.unsafe(sqlText, params, { prepare: false });\n return { rows };\n },\n };\n}\n\n/**\n * Resolves a Drizzle-wrapped PostgreSQL client to a uniform `{query}` shape\n * that the fast path can call. Supports:\n *\n * - `drizzle-orm/node-postgres` (pg Pool / Client) — wrapped to use\n * server-side prepared statements with stable counter-derived names\n * keyed by the SQL text (see `statementNameFor`). When\n * `prepareStatements` is `false`, falls back to unnamed\n * `client.query(text, values)` for pgbouncer transaction-pool\n * compatibility.\n * - `drizzle-orm/neon-serverless` (@neondatabase/serverless Pool) —\n * pg-Pool-compatible, takes the same wrapper as node-postgres\n * - `drizzle-orm/postgres-js` (postgres-js tagged-template Sql) — adapted\n * via `.unsafe(sql, params)`. Safe because Drizzle installs transparent\n * parsers on the same client instance at `drizzle()` time, so direct\n * calls and Drizzle-routed calls produce identical row shapes.\n * - `drizzle-orm/pglite` (PGlite, Postgres-in-WASM) — routed to the unnamed\n * wrapper unconditionally. PGlite's `.query` has no named-statement config\n * form (and server-side prepared statements buy nothing for an in-process\n * engine), so `prepareStatements` is ignored for it.\n *\n * Returns `undefined` for `drizzle-orm/neon-http` and any other driver we\n * don't recognize; callers fall back to `db.execute(sql)`, which goes\n * through the Drizzle session and is always correct (just without the\n * server-side prepared-statement perf win).\n */\nfunction resolvePgClient(\n db: AnyPgDatabase,\n prepareStatements: boolean,\n cacheMax: number,\n useTransactionClient: boolean,\n): PgQueryClient | undefined {\n // Order matters: neon-http and postgres-js are both callable + have\n // `.unsafe`, but neon-http's `.unsafe` is a fragment builder (not a\n // query executor) and its `.query` doesn't accept the {name, text,\n // values} config form. Skip the fast path entirely for neon-http and\n // let Drizzle's session route the call.\n if (isNeonHttpClient(db)) {\n return undefined;\n }\n const carrier = db as PgClientCarrier;\n // Top-level Drizzle databases expose `$client`. Transaction objects do not;\n // they retain the exact pinned pool/client transaction on `session.client`.\n // Reading that structural internal is what keeps trusted import on the same\n // connection that will COMMIT/ROLLBACK, instead of accidentally using the\n // outer pool while a transaction is open.\n const client =\n carrier.$client ??\n (useTransactionClient ? transactionSession(carrier)?.client : undefined);\n // Must precede `isPgNativeClient`: PGlite matches it too (object with\n // `.query`), but only the unnamed wrapper is safe for it (see\n // `isPgliteClient`).\n if (\n isPgliteClient(client) ||\n (useTransactionClient && hasPgliteSession(carrier))\n ) {\n if (!isPgNativeClient(client)) return undefined;\n return wrapNodePgClientUnnamed(client);\n }\n if (isPgNativeClient(client)) {\n return prepareStatements ?\n wrapNodePgClient(client, cacheMax)\n : wrapNodePgClientUnnamed(client);\n }\n if (isPostgresJsClient(client)) {\n // postgres-js handles its own preparation internally (controlled\n // by the driver's own `prepare` connection option) — the\n // `prepareStatements` flag here only affects the node-postgres\n // path.\n return adaptPostgresJsClient(client);\n }\n return undefined;\n}\n\n/**\n * Normalizes the result shape of `db.execute(sql)` across drivers.\n *\n * - `drizzle-orm/node-postgres` / `drizzle-orm/neon-serverless` return a\n * pg-style `{ rows, rowCount, ... }` object.\n * - `drizzle-orm/postgres-js` returns the raw postgres-js result, which is\n * a plain array of rows (with extra non-enumerable properties like\n * `count` / `command`).\n *\n * The backend contract is \"a row array.\" Normalize here so every caller\n * downstream can assume the same shape.\n */\nasync function executeDrizzleQuery<TRow>(\n db: AnyPgDatabase,\n query: DrizzleSql,\n): Promise<readonly TRow[]> {\n const result = await db.execute(query);\n if (Array.isArray(result)) {\n return result as readonly TRow[];\n }\n return (result as Readonly<{ rows: readonly TRow[] }>).rows;\n}\n\nfunction createPgPreparedStatement(\n pgClient: PgQueryClient,\n sqlText: string,\n): PreparedSqlStatement {\n return {\n async execute<TRow>(params: readonly unknown[]): Promise<readonly TRow[]> {\n const result = await pgClient.query(sqlText, params);\n return result.rows as readonly TRow[];\n },\n };\n}\n\n/**\n * Tuning options for the PostgreSQL execution fast path.\n *\n * Defaults are correct for `drizzle-orm/node-postgres` against a\n * standalone PostgreSQL or session-pooled deployment. Override when:\n *\n * - **Pooling through pgbouncer in transaction-pool mode.** Set\n * `prepareStatements: false`. Named statements registered on one\n * pooled backend connection aren't visible to the next, so the\n * server-side prepared-statement cache must be off.\n * - **High-cardinality SQL text.** If the application emits many\n * distinct compiled SQL strings (variable-length IN-list expansions,\n * custom `backend.execute()` calls, generated aliases), tune\n * `preparedStatementCacheMax` down to bound per-session memory more\n * aggressively, or up if memory is plentiful and you want fewer\n * re-PREPAREs.\n */\nexport type PostgresExecutionAdapterOptions = Readonly<{\n /**\n * When `true` (default), node-postgres / neon-serverless calls go\n * through `client.query({name, text, values})` so PostgreSQL caches\n * the parsed/planned statement per session. Set to `false` to issue\n * unnamed `client.query(text, values)` calls — required for\n * pgbouncer transaction-pool mode.\n */\n prepareStatements?: boolean;\n /**\n * Maximum number of distinct SQL strings tracked for prepared-\n * statement naming. Defaults to `DEFAULT_POSTGRES_STATEMENT_CACHE_MAX`\n * (256). Ignored when `prepareStatements` is `false`.\n */\n preparedStatementCacheMax?: number;\n /**\n * @internal Resolve Drizzle's pinned transaction client. Trusted import uses\n * this on its private adapter; ordinary transaction backends deliberately do\n * not expose a new raw-execution surface that would change routing behavior.\n */\n useTransactionClient?: boolean;\n}>;\n\nexport function createPostgresExecutionAdapter(\n db: AnyPgDatabase,\n options: PostgresExecutionAdapterOptions = {},\n): PostgresExecutionAdapter {\n const prepareStatements = options.prepareStatements ?? true;\n const cacheMax =\n options.preparedStatementCacheMax ?? DEFAULT_POSTGRES_STATEMENT_CACHE_MAX;\n const pgClient = resolvePgClient(\n db,\n prepareStatements,\n cacheMax,\n options.useTransactionClient ?? false,\n );\n\n function compile(query: ExecutableSql): CompiledSqlQuery {\n return compileQueryWithDialect(db, query, \"PostgreSQL\");\n }\n\n if (pgClient === undefined) {\n return {\n compile,\n async execute<TRow>(query: ExecutableSql): Promise<readonly TRow[]> {\n return executeDrizzleQuery<TRow>(\n db,\n isSqlFragment(query) ? toDrizzleSql(query, \"postgres\") : query,\n );\n },\n };\n }\n\n const pgQueryClient = pgClient;\n\n async function executeCompiled<TRow>(\n compiledQuery: CompiledSqlQuery,\n ): Promise<readonly TRow[]> {\n const result = await pgQueryClient.query(\n compiledQuery.sql,\n compiledQuery.params,\n );\n return result.rows as readonly TRow[];\n }\n\n return {\n compile,\n async execute<TRow>(query: ExecutableSql): Promise<readonly TRow[]> {\n // Fast path: compile via Drizzle's dialect, then execute through\n // the wrapped client directly. Bypasses Drizzle's session\n // overhead (logging spans, plan-cache bookkeeping for typed\n // queries we don't use), and on node-postgres this also enables\n // the server-side prepared-statement path because the wrapped\n // client assigns each unique SQL a stable statement name.\n const compiled = compile(query);\n if (isSqlFragment(query) && shouldForceCustomPlan(query)) {\n const result = await pgQueryClient.queryUnnamed(\n compiled.sql,\n compiled.params,\n );\n return result.rows as readonly TRow[];\n }\n return executeCompiled<TRow>(compiled);\n },\n executeCompiled,\n prepare(sqlText: string): PreparedSqlStatement {\n return createPgPreparedStatement(pgQueryClient, sqlText);\n },\n };\n}\n","/**\n * Per-connection statement serialization for transaction-scoped backends.\n *\n * A pooled backend hands every statement its own connection, so concurrent\n * work is genuinely concurrent. A transaction is the opposite: every\n * statement shares one pinned connection, and the PostgreSQL wire protocol\n * has no request pipelining a driver could use to keep two in flight. Drivers\n * paper over this with an internal queue — node-postgres queues on\n * `Client._queryQueue` — but that queue is deprecated as of `pg@8.22` and is\n * removed in `pg@9`:\n *\n * > Calling client.query() when the client is already executing a query is\n * > deprecated and will be removed in pg@9.0. Use async/await or an external\n * > async flow control mechanism instead.\n *\n * TypeGraph overlaps statements on a pinned connection by construction: the\n * node write pipeline issues embedding and fulltext sync concurrently, and\n * `store.transaction()` invites callers to `Promise.all` their writes. This\n * queue is the \"external async flow control mechanism\" the deprecation asks\n * for — it keeps the concurrency at the API surface while presenting exactly\n * one statement at a time to the connection.\n *\n * Wrapping is deliberately confined to transaction-scoped adapters. On a pool\n * the queue would serialize independent connections and destroy throughput.\n *\n * Edge-safe: no `node:*` imports (loaded on Workers via neon-serverless).\n */\nimport { TransactionClosedError } from \"../../../errors\";\nimport {\n type CompiledSqlQuery,\n type ExecutableSql,\n type PreparedSqlStatement,\n type SqlExecutionAdapter,\n} from \"./types\";\n\n/**\n * A {@link SqlExecutionAdapter} that runs one statement at a time and can be\n * shut so that late statements never reach the connection.\n */\nexport type SerialExecutionAdapter = SqlExecutionAdapter &\n Readonly<{\n runExclusive: NonNullable<SqlExecutionAdapter[\"runExclusive\"]>;\n /**\n * Waits for the statement currently on the wire, then refuses every\n * later one with a {@link TransactionClosedError}.\n *\n * Callers invoke this at the transaction boundary, before the driver\n * emits `COMMIT` / `ROLLBACK` on the same connection. The driver's control\n * statement does not travel through this queue, so without the drain it\n * would overlap a live statement; without the close, a statement the\n * callback left running could land after the pool reclaimed the\n * connection — inside an unrelated transaction.\n *\n * Idempotent.\n */\n drainAndClose: () => Promise<void>;\n }>;\n\ntype StatementQueue = Readonly<{\n /** Runs tasks one at a time, in the order they were submitted. */\n enqueue: <T>(task: () => Promise<T>) => Promise<T>;\n drainAndClose: () => Promise<void>;\n}>;\n\n/**\n * Swallows a statement's outcome so the queue's tail always fulfills. The\n * caller owns the result promise; the tail only tracks completion, and an\n * untouched rejection here would surface as an unhandled rejection.\n */\nfunction ignoreOutcome(): void {\n // Intentionally empty: see above.\n}\n\nfunction createStatementQueue(): StatementQueue {\n // Always fulfilled: a failed statement must not strand its successors, and\n // an untouched rejection here would surface as an unhandled rejection.\n let tail: Promise<void> = Promise.resolve();\n let closed = false;\n\n return {\n enqueue<T>(task: () => Promise<T>): Promise<T> {\n if (closed) return Promise.reject(new TransactionClosedError());\n // Chained synchronously, so queue order is submission order.\n const result = tail.then(() => task());\n tail = result.then(ignoreOutcome, ignoreOutcome);\n return result;\n },\n\n async drainAndClose(): Promise<void> {\n // Close first: a statement whose continuation enqueues a successor must\n // find the queue already shut, or it would slip in behind the drain.\n closed = true;\n await tail;\n },\n };\n}\n\n/**\n * Wraps `adapter` so at most one statement is in flight on its connection.\n *\n * Only the I/O members are queued. `compile` is pure — it renders a Drizzle\n * `SQL` to text and params without touching the connection — so it stays\n * synchronous and unqueued.\n *\n * The queue is a leaf: nothing it runs re-enters it, so a queued statement\n * can never wait on a statement queued behind it.\n */\nexport function createSerialExecutionAdapter(\n adapter: SqlExecutionAdapter,\n): SerialExecutionAdapter {\n const { enqueue, drainAndClose } = createStatementQueue();\n const { executeCompiled, prepare } = adapter;\n\n return {\n drainAndClose,\n\n compile(query: ExecutableSql): CompiledSqlQuery {\n return adapter.compile(query);\n },\n\n execute<TRow>(query: ExecutableSql): Promise<readonly TRow[]> {\n return enqueue(() => adapter.execute<TRow>(query));\n },\n\n runExclusive<T>(\n critical: (connection: SqlExecutionAdapter) => Promise<T>,\n ): Promise<T> {\n // One queue slot for the whole group. `critical` receives the UNQUEUED\n // adapter: re-entering the queue from inside the slot it already holds\n // would deadlock, and it needs no serializing anyway — nothing else can\n // reach the connection until the slot is released.\n return enqueue(() => critical(adapter));\n },\n\n ...(executeCompiled === undefined ?\n {}\n : {\n executeCompiled<TRow>(\n compiledQuery: CompiledSqlQuery,\n ): Promise<readonly TRow[]> {\n return enqueue(() => executeCompiled<TRow>(compiledQuery));\n },\n }),\n\n ...(prepare === undefined ?\n {}\n : {\n prepare(sqlText: string): PreparedSqlStatement {\n const statement = prepare(sqlText);\n return {\n execute<TRow>(\n params: readonly unknown[],\n ): Promise<readonly TRow[]> {\n return enqueue(() => statement.execute<TRow>(params));\n },\n };\n },\n }),\n };\n}\n","/**\n * PostgreSQL backend adapter for TypeGraph.\n *\n * Works with any Drizzle PostgreSQL database instance. Tested against:\n * - `drizzle-orm/node-postgres` (pg Pool / Client)\n * - `drizzle-orm/postgres-js` (postgres-js tagged-template client)\n * - `drizzle-orm/neon-serverless` (@neondatabase/serverless Pool / Client)\n * - `drizzle-orm/neon-http` (@neondatabase/serverless `neon(url)`) —\n * transactions are auto-disabled because HTTP can't hold a session;\n * use `drizzle-orm/neon-serverless` if you need transactional writes.\n *\n * - `drizzle-orm/pglite` (PGlite, Postgres-in-WASM) — the execution\n * fast path detects PGlite and routes it correctly (its `.query` has no\n * named-statement form). For a batteries-included in-process setup, see\n * `createLocalPgliteBackend` in `@nicia-ai/typegraph/adapters/drizzle/postgres/pglite`.\n *\n * Other pg-protocol Drizzle adapters (Vercel Postgres, Supabase via pg)\n * work unchanged because they all expose a compatible `db.execute()` /\n * `db.transaction()` surface.\n *\n * @example\n * ```typescript\n * import { drizzle } from \"drizzle-orm/node-postgres\";\n * import { Pool } from \"pg\";\n * import { createPostgresBackend, tables } from \"@nicia-ai/typegraph/adapters/drizzle/postgres\";\n *\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n * const db = drizzle(pool);\n * const backend = createPostgresBackend(db, { tables });\n * ```\n */\nimport {\n and,\n eq,\n getTableName,\n inArray,\n isNull,\n type SQL,\n sql,\n} from \"drizzle-orm\";\nimport { PgTransaction } from \"drizzle-orm/pg-core\";\n\nimport { CompilerInvariantError, ConfigurationError } from \"../../errors\";\nimport type { ResolvedSqlTableNames } from \"../../query/compiler/schema\";\nimport {\n buildFulltextCapabilities,\n type FulltextStrategy,\n tsvectorStrategy,\n} from \"../../query/dialect/fulltext-strategy\";\nimport {\n assertPgvectorEfSearch,\n pgvectorStrategy,\n} from \"../../query/dialect/vector/pgvector-strategy\";\nimport {\n assertVectorSearchLimit,\n buildVectorCapabilities,\n type VectorSlot,\n type VectorStrategy,\n} from \"../../query/dialect/vector-strategy\";\nimport {\n isSqlFragment,\n sql as portableSql,\n type SqlFragment,\n} from \"../../query/sql-fragment\";\nimport {\n annIndexScanTypes,\n type CompiledRowsSql,\n} from \"../../query/sql-intent\";\nimport { chunk as chunkArray } from \"../../utils/array\";\nimport { requireDefined } from \"../../utils/presence\";\nimport {\n isInsufficientResourcesError,\n isMissingTableError,\n} from \"../../utils/sql-errors\";\nimport { buildLiveNodeCandidates } from \"../live-node-candidates\";\nimport {\n coerceNumericScore,\n createEdgeRowMapper,\n createNodeRowMapper,\n createSchemaVersionRowMapper,\n createUniqueRowMapper,\n nowIso,\n POSTGRES_ROW_MAPPER_CONFIG,\n} from \"../row-mappers\";\nimport {\n type AdapterBackend,\n type BackendCapabilities,\n type ClaimIndexMaterializationParams,\n type CommitSchemaVersionParams,\n type ContributionMaterializationIdentity,\n type ContributionMaterializationRow,\n createBackendOverlay,\n type CreateVectorIndexParams,\n type DeleteEmbeddingParams,\n type DeleteFulltextBatchParams,\n type DeleteFulltextParams,\n type DropVectorIndexParams,\n type FulltextSearchParams,\n type FulltextSearchResult,\n type HybridSearchParams,\n type HybridSearchRow,\n type IndexMaterializationRow,\n INTERNAL_TEMPORARY_WRITES,\n type InternalTransactionOptions,\n type KindRemovalRow,\n normalizeGraphAnalyticsCapabilities,\n POSTGRES_CAPABILITIES,\n POSTGRES_MAX_BIND_PARAMETERS,\n type RecordContributionMaterializationParams,\n type RecordIndexMaterializationParams,\n type RecordKindRemovalParams,\n type ReleaseIndexMaterializationClaimParams,\n type SchemaVersionRow,\n type SetActiveVersionParams,\n type TransactionBackend,\n type TrustedImportSession,\n type UpsertEmbeddingBatchParams,\n type UpsertEmbeddingParams,\n type UpsertFulltextBatchParams,\n type UpsertFulltextParams,\n type VectorSearchParams,\n type VectorSearchResult,\n} from \"../types\";\nimport {\n buildContributionInsertValues,\n buildContributionOnConflictSet,\n type ContributionMaterializer,\n createContributionMaterializer,\n gateFulltext,\n gateFulltextMethods,\n mapContributionMaterializationRow,\n POSTGRES_CONTRIBUTION_MAT_TIMESTAMPS,\n} from \"./contribution-materializations\";\nimport { generatePgCreateTableSQL, generatePostgresDDL } from \"./ddl\";\nimport {\n type AnyPgDatabase,\n type AnyPgTransaction,\n createPostgresExecutionAdapter,\n isNeonHttpClient,\n type PostgresExecutionAdapter,\n type PostgresExecutionAdapterOptions,\n} from \"./execution/postgres-execution\";\nimport { createSerialExecutionAdapter } from \"./execution/statement-queue\";\nimport { type ExecutableSql, toDrizzleSql } from \"./execution/types\";\nimport {\n buildMaterializationInsertValues,\n buildMaterializationOnConflictSet,\n mapMaterializationRow,\n POSTGRES_INDEX_MAT_TIMESTAMPS,\n} from \"./index-materializations\";\nimport {\n buildKindRemovalInsertValues,\n buildKindRemovalOnConflictSet,\n mapKindRemovalRow,\n POSTGRES_KIND_REMOVAL_TIMESTAMPS,\n} from \"./kind-removals\";\nimport {\n assertAdoptedDialect,\n type CommonOperationBackend,\n createCommonOperationBackend,\n type InternalOperationBackend,\n} from \"./operation-backend-core\";\nimport { mapHybridSearchRow } from \"./operations/hybrid\";\nimport {\n createCachedTableExistence,\n createPostgresOperationStrategy,\n} from \"./operations/strategy\";\nimport {\n type PostgresTables,\n tables as defaultTables,\n} from \"./schema/postgres\";\nimport {\n analyzeImportedTables,\n assertTrustedImportDatabaseEmpty,\n createPostgresTrustedImportSession,\n lockPostgresTrustedImportTables,\n restoreSecondaryIndexes,\n suspendPostgresSecondaryIndexes,\n} from \"./trusted-import\";\nimport {\n EMBEDDING_UPSERT_PARAM_COUNT,\n mapVectorWriteError,\n vectorSlotFromCreateIndexParams,\n vectorSlotFromDropIndexParams,\n vectorSlotFromParams,\n} from \"./vector-runtime\";\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * Options for creating a PostgreSQL backend.\n */\nexport type PostgresBackendOptions = Readonly<{\n /**\n * Custom table definitions. Use createPostgresTables() to customize table names.\n * Defaults to standard TypeGraph table names.\n */\n tables?: PostgresTables;\n /**\n * Fulltext strategy override. Defaults to `tsvectorStrategy`\n * (Postgres built-in `tsvector` + GIN). Pass a custom strategy here to\n * swap the entire fulltext stack — DDL, MATCH condition, rank\n * expression, and snippet generation — for alternate Postgres\n * backends like ParadeDB (`pg_search`), pg_trgm similarity, or\n * pgroonga without forking TypeGraph.\n */\n fulltext?: FulltextStrategy;\n /**\n * Vector strategy override. Defaults to `pgvectorStrategy` (pgvector's\n * `vector(N)` columns + HNSW/IVFFlat). The strategy owns per-`(kind,\n * field)` typed storage — DDL, upsert, delete, similarity search, and\n * ANN index lifecycle — and advertises `strategy.capabilities` as\n * `capabilities.vector`. Pass a custom strategy to swap the entire\n * vector stack for an alternate Postgres extension without forking\n * TypeGraph.\n *\n * Pass `false` to disable vector support entirely. The backend then\n * advertises no `capabilities.vector` and omits the embedding/search\n * methods, mirroring a SQLite connection without sqlite-vec. Required\n * for an in-process Postgres (e.g. PGlite) built without the pgvector\n * extension: the default `pgvectorStrategy` assumes `vector(N)` exists,\n * so any embedding write or `CREATE EXTENSION vector` would otherwise\n * hard-fail at runtime.\n */\n vector?: VectorStrategy | false;\n /**\n * Override specific backend capabilities. Useful when the underlying\n * driver doesn't support a feature TypeGraph would otherwise assume —\n * for example, an HTTP-only Postgres driver that can't hold a session\n * across statements would need `{ transactions: false }` so\n * TypeGraph falls through to non-transactional execution paths.\n *\n * `drizzle-orm/neon-http` is auto-detected and has `transactions`\n * disabled without an explicit override; this option exists for\n * other HTTP-style drivers and for tests that need to simulate a\n * capability gap.\n */\n capabilities?: Partial<BackendCapabilities>;\n /**\n * Use server-side prepared statements (named statements cached per\n * pg connection) on the node-postgres / neon-serverless fast path.\n * Defaults to `true`. Set to `false` when pooling through pgbouncer\n * in transaction-pool mode — pgbouncer routes successive statements\n * over different backend connections, and a `name` registered on one\n * is invisible on the next.\n *\n * No effect on `drizzle-orm/postgres-js` (handles preparation\n * internally) or `drizzle-orm/neon-http` (no fast path).\n */\n prepareStatements?: boolean;\n /**\n * Cap on the number of distinct SQL strings tracked for\n * prepared-statement naming. Defaults to 256. The cache is LRU-\n * bounded so high-cardinality SQL text (variable-length IN-lists,\n * generated aliases, `backend.execute()` calls with one-off SQL)\n * doesn't grow unbounded in either the Node process or in\n * PostgreSQL's per-session prepared-statement memory. Worst-case\n * server-side footprint is roughly `cap × pool size` statements\n * across all pooled connections. Ignored when\n * `prepareStatements` is `false`.\n */\n preparedStatementCacheMax?: number;\n}>;\n\nconst NODE_INSERT_PARAM_COUNT = 9;\nconst EDGE_INSERT_PARAM_COUNT = 12;\nconst POSTGRES_NODE_INSERT_BATCH_SIZE = Math.max(\n 1,\n Math.floor(POSTGRES_MAX_BIND_PARAMETERS / NODE_INSERT_PARAM_COUNT),\n);\nconst POSTGRES_EDGE_INSERT_BATCH_SIZE = Math.max(\n 1,\n Math.floor(POSTGRES_MAX_BIND_PARAMETERS / EDGE_INSERT_PARAM_COUNT),\n);\nconst POSTGRES_GET_NODES_ID_CHUNK_SIZE = Math.max(\n 1,\n POSTGRES_MAX_BIND_PARAMETERS - 2,\n);\nconst POSTGRES_GET_EDGES_ID_CHUNK_SIZE = Math.max(\n 1,\n POSTGRES_MAX_BIND_PARAMETERS - 1,\n);\nconst FULLTEXT_UPSERT_PARAM_COUNT = 6;\nconst FULLTEXT_DELETE_FIXED_PARAM_COUNT = 2;\nconst POSTGRES_FULLTEXT_UPSERT_BATCH_SIZE = Math.max(\n 1,\n Math.floor(POSTGRES_MAX_BIND_PARAMETERS / FULLTEXT_UPSERT_PARAM_COUNT),\n);\nconst POSTGRES_FULLTEXT_DELETE_CHUNK_SIZE = Math.max(\n 1,\n POSTGRES_MAX_BIND_PARAMETERS - FULLTEXT_DELETE_FIXED_PARAM_COUNT,\n);\nconst CHECK_UNIQUE_BATCH_FIXED_PARAM_COUNT = 3;\nconst POSTGRES_CHECK_UNIQUE_BATCH_CHUNK_SIZE = Math.max(\n 1,\n POSTGRES_MAX_BIND_PARAMETERS - CHECK_UNIQUE_BATCH_FIXED_PARAM_COUNT,\n);\nconst UNIQUE_INSERT_PARAM_COUNT = 6;\nconst POSTGRES_UNIQUE_INSERT_BATCH_SIZE = Math.max(\n 1,\n Math.floor(POSTGRES_MAX_BIND_PARAMETERS / UNIQUE_INSERT_PARAM_COUNT),\n);\n\n// ============================================================\n// Utilities\n// ============================================================\n\nconst toNodeRow = createNodeRowMapper(POSTGRES_ROW_MAPPER_CONFIG);\nconst toEdgeRow = createEdgeRowMapper(POSTGRES_ROW_MAPPER_CONFIG);\nconst toUniqueRow = createUniqueRowMapper(POSTGRES_ROW_MAPPER_CONFIG);\nconst toSchemaVersionRow = createSchemaVersionRowMapper(\n POSTGRES_ROW_MAPPER_CONFIG,\n);\n\nfunction buildPostgresCapabilities(\n fulltextStrategy: FulltextStrategy,\n vectorStrategy: VectorStrategy | undefined,\n): BackendCapabilities {\n return {\n ...POSTGRES_CAPABILITIES,\n ...(vectorStrategy === undefined ?\n {}\n : { vector: buildVectorCapabilities(vectorStrategy) }),\n fulltext: buildFulltextCapabilities(fulltextStrategy),\n };\n}\n\n// ============================================================\n// Backend Factory\n// ============================================================\n\n/**\n * Creates a TypeGraph backend for PostgreSQL databases.\n *\n * Works with any Drizzle PostgreSQL instance regardless of the underlying driver.\n *\n * @param db - A Drizzle PostgreSQL database instance\n * @param options - Backend configuration\n * @returns A GraphBackend implementation\n */\nexport function createPostgresBackend(\n db: AnyPgDatabase,\n options: PostgresBackendOptions = {},\n): AdapterBackend<AnyPgTransaction> {\n const tables = options.tables ?? defaultTables;\n const fulltextStrategy = options.fulltext ?? tsvectorStrategy;\n // pgvector is compiled into a standalone Postgres server, so it is wired\n // unconditionally by default (overridable for alternate Postgres vector\n // stacks). `vector: false` disables it — required for an in-process\n // Postgres (PGlite) built without the pgvector extension, where the\n // default strategy's `vector(N)` DDL would hard-fail.\n const vectorStrategy =\n options.vector === false ? undefined : (options.vector ?? pgvectorStrategy);\n // One probe per backend instance, shared with every transaction-scoped\n // backend so the pgvector version check runs — and its pre-0.8 warning\n // fires — at most once per backend, not once per `store.transaction()`.\n const iterativeScanProbe = createIterativeScanProbe();\n const baseCapabilities = buildPostgresCapabilities(\n fulltextStrategy,\n vectorStrategy,\n );\n // HTTP-only drivers (notably `drizzle-orm/neon-http`) can't hold a\n // session across statements, so multi-statement transactions are\n // unavailable regardless of what we declare. Auto-detect and downgrade\n // the capability so callers get correct fallback behavior without\n // having to remember to override it themselves.\n const httpOnlyOverrides =\n isNeonHttpClient(db) ?\n {\n transactions: false,\n graphAnalytics: {\n ...(baseCapabilities.graphAnalytics ?? { mathFunctions: true }),\n supported: false,\n },\n }\n : {};\n const capabilities = normalizeGraphAnalyticsCapabilities({\n ...baseCapabilities,\n ...httpOnlyOverrides,\n ...options.capabilities,\n });\n const adapterOptions: PostgresExecutionAdapterOptions = {\n ...(options.prepareStatements === undefined ?\n {}\n : { prepareStatements: options.prepareStatements }),\n ...(options.preparedStatementCacheMax === undefined ?\n {}\n : { preparedStatementCacheMax: options.preparedStatementCacheMax }),\n };\n const executionAdapter = createPostgresExecutionAdapter(db, adapterOptions);\n const tableNames: ResolvedSqlTableNames = {\n nodes: getTableName(tables.nodes),\n edges: getTableName(tables.edges),\n recordedNodes: getTableName(tables.recordedNodes),\n recordedEdges: getTableName(tables.recordedEdges),\n recordedClock: getTableName(tables.recordedClock),\n revisionOrigins: getTableName(tables.revisionOrigins),\n fulltext: tables.fulltextTableName,\n uniques: getTableName(tables.uniques),\n };\n // Pre-quote identifiers so refreshStatistics() doesn't rebuild the\n // ANALYZE statements on every call. The recorded relations are ANALYZEd\n // separately under an existence guard (see refreshStatistics): a schema\n // created before recorded-time history landed (bring-your-own-pool, no DDL\n // re-run) has no recorded tables, and Postgres fails the whole ANALYZE if any\n // named relation is missing. Per-field vector tables are created lazily and\n // live outside this base set, so they are not ANALYZEd here.\n //\n // ONE statement per table with SKIP_LOCKED, never `ANALYZE a, b, c`:\n // ANALYZE takes a ShareUpdateExclusive lock, the same class CREATE INDEX\n // CONCURRENTLY holds for its whole build — and a CIC in another session\n // waits on every regular transaction's snapshot, ANALYZE's included. An\n // ANALYZE that queues on a CIC's table lock while that CIC waits on the\n // ANALYZE's snapshot is a two-node deadlock (observed when two\n // materializeIndexes callers race). SKIP_LOCKED makes ANALYZE skip a\n // locked table instead of queuing, so it can never join a wait cycle;\n // a skipped table is covered by the next refresh or autovacuum.\n const coreAnalyzeStatements = [\n tableNames.nodes,\n tableNames.edges,\n getTableName(tables.uniques),\n tableNames.fulltext,\n ].map((name) =>\n toDrizzleSql(\n portableSql`ANALYZE (SKIP_LOCKED) ${portableSql.identifier(name)}`,\n \"postgres\",\n ),\n );\n const recordedAnalyzeTables = [\n tableNames.recordedNodes,\n tableNames.recordedEdges,\n tableNames.recordedClock,\n ] as const;\n const operationStrategy = createPostgresOperationStrategy(\n tables,\n fulltextStrategy,\n );\n\n // Whether `tableName` currently exists, via the same catalog probe `clear()`\n // uses — so refreshStatistics() never ANALYZEs a recorded relation that a\n // bring-your-own-pool schema has not yet created. The Postgres probe is\n // search_path-aware, so positive results are deliberately not cached by bare\n // table name.\n const recordedTableExists = createCachedTableExistence(\n async (tableName) => {\n const rows = await executionAdapter.execute<Record<string, unknown>>(\n operationStrategy.buildTableExists(tableName),\n );\n return rows[0];\n },\n { cacheExisting: false },\n );\n\n // Durable fulltext + vector materialization (#135): the dialect-specific\n // marker-table primitives. Orchestration (materialize / assert /\n // per-instance cache) lives once in `createContributionMaterializer`,\n // shared by the outer backend and every transaction-scoped backend so a\n // slot's marker is resolved at most once per process. Built before\n // `operations` so the operation backend's vector methods can assert/\n // ensure through it instead of issuing DDL on the hot path.\n const matTable = tables.contributionMaterializations;\n\n async function ensureContributionMaterializationsTableImpl(): Promise<void> {\n await db.execute(sql.raw(generatePgCreateTableSQL(matTable)));\n }\n\n async function getContributionMaterializationRow(\n identity: ContributionMaterializationIdentity,\n ): Promise<ContributionMaterializationRow | undefined> {\n const rows = await db\n .select()\n .from(matTable)\n .where(\n and(\n eq(matTable.graphId, identity.graphId),\n eq(matTable.logicalName, identity.logicalName),\n eq(matTable.owner, identity.owner),\n eq(matTable.tableName, identity.tableName),\n ),\n );\n const row = rows[0];\n if (row === undefined) return undefined;\n return mapContributionMaterializationRow(\n row,\n POSTGRES_CONTRIBUTION_MAT_TIMESTAMPS.decode,\n );\n }\n\n async function getContributionMaterializationRows(\n graphId: string,\n ): Promise<readonly ContributionMaterializationRow[]> {\n const rows = await db\n .select()\n .from(matTable)\n .where(eq(matTable.graphId, graphId));\n return rows.map((row) =>\n mapContributionMaterializationRow(\n row,\n POSTGRES_CONTRIBUTION_MAT_TIMESTAMPS.decode,\n ),\n );\n }\n\n async function recordContributionMaterializationRow(\n params: RecordContributionMaterializationParams,\n ): Promise<void> {\n await db\n .insert(matTable)\n .values(\n buildContributionInsertValues(\n params,\n POSTGRES_CONTRIBUTION_MAT_TIMESTAMPS.encode,\n ),\n )\n .onConflictDoUpdate({\n target: [\n matTable.graphId,\n matTable.logicalName,\n matTable.owner,\n matTable.tableName,\n ],\n set: buildContributionOnConflictSet(\n matTable.materializedAt,\n params.materializedAt,\n ),\n });\n }\n\n async function deleteContributionMaterializationRow(\n identity: ContributionMaterializationIdentity,\n ): Promise<void> {\n await db\n .delete(matTable)\n .where(\n and(\n eq(matTable.graphId, identity.graphId),\n eq(matTable.logicalName, identity.logicalName),\n eq(matTable.owner, identity.owner),\n eq(matTable.tableName, identity.tableName),\n ),\n );\n }\n\n const contributionMaterializer = createContributionMaterializer({\n dialect: \"postgres\",\n fulltextStrategy,\n fulltextTableName: tables.fulltextTableName,\n vectorStrategy,\n execDdl: async (statement) => {\n await db.execute(sql.raw(statement));\n },\n ensureMarkerTable: ensureContributionMaterializationsTableImpl,\n getMarkers: getContributionMaterializationRows,\n recordMarker: recordContributionMaterializationRow,\n deleteMarker: deleteContributionMaterializationRow,\n });\n\n const operations = createPostgresOperationBackend({\n db,\n executionAdapter,\n adapterOptions,\n operationStrategy,\n tableNames,\n capabilities,\n fulltextStrategy,\n vectorStrategy,\n contributionMaterializer,\n iterativeScanProbe,\n });\n\n /**\n * Runs `fn` inside a Postgres transaction, holding an\n * `pg_advisory_xact_lock` keyed on the graph id. The advisory lock\n * serializes all schema commits per-graph: the read-then-write CAS in\n * `commitSchemaVersion` is safe even for the initial-commit case\n * where there is no row yet to `SELECT ... FOR UPDATE`.\n *\n * Refuses on backends that don't support transactions\n * (`drizzle-orm/neon-http`). The orphan-row crash window cannot be\n * eliminated without atomicity, so silent best-effort degradation is\n * worse than a typed error.\n */\n function runSchemaWriteTransaction<T>(\n graphId: string,\n fn: (tx: CommonOperationBackend) => Promise<T>,\n ): Promise<T> {\n if (!capabilities.transactions) {\n throw new ConfigurationError(\n \"commitSchemaVersion and setActiveVersion require atomic transactions, \" +\n \"but this Postgres backend does not provide them. The drizzle-orm/neon-http \" +\n \"driver communicates over HTTP and cannot hold a session across statements; \" +\n \"use drizzle-orm/neon-serverless (websocket) for transactional writes.\",\n {\n backend: \"postgres\",\n capability: \"transactions\",\n supportsTransactions: false,\n },\n );\n }\n\n return db.transaction(async (tx) => {\n // Advisory lock: hashtext($graphId) is collision-tolerant for the\n // size of an active graph set; collisions just serialize unrelated\n // graphs which is harmless. Held until the transaction commits.\n await tx.execute(sql`SELECT pg_advisory_xact_lock(hashtext(${graphId}))`);\n // Advisory lock is held here, so the schema-write-capable\n // InternalOperationBackend is used intentionally (see its type).\n const { backend: txBackend, drainAndClose } = createTransactionBackend({\n db: tx,\n adapterOptions,\n operationStrategy,\n tableNames,\n capabilities,\n fulltextStrategy,\n vectorStrategy,\n contributionMaterializer,\n iterativeScanProbe,\n });\n try {\n return await fn(txBackend);\n } finally {\n await drainAndClose();\n }\n });\n }\n\n // Shared by `transaction()` (TypeGraph opens the tx) and\n // `adoptTransaction()` (#134 — the caller already opened it): bind a\n // tx-scoped backend to the *literal* `tx` client and gate fulltext on\n // the durable marker (a cached SELECT, never DDL).\n function bindTransactionBackend(tx: AnyPgTransaction): Readonly<{\n backend: TransactionBackend;\n drainAndClose: () => Promise<void>;\n }> {\n const { backend, drainAndClose } = createTransactionBackend({\n db: tx,\n adapterOptions,\n operationStrategy,\n tableNames,\n capabilities,\n fulltextStrategy,\n vectorStrategy,\n contributionMaterializer,\n iterativeScanProbe,\n });\n return {\n backend: gateFulltext(\n backend,\n contributionMaterializer.assertInitialized,\n ),\n drainAndClose,\n };\n }\n\n const backend: AdapterBackend<AnyPgTransaction> = {\n ...operations,\n\n ...((\n capabilities.transactions &&\n executionAdapter.executeCompiled !== undefined\n ) ?\n {\n async trustedImport<T>(\n fn: (session: TrustedImportSession) => Promise<T>,\n ): Promise<T> {\n return backend.transactionWithNative(async (tx, rawSql) => {\n const trustedExecutionAdapter = createPostgresExecutionAdapter(\n rawSql,\n { ...adapterOptions, useTransactionClient: true },\n );\n const executeCompiled = trustedExecutionAdapter.executeCompiled;\n if (executeCompiled === undefined) {\n throw new ConfigurationError(\n \"Trusted import could not bind raw execution to the PostgreSQL transaction.\",\n { capability: \"trustedImport\", dialect: \"postgres\" },\n );\n }\n const trustedTx = createBackendOverlay(tx, {\n executeRaw<T>(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<readonly T[]> {\n return executeCompiled<T>({ params, sql: sqlText });\n },\n });\n await lockPostgresTrustedImportTables(trustedTx, tableNames);\n await assertTrustedImportDatabaseEmpty(trustedTx, tableNames);\n const indexDefinitions = await suspendPostgresSecondaryIndexes(\n trustedTx,\n tableNames,\n );\n const result = await fn(\n createPostgresTrustedImportSession(trustedTx, tableNames),\n );\n await restoreSecondaryIndexes(trustedTx, indexDefinitions);\n await analyzeImportedTables(trustedTx, tableNames);\n return result;\n });\n },\n }\n : {}),\n\n async bootstrapTables(): Promise<void> {\n const statements = generatePostgresDDL(tables, fulltextStrategy);\n for (const statement of statements) {\n await db.execute(sql.raw(statement));\n }\n },\n\n async ensureRevisionOriginsTable(): Promise<void> {\n await db.execute(\n sql.raw(generatePgCreateTableSQL(tables.revisionOrigins)),\n );\n },\n\n // Every fulltext-touching method asserts the durable marker instead\n // of lazily emitting DDL. Steady state performs zero ensure; an\n // uninitialized database throws `StoreNotInitializedError` loudly\n // rather than self-healing on a read/write path (#135). Shared\n // verbatim with the tx-scoped gate via `gateFulltextMethods`.\n ...gateFulltextMethods(\n operations,\n contributionMaterializer.assertInitialized,\n ),\n\n async executeDdl(ddl: string): Promise<void> {\n await db.execute(sql.raw(ddl));\n },\n\n async ensureIndexMaterializationsTable(): Promise<void> {\n await db.execute(\n sql.raw(generatePgCreateTableSQL(tables.indexMaterializations)),\n );\n // Deployments created before the build-claim columns existed get\n // them additively; fresh installs already have them from the\n // CREATE TABLE above.\n const tableName = getTableName(tables.indexMaterializations);\n await db.execute(\n sql.raw(\n `ALTER TABLE \"${tableName}\" ADD COLUMN IF NOT EXISTS \"building_since\" timestamptz;`,\n ),\n );\n await db.execute(\n sql.raw(\n `ALTER TABLE \"${tableName}\" ADD COLUMN IF NOT EXISTS \"claim_token\" text;`,\n ),\n );\n },\n\n async claimIndexMaterialization(\n params: ClaimIndexMaterializationParams,\n ): Promise<boolean> {\n const t = tables.indexMaterializations;\n // Atomic claim: insert a fresh claim row, or take over an existing\n // row only when no live claim is on it (NULL or lease-expired\n // building_since). The WHERE on the conflict update makes losing\n // racers see zero returned rows — the row's own atomicity is the\n // mutex, so this works identically through pools and across\n // processes (unlike session advisory locks, which pin a\n // connection).\n const rows = await db.execute(sql`\n INSERT INTO ${t} (\n \"index_name\", \"graph_id\", \"entity\", \"kind\", \"signature\",\n \"schema_version\", \"last_attempted_at\", \"building_since\",\n \"claim_token\"\n )\n VALUES (\n ${params.indexName}, ${params.graphId}, ${params.entity},\n ${params.kind}, ${params.signature}, ${params.schemaVersion},\n now(), now(), ${params.token}\n )\n ON CONFLICT (\"index_name\") DO UPDATE SET\n \"building_since\" = now(),\n \"claim_token\" = EXCLUDED.\"claim_token\"\n WHERE ${t}.\"building_since\" IS NULL\n OR ${t}.\"building_since\" < now() - (${params.leaseMs} * interval '1 millisecond')\n RETURNING \"index_name\"\n `);\n const result = rows;\n const returned =\n Array.isArray(result) ? result : (\n ((result as Readonly<{ rows?: readonly unknown[] }>).rows ?? [])\n );\n return returned.length > 0;\n },\n\n async releaseIndexMaterializationClaim(\n params: ReleaseIndexMaterializationClaimParams,\n ): Promise<void> {\n const t = tables.indexMaterializations;\n // Token-guarded: a lease-expired claim taken over by another\n // materializer must not be released by the original holder.\n await db.execute(sql`\n UPDATE ${t}\n SET \"building_since\" = NULL, \"claim_token\" = NULL\n WHERE \"index_name\" = ${params.indexName}\n AND \"claim_token\" = ${params.token}\n `);\n },\n\n async getIndexMaterialization(\n indexName: string,\n ): Promise<IndexMaterializationRow | undefined> {\n const t = tables.indexMaterializations;\n const rows = await db.select().from(t).where(eq(t.indexName, indexName));\n const row = rows[0];\n if (row === undefined) return undefined;\n return mapMaterializationRow(row, POSTGRES_INDEX_MAT_TIMESTAMPS.decode);\n },\n\n async getIndexMaterializations(\n statusKeys: readonly string[],\n ): Promise<readonly IndexMaterializationRow[]> {\n if (statusKeys.length === 0) return [];\n const t = tables.indexMaterializations;\n const rows = await db\n .select()\n .from(t)\n .where(inArray(t.indexName, [...statusKeys]));\n return rows.map((row) =>\n mapMaterializationRow(row, POSTGRES_INDEX_MAT_TIMESTAMPS.decode),\n );\n },\n\n async recordIndexMaterialization(\n params: RecordIndexMaterializationParams,\n ): Promise<void> {\n const t = tables.indexMaterializations;\n await db\n .insert(t)\n .values(\n buildMaterializationInsertValues(\n params,\n POSTGRES_INDEX_MAT_TIMESTAMPS.encode,\n ),\n )\n .onConflictDoUpdate({\n target: t.indexName,\n set: buildMaterializationOnConflictSet(params.materializedAt),\n });\n },\n\n async ensureContributionMaterializationsTable(): Promise<void> {\n await ensureContributionMaterializationsTableImpl();\n },\n\n async getContributionMaterialization(\n identity: ContributionMaterializationIdentity,\n ): Promise<ContributionMaterializationRow | undefined> {\n return getContributionMaterializationRow(identity);\n },\n\n async recordContributionMaterialization(\n params: RecordContributionMaterializationParams,\n ): Promise<void> {\n await recordContributionMaterializationRow(params);\n },\n\n async assertRuntimeContributionsInitialized(\n graphId: string,\n ): Promise<void> {\n await contributionMaterializer.assertInitialized(graphId);\n },\n\n async ensureKindRemovalsTable(): Promise<void> {\n await db.execute(sql.raw(generatePgCreateTableSQL(tables.kindRemovals)));\n },\n\n async getPendingKindRemovals(\n graphId: string,\n ): Promise<readonly KindRemovalRow[]> {\n const t = tables.kindRemovals;\n const rows = await db\n .select()\n .from(t)\n .where(and(eq(t.graphId, graphId), isNull(t.removedAt)));\n return rows.map((row) =>\n mapKindRemovalRow(row, POSTGRES_KIND_REMOVAL_TIMESTAMPS.decode),\n );\n },\n\n async getAllKindRemovals(\n graphId: string,\n ): Promise<readonly KindRemovalRow[]> {\n const t = tables.kindRemovals;\n const rows = await db.select().from(t).where(eq(t.graphId, graphId));\n return rows.map((row) =>\n mapKindRemovalRow(row, POSTGRES_KIND_REMOVAL_TIMESTAMPS.decode),\n );\n },\n\n async recordKindRemoval(params: RecordKindRemovalParams): Promise<void> {\n const t = tables.kindRemovals;\n await db\n .insert(t)\n .values(\n buildKindRemovalInsertValues(\n params,\n POSTGRES_KIND_REMOVAL_TIMESTAMPS.encode,\n ),\n )\n .onConflictDoUpdate({\n target: [t.graphId, t.kindName, t.entity, t.schemaVersion],\n set: buildKindRemovalOnConflictSet(t.removedAt, params.removedAt),\n });\n },\n\n async ensureReconciliationMarkersTable(): Promise<void> {\n await db.execute(\n sql.raw(generatePgCreateTableSQL(tables.reconciliationMarkers)),\n );\n },\n\n async ensureRuntimeContributions(graphId: string): Promise<void> {\n await contributionMaterializer.ensureRuntimeContributions(graphId);\n },\n\n /**\n * Superseded by `ensureRuntimeContributions(graphId)` (#129).\n * Retained as a thin back-compat wrapper for callers predating\n * #129; #135 routed it through the durable-marker writer.\n */\n async ensureFulltextTable(graphId: string): Promise<void> {\n await contributionMaterializer.ensureRuntimeContributions(graphId);\n },\n\n // Vector counterparts of the runtime-contribution methods. Present\n // only when a vector strategy is wired (omitted under `vector: false`,\n // mirroring the embedding/search methods), so a no-vector backend\n // doesn't advertise vector materialization it can't perform.\n ...(vectorStrategy === undefined ?\n {}\n : {\n async ensureVectorSlotContribution(\n slot: VectorSlot,\n options_?: Readonly<{ force?: boolean; onDrift?: \"throw\" | \"skip\" }>,\n ): Promise<void> {\n await contributionMaterializer.ensureVectorSlot(slot, options_);\n },\n\n async ensureVectorSlotContributions(\n slots: readonly VectorSlot[],\n options_?: Readonly<{ force?: boolean; onDrift?: \"throw\" | \"skip\" }>,\n ): Promise<void> {\n await contributionMaterializer.ensureVectorSlots(slots, options_);\n },\n\n async assertVectorSlotInitialized(slot: VectorSlot): Promise<void> {\n await contributionMaterializer.assertVectorSlot(slot);\n },\n\n async assertVectorSlotsInitialized(\n slots: readonly VectorSlot[],\n ): Promise<void> {\n await contributionMaterializer.assertVectorSlots(slots);\n },\n\n async deleteVectorSlotContribution(slot: VectorSlot): Promise<void> {\n await contributionMaterializer.dropVectorSlot(slot);\n },\n }),\n\n async getReconciliationMarker(\n graphId: string,\n ): Promise<number | undefined> {\n const t = tables.reconciliationMarkers;\n const rows = await db.select().from(t).where(eq(t.graphId, graphId));\n return rows[0]?.reconciledToVersion;\n },\n\n async setReconciliationMarker(\n graphId: string,\n version: number,\n ): Promise<void> {\n const t = tables.reconciliationMarkers;\n await db\n .insert(t)\n .values({ graphId, reconciledToVersion: version })\n .onConflictDoUpdate({\n target: t.graphId,\n set: { reconciledToVersion: version },\n });\n },\n\n async refreshStatistics(): Promise<void> {\n // Scoped to TypeGraph-managed tables only — we don't touch\n // unrelated tables in the same database. Without fresh stats\n // after a bulk load the planner can pick a reverse-index scan\n // with a filter (5ms forward traversal instead of 0.5ms) until\n // autovacuum catches up. Sequential per-table statements — see\n // coreAnalyzeStatements for why they are never combined.\n for (const statement of coreAnalyzeStatements) {\n await db.execute(statement);\n }\n // The recorded relations may be absent on a schema created before\n // recorded-time history landed (bring-your-own-pool, no DDL re-run).\n // Postgres fails an ANALYZE naming a missing relation, so ANALYZE\n // only the recorded tables that exist.\n const tablePresence = await Promise.all(\n recordedAnalyzeTables.map(async (tableName) => ({\n tableName,\n exists: await recordedTableExists(tableName),\n })),\n );\n const presentRecordedTables = tablePresence\n .filter((entry) => entry.exists)\n .map((entry) => entry.tableName);\n for (const tableName of presentRecordedTables) {\n await db.execute(\n toDrizzleSql(\n portableSql`ANALYZE (SKIP_LOCKED) ${portableSql.identifier(tableName)}`,\n \"postgres\",\n ),\n );\n }\n },\n\n async commitSchemaVersion(\n params: CommitSchemaVersionParams,\n ): Promise<SchemaVersionRow> {\n return runSchemaWriteTransaction(params.graphId, (target) =>\n target.commitSchemaVersion(params),\n );\n },\n\n async setActiveVersion(params: SetActiveVersionParams): Promise<void> {\n await runSchemaWriteTransaction(params.graphId, (target) =>\n target.setActiveVersion(params),\n );\n },\n\n async transaction<T>(\n fn: (tx: TransactionBackend) => Promise<T>,\n options?: InternalTransactionOptions,\n ): Promise<T> {\n return backend.transactionWithNative((tx) => fn(tx), options);\n },\n\n async transactionWithNative<T>(\n fn: (tx: TransactionBackend, sql: AnyPgTransaction) => Promise<T>,\n options?: InternalTransactionOptions,\n ): Promise<T> {\n // #134/#135: NO DDL or ensure here. The tx-scoped backend's\n // fulltext-touching methods assert the durable contribution\n // marker (one cached SELECT — never DDL) at point of use, exactly\n // like the non-tx wrappers. A transaction that never touches\n // fulltext never asserts; one that does runs pure DML against an\n // already-materialized table, with the \"no DDL in the business\n // transaction\" guarantee backed by the durable fact.\n const temporaryWrites =\n options?.temporaryWrites === INTERNAL_TEMPORARY_WRITES;\n if (temporaryWrites && options.accessMode !== \"read_only\") {\n throw new ConfigurationError(\n \"Temporary-write transactions must be semantically read-only.\",\n { dialect: \"postgres\" },\n );\n }\n const txConfig =\n (\n options?.isolationLevel !== undefined ||\n options?.accessMode !== undefined ||\n temporaryWrites\n ) ?\n {\n ...(options.isolationLevel === undefined ?\n {}\n : {\n isolationLevel: options.isolationLevel.replace(\"_\", \" \") as\n | \"read uncommitted\"\n | \"read committed\"\n | \"repeatable read\"\n | \"serializable\",\n }),\n ...(options.accessMode === undefined && !temporaryWrites ?\n {}\n : {\n accessMode:\n temporaryWrites ?\n (\"read write\" as const)\n : (requireDefined(options.accessMode).replace(\"_\", \" \") as\n \"read only\" | \"read write\"),\n }),\n }\n : undefined;\n\n return db.transaction(async (tx) => {\n const { backend: txBackend, drainAndClose } =\n bindTransactionBackend(tx);\n try {\n return await fn(txBackend, tx);\n } finally {\n // Drizzle emits COMMIT / ROLLBACK on this same pinned connection the\n // instant the callback settles, and those control statements do not\n // travel through the backend's statement queue. Wait for whatever is\n // on the wire, and refuse anything the callback left running — a\n // `Promise.all` that rejects orphans its siblings, whose statements\n // would otherwise overlap the ROLLBACK and then land on a connection\n // the pool had already handed to somebody else.\n await drainAndClose();\n }\n }, txConfig);\n },\n\n adoptTransaction(externalTx: AnyPgTransaction): TransactionBackend {\n // #134: cross-store atomicity is unsafe without real rollback —\n // the caller's relational write on `externalTx` *would* still\n // commit even though the graph write could not be undone. Refuse\n // loudly rather than silently degrade.\n if (!capabilities.transactions) {\n throw new ConfigurationError(\n \"Cross-store atomicity is unavailable on this Postgres backend: \" +\n \"its driver does not support transactions (drizzle-orm/neon-http, \" +\n \"Cloudflare D1). Adopting an external transaction here would let \" +\n \"the caller's relational write commit with no way to roll back \" +\n \"the graph write. Use a node-postgres or neon-serverless \" +\n \"(Pool/WebSocket) connection for cross-store transactions.\",\n {\n backend: \"postgres\",\n capability: \"transactions\",\n supportsTransactions: false,\n },\n );\n }\n assertAdoptedDialect<AnyPgTransaction>(\n externalTx,\n PgTransaction,\n \"postgres\",\n );\n // The caller owns BEGIN/COMMIT/ROLLBACK via its own\n // `db.transaction(...)`. We adopt the literal `tx` client and run\n // pure DML on it — no transaction is opened or closed here, and no\n // DDL is emitted inside the caller's business transaction.\n //\n // Statements still serialize onto the pinned connection, but the queue\n // is never closed: only the caller knows when their transaction ends,\n // so it is on them to await every graph write before committing.\n return bindTransactionBackend(externalTx).backend;\n },\n\n async close(): Promise<void> {\n // Drizzle doesn't expose a close method\n // Users manage connection lifecycle themselves\n },\n };\n\n return backend;\n}\n\n/**\n * Memoized \"does this server's pgvector support the iterative scan (>= 0.8)?\"\n * probe, plus a one-shot warning when it does not.\n *\n * Created once per {@link createPostgresBackend} and shared with every\n * transaction-scoped operation backend, so the probe query runs once and the\n * pre-0.8 warning fires once per backend instance rather than once per\n * `store.transaction()`. The answer is connection-independent\n * (`pg_extension.extversion`), so caching it across connections is sound.\n */\nexport type IterativeScanProbe = Readonly<{\n isSupported: (\n execAll: <T>(query: SQL) => Promise<readonly T[]>,\n ) => Promise<boolean>;\n}>;\n\n/**\n * Exported for unit testing the memoization / warn-once behavior in isolation;\n * production code reaches it only through {@link createPostgresBackend}.\n */\nexport function createIterativeScanProbe(): IterativeScanProbe {\n let probe: Promise<boolean> | undefined;\n let warned = false;\n\n function warnUnavailable(version: string): void {\n if (warned) return;\n warned = true;\n if (typeof console === \"undefined\" || typeof console.warn !== \"function\") {\n return;\n }\n console.warn(\n `[typegraph] pgvector ${version} has no iterative scan (added in 0.8), ` +\n \"so a filtered approximate vector search stays ef_search-bounded and \" +\n \"can return fewer rows than `limit` while more matches exist. Upgrade \" +\n \"pgvector to >= 0.8, or use an exact search (`approximate: false`) \" +\n \"where a full page matters.\",\n );\n }\n\n return {\n isSupported(execAll) {\n // Probing the GUC directly is unreliable — extension GUCs register only\n // once the extension library has loaded into the session, so a fresh\n // pooled connection reports NULL even on 0.8+. `extversion` is truth.\n probe ??= (async () => {\n try {\n const [row] = await execAll<{ v: string | null }>(\n sql`SELECT extversion AS v FROM pg_extension WHERE extname = 'vector'`,\n );\n if (typeof row?.v !== \"string\") return false;\n const [major = 0, minor = 0] = row.v\n .split(\".\")\n .map((part) => Number.parseInt(part, 10));\n const supported = major > 0 || (major === 0 && minor >= 8);\n if (!supported) warnUnavailable(row.v);\n return supported;\n } catch {\n return false;\n }\n })();\n return probe;\n },\n };\n}\n\ntype CreatePostgresOperationBackendOptions = Readonly<{\n db: AnyPgDatabase;\n executionAdapter: PostgresExecutionAdapter;\n /**\n * Adapter tuning (prepared-statement cache settings). Used to bind a\n * fresh, equivalently-configured adapter to a transaction client when\n * a per-search `efSearch` override opens its own transaction.\n */\n adapterOptions?: PostgresExecutionAdapterOptions | undefined;\n operationStrategy: ReturnType<typeof createPostgresOperationStrategy>;\n tableNames: ResolvedSqlTableNames;\n capabilities: BackendCapabilities;\n fulltextStrategy: FulltextStrategy;\n /**\n * Active vector strategy (`pgvectorStrategy` unless overridden), or\n * `undefined` when vector support is disabled (`vector: false`).\n */\n vectorStrategy: VectorStrategy | undefined;\n /**\n * Shared durable-marker materializer. The vector methods assert a\n * slot's marker (SELECT, never DDL) on the hot path and `createVectorIndex`\n * ensures it (privileged) — replacing the old in-process ensure-latch.\n * Shared across the outer backend and every transaction-scoped backend\n * so a slot's marker is resolved at most once per process.\n */\n contributionMaterializer: ContributionMaterializer;\n /**\n * Shared pgvector iterative-scan probe (memoized version check + one-shot\n * pre-0.8 warning). Owned by the top-level backend and reused by every\n * transaction backend so the warning fires once per backend instance.\n */\n iterativeScanProbe: IterativeScanProbe;\n}>;\n\ntype CreatePostgresTransactionBackendOptions = Readonly<{\n db: AnyPgDatabase;\n adapterOptions?: PostgresExecutionAdapterOptions;\n operationStrategy: ReturnType<typeof createPostgresOperationStrategy>;\n tableNames: ResolvedSqlTableNames;\n capabilities: BackendCapabilities;\n fulltextStrategy: FulltextStrategy;\n /** Active vector strategy. See {@link CreatePostgresOperationBackendOptions}. */\n vectorStrategy: VectorStrategy | undefined;\n /** Shared durable-marker materializer. See {@link CreatePostgresOperationBackendOptions}. */\n contributionMaterializer: ContributionMaterializer;\n /** Shared iterative-scan probe. See {@link CreatePostgresOperationBackendOptions}. */\n iterativeScanProbe: IterativeScanProbe;\n}>;\n\nfunction createPostgresOperationBackend(\n options: CreatePostgresOperationBackendOptions,\n): InternalOperationBackend {\n const {\n db,\n executionAdapter,\n adapterOptions,\n operationStrategy,\n tableNames,\n capabilities,\n fulltextStrategy,\n vectorStrategy,\n contributionMaterializer,\n iterativeScanProbe,\n } = options;\n\n // Route through the execution adapter so driver-specific result shapes\n // (`{rows}` for node-postgres / neon-serverless; bare array for\n // postgres-js) are normalized in one place.\n async function execAll<T>(query: ExecutableSql): Promise<readonly T[]> {\n return executionAdapter.execute<T>(query);\n }\n\n async function execGet<T>(query: ExecutableSql): Promise<T | undefined> {\n const rows = await executionAdapter.execute<T>(query);\n return rows[0];\n }\n\n async function execRun(query: ExecutableSql): Promise<void> {\n await executionAdapter.execute(query);\n }\n\n type VectorSearchRow = Readonly<{ node_id: string; score: number }>;\n\n // One warning per backend instance when `efSearch` is supplied but the\n // driver can't hold a transaction to scope `SET LOCAL` to.\n let efSearchUnsupportedWarned = false;\n function warnEfSearchUnsupported(): void {\n if (efSearchUnsupportedWarned) return;\n efSearchUnsupportedWarned = true;\n if (typeof console === \"undefined\" || typeof console.warn !== \"function\") {\n return;\n }\n console.warn(\n \"[typegraph] efSearch (hnsw.ef_search override) was ignored: this \" +\n \"Postgres backend has transactions disabled (e.g. drizzle-orm/neon-http), \" +\n \"and SET LOCAL needs a transaction to scope the override. Use a \" +\n \"transactional driver (node-postgres / neon-serverless / postgres-js) \" +\n \"to apply efSearch.\",\n );\n }\n\n /** One transaction-local GUC override applied around a vector SELECT. */\n type SearchGucOverride = Readonly<{ name: string; value: string }>;\n\n // `hnsw.iterative_scan` exists on pgvector >= 0.8. The probe + \"warn once\"\n // state lives on the top-level backend and is SHARED with every\n // transaction-scoped operation backend (see `iterativeScanProbe` in the\n // options), so a pre-0.8 server is probed and warned about once per backend\n // instance — not once per `store.transaction()`.\n function pgvectorIterativeScanSupported(): Promise<boolean> {\n return iterativeScanProbe.isSupported(execAll);\n }\n\n /**\n * The transaction-local GUC overrides for one vector search:\n *\n * - `hnsw.ef_search` when the caller supplied `efSearch` (validated\n * upstream; warned-and-skipped on transactionless drivers, where\n * `SET LOCAL` cannot be scoped).\n * - `hnsw.iterative_scan = strict_order` on HNSW slots (pgvector >= 0.8):\n * the search SQL constrains results to live candidate nodes (and\n * optionally `minScore`), and a plain HNSW scan yields only `ef_search`\n * candidates BEFORE those filters — so a filter-heavy neighborhood can\n * under-fill top-k. The iterative scan keeps yielding until `LIMIT`\n * rows pass or it hits `hnsw.max_scan_tuples` — better recall, not a\n * full-page guarantee. `strict_order` preserves the distance ordering the\n * plan relies on (`relaxed_order` may emit slightly out of order beneath\n * our LIMIT). On pgvector < 0.8 the search stays `ef_search`-bounded and\n * the backend warns once (see `warnIterativeScanUnavailable`).\n * - `ivfflat.iterative_scan = relaxed_order` on IVFFlat slots (same\n * pgvector floor): IVFFlat has no strict_order mode, so the strategy's\n * IVFFlat search SQL re-sorts the relaxed candidate set inside a\n * MATERIALIZED wrapper (see `buildSearch`) to restore exact ordering.\n */\n async function vectorSearchGucOverrides(\n params: Pick<VectorSearchParams, \"efSearch\" | \"indexType\">,\n ): Promise<readonly SearchGucOverride[]> {\n const overrides: SearchGucOverride[] = [];\n if (params.efSearch !== undefined) {\n if (capabilities.transactions) {\n overrides.push({\n name: \"hnsw.ef_search\",\n value: String(params.efSearch),\n });\n } else {\n warnEfSearchUnsupported();\n }\n }\n if (\n params.indexType === \"hnsw\" &&\n capabilities.transactions &&\n (await pgvectorIterativeScanSupported())\n ) {\n overrides.push({ name: \"hnsw.iterative_scan\", value: \"strict_order\" });\n }\n if (\n params.indexType === \"ivfflat\" &&\n capabilities.transactions &&\n (await pgvectorIterativeScanSupported())\n ) {\n overrides.push({\n name: \"ivfflat.iterative_scan\",\n value: \"relaxed_order\",\n });\n }\n return overrides;\n }\n\n /**\n * Runs the vector SELECT, applying the given GUC overrides\n * transaction-locally. `SET LOCAL` semantics (via\n * `set_config(name, value, is_local => true)`, the parameterizable form)\n * only take effect inside an explicit transaction — issued in autocommit\n * they roll off with the statement and the next pooled query (notably\n * under transaction-mode pgbouncer) sees the session default again. So\n * with overrides present we bundle `BEGIN; SET …; SELECT …; COMMIT;`\n * onto one connection. With none we take the unchanged single-statement\n * fast path and open no transaction.\n */\n /**\n * The `SET LOCAL`-scoped vector SELECT, run as one exclusive group on the\n * transaction's connection. See {@link runVectorSearch}.\n */\n async function runVectorSearchGucGroup<Row>(\n overrides: readonly SearchGucOverride[],\n query: ExecutableSql,\n ): Promise<readonly Row[]> {\n const runExclusive = executionAdapter.runExclusive;\n if (runExclusive === undefined) {\n throw new CompilerInvariantError(\n \"A transaction-scoped Postgres backend must expose runExclusive; \" +\n \"its execution adapter was not wrapped by createSerialExecutionAdapter.\",\n );\n }\n return runExclusive(async (connection) => {\n const snapshots: SearchGucOverride[] = [];\n for (const override of overrides) {\n const [setting] = await connection.execute<{ v: string }>(\n sql`SELECT current_setting(${override.name}) AS v`,\n );\n if (setting !== undefined) {\n snapshots.push({ name: override.name, value: setting.v });\n }\n await connection.execute(\n sql`SELECT set_config(${override.name}, ${override.value}, true)`,\n );\n }\n const rows = await connection.execute<Row>(query);\n // Restore only on success: a failed SELECT aborts the caller's\n // transaction, so its rollback discards the overrides anyway and a\n // restore here would just fail against the aborted tx, masking the\n // real error.\n for (const snapshot of snapshots) {\n await connection.execute(\n sql`SELECT set_config(${snapshot.name}, ${snapshot.value}, true)`,\n );\n }\n return rows;\n });\n }\n\n async function runVectorSearch<Row = VectorSearchRow>(\n overrides: readonly SearchGucOverride[],\n query: ExecutableSql,\n ): Promise<readonly Row[]> {\n if (overrides.length === 0) {\n return execAll<Row>(query);\n }\n if (db instanceof PgTransaction) {\n // Already inside the caller's transaction (low-level\n // backend.transaction / adoptTransaction). `executionAdapter` is\n // bound to this tx client, but SET LOCAL persists to the end of the\n // caller's transaction — leaking the override into their later\n // vector searches and breaking the per-search contract. Snapshot\n // the current values, apply the overrides, then restore them once\n // the SELECT has materialized so the overrides stay scoped to this\n // one search.\n //\n // The four steps are ONE critical section, not four serialized\n // statements. A transaction has a single GUC namespace, so two searches\n // that merely take turns interleave as `A snapshot → B snapshot → A set\n // → B set → A select` and `A` runs under `B`'s efSearch. `runExclusive`\n // holds the connection for the whole group; it is always present on a\n // transaction-scoped adapter (see `createTransactionBackend`).\n return runVectorSearchGucGroup(overrides, query);\n }\n return db.transaction(async (tx) => {\n // Bind an equivalently-configured adapter to the tx client so the\n // SELECT keeps the driver result-shape normalization rather than a\n // bespoke execute. A Drizzle transaction carries no `$client`, so this\n // adapter routes through Drizzle's session (no server-side prepared\n // statement) — correct either way, and the statements below are\n // sequential, so they need no serializing wrapper.\n const txAdapter = createPostgresExecutionAdapter(tx, adapterOptions);\n for (const override of overrides) {\n await txAdapter.execute(\n sql`SELECT set_config(${override.name}, ${override.value}, true)`,\n );\n }\n return txAdapter.execute<Row>(query);\n });\n }\n\n const batchConfig = {\n checkUniqueBatchChunkSize: POSTGRES_CHECK_UNIQUE_BATCH_CHUNK_SIZE,\n edgeInsertBatchSize: POSTGRES_EDGE_INSERT_BATCH_SIZE,\n // Unlike the static siblings, the embedding upsert honors a runtime\n // `maxBindParameters` override so its chunk size tracks the connection's\n // actual bind budget.\n embeddingUpsertBatchSize: Math.max(\n 1,\n Math.floor(\n (capabilities.maxBindParameters ?? POSTGRES_MAX_BIND_PARAMETERS) /\n EMBEDDING_UPSERT_PARAM_COUNT,\n ),\n ),\n getEdgesChunkSize: POSTGRES_GET_EDGES_ID_CHUNK_SIZE,\n getNodesChunkSize: POSTGRES_GET_NODES_ID_CHUNK_SIZE,\n nodeInsertBatchSize: POSTGRES_NODE_INSERT_BATCH_SIZE,\n uniqueInsertBatchSize: POSTGRES_UNIQUE_INSERT_BATCH_SIZE,\n };\n\n const commonBackend = createCommonOperationBackend({\n batchConfig,\n execution: {\n execAll,\n execGet,\n execRun,\n },\n nowIso,\n operationStrategy,\n rowMappers: {\n toEdgeRow,\n toNodeRow,\n toSchemaVersionRow,\n toUniqueRow,\n },\n tableExistenceCache: { cacheExisting: false },\n });\n\n const executeCompiled = executionAdapter.executeCompiled;\n const executeRawMethod: Pick<TransactionBackend, \"executeRaw\"> =\n executeCompiled === undefined ?\n {}\n : {\n async executeRaw<T>(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<readonly T[]> {\n return executeCompiled<T>({ params, sql: sqlText });\n },\n };\n\n // Embedding write/search methods are present only when a vector strategy\n // is wired. With `vector: false` (e.g. PGlite without pgvector) they are\n // omitted, so `capabilities.vector` is absent and the store never routes\n // embedding work here — mirroring a SQLite connection without sqlite-vec.\n const vectorEmbeddingMethods =\n vectorStrategy === undefined ?\n {}\n : {\n async upsertEmbedding(params: UpsertEmbeddingParams): Promise<void> {\n const slot = vectorSlotFromParams(params);\n // Assert the slot's durable marker (SELECT, cached) — never DDL.\n // The per-field table is provisioned by the privileged migrator\n // (`createStoreWithSchema` → `materializeVectorContributions`), so\n // a least-privilege runtime role writes embeddings without CREATE.\n await contributionMaterializer.assertVectorSlot(slot);\n const statements = vectorStrategy.buildUpsert(slot, params, nowIso());\n try {\n for (const statement of statements) {\n await execRun(statement);\n }\n } catch (error) {\n throw mapVectorWriteError(error, params);\n }\n },\n\n async upsertEmbeddingBatch(\n params: UpsertEmbeddingBatchParams,\n ): Promise<void> {\n if (params.rows.length === 0) return;\n const slot = vectorSlotFromParams(params);\n // Same SELECT-only marker assert as the single-row path — never DDL.\n await contributionMaterializer.assertVectorSlot(slot);\n // Last-write-wins dedupe: a multi-row upsert cannot affect one\n // row twice.\n const rowsById = new Map(\n params.rows.map((row) => [row.nodeId, row] as const),\n );\n const rows = [...rowsById.values()];\n const timestamp = nowIso();\n try {\n for (const chunk of chunkArray(\n rows,\n batchConfig.embeddingUpsertBatchSize,\n )) {\n const statements =\n vectorStrategy.buildUpsertBatch === undefined ?\n chunk.flatMap((row) =>\n vectorStrategy.buildUpsert(\n slot,\n {\n graphId: params.graphId,\n nodeKind: params.nodeKind,\n nodeId: row.nodeId,\n fieldPath: params.fieldPath,\n embedding: row.embedding,\n dimensions: params.dimensions,\n metric: params.metric,\n indexType: params.indexType,\n },\n timestamp,\n ),\n )\n : vectorStrategy.buildUpsertBatch(\n slot,\n { ...params, rows: chunk },\n timestamp,\n );\n for (const statement of statements) {\n await execRun(statement);\n }\n }\n } catch (error) {\n throw mapVectorWriteError(error, params);\n }\n },\n\n async deleteEmbedding(params: DeleteEmbeddingParams): Promise<void> {\n // Assert the slot's durable marker before deleting. A delete can\n // run before any embedding was ever written for the field (e.g. a\n // node hard-deleted having never carried one); the per-field table\n // was provisioned at boot, so the DELETE targets an existing\n // (possibly empty) table and is a clean no-op — never a DELETE\n // against a missing relation, which would abort an enclosing\n // Postgres transaction. SELECT-only assert, never DDL.\n const slot = vectorSlotFromParams(params);\n await contributionMaterializer.assertVectorSlot(slot);\n const statements = vectorStrategy.buildDelete(slot, params);\n for (const statement of statements) {\n await execRun(statement);\n }\n },\n\n async vectorSearch(\n params: VectorSearchParams,\n ): Promise<readonly VectorSearchResult[]> {\n assertVectorSearchLimit(params.limit);\n // Validate `efSearch` against pgvector's `hnsw.ef_search` ceiling\n // before `runVectorSearch` applies it via `set_config`.\n assertPgvectorEfSearch(params.efSearch);\n const slot = vectorSlotFromParams(params);\n // Deliberately NOT marker-gated: search is read-only (no DDL\n // hazard to gate), and its params carry the caller's runtime\n // metric override, which legitimately diverges from the\n // provisioned shape on strategies that bake the metric into the\n // DDL (sqlite-vec; pgvector's table DDL is metric-free but the\n // contract is kept identical across dialects). An unprovisioned\n // slot surfaces the engine's missing-relation error — the same\n // contract as a query-builder `similarTo()` predicate;\n // `createVerifiedStore` catches both at attach.\n const query = vectorStrategy.buildSearch(\n slot,\n params,\n // Store-compiled candidates (predicates + subclass + currency)\n // take precedence; the live-node default covers direct backend use.\n params.candidates ??\n buildLiveNodeCandidates(\n tableNames.nodes,\n params.graphId,\n params.nodeKind,\n nowIso(),\n ),\n );\n const gucOverrides = await vectorSearchGucOverrides(params);\n let rows: readonly { node_id: string; score: number }[];\n try {\n rows = await runVectorSearch(gucOverrides, query);\n } catch (error) {\n // A query vector whose dimension no longer matches the stored\n // column surfaces the same typed error as the write path.\n throw mapVectorWriteError(error, params);\n }\n return rows.map((row) => ({\n nodeId: row.node_id,\n score: row.score,\n }));\n },\n // Single-statement hybrid needs ROW_NUMBER(); a capability\n // profile that disables window functions keeps the store's\n // multi-statement fallback by simply not exposing the member.\n ...(capabilities.windowFunctions ?\n {\n async hybridSearch(\n params: HybridSearchParams,\n ): Promise<readonly HybridSearchRow[]> {\n assertVectorSearchLimit(params.limit);\n // Source depths get the same boundary validation the fallback\n // path applies (vectorSearch validates its limit; the fulltext\n // depth is validated inside buildFulltextSearch).\n assertVectorSearchLimit(params.vector.k);\n assertPgvectorEfSearch(params.vector.efSearch);\n const slot = vectorSlotFromParams({\n graphId: params.graphId,\n nodeKind: params.nodeKind,\n fieldPath: params.vector.fieldPath,\n dimensions: params.vector.dimensions,\n metric: params.vector.metric,\n indexType: params.vector.indexType,\n });\n // Read-only, not marker-gated — see vectorSearch above.\n const candidates =\n params.candidates ??\n buildLiveNodeCandidates(\n tableNames.nodes,\n params.graphId,\n params.nodeKind,\n nowIso(),\n );\n const vectorParams: VectorSearchParams = {\n graphId: params.graphId,\n nodeKind: params.nodeKind,\n fieldPath: params.vector.fieldPath,\n queryEmbedding: params.vector.queryEmbedding,\n metric: params.vector.metric,\n dimensions: params.vector.dimensions,\n indexType: params.vector.indexType,\n limit: params.vector.k,\n ...(params.vector.minScore === undefined ?\n {}\n : { minScore: params.vector.minScore }),\n };\n // The vector leg references the statement's shared\n // tg_hybrid_cand CTE; the actual candidates SQL is emitted\n // once by buildHybridSearch.\n const vectorSql = vectorStrategy.buildSearch(\n slot,\n vectorParams,\n portableSql.raw(\"SELECT node_id FROM tg_hybrid_cand\"),\n );\n const statement = operationStrategy.buildHybridSearch(\n { ...params, candidates },\n toDrizzleSql(vectorSql, \"postgres\"),\n params.vector.metric === \"cosine\",\n );\n const gucOverrides = await vectorSearchGucOverrides({\n indexType: params.vector.indexType,\n ...(params.vector.efSearch === undefined ?\n {}\n : { efSearch: params.vector.efSearch }),\n });\n let raw: readonly Record<string, unknown>[];\n try {\n raw = await runVectorSearch<Record<string, unknown>>(\n gucOverrides,\n statement,\n );\n } catch (error) {\n throw mapVectorWriteError(error, vectorParams);\n }\n return raw.map((row) => mapHybridSearchRow(row, toNodeRow));\n },\n }\n : {}),\n };\n\n const operationBackend: InternalOperationBackend = {\n ...commonBackend,\n ...executeRawMethod,\n ...vectorEmbeddingMethods,\n capabilities,\n fulltextStrategy,\n ...(vectorStrategy === undefined ? {} : { vectorStrategy }),\n dialect: \"postgres\",\n tableNames,\n\n // === Vector Index Operations ===\n\n async createVectorIndex(params: CreateVectorIndexParams): Promise<void> {\n if (vectorStrategy === undefined) return;\n const slot = vectorSlotFromCreateIndexParams(params);\n // Ensure the per-field table + its durable marker first (privileged,\n // idempotent), then create its ANN index. pgvector's `ownedTables`\n // builds the table only — the HNSW/IVFFlat index is created here (and\n // only here) so it picks up the declared `m`/`ef_construction`/`lists`\n // from `slot.indexParams` rather than defaults.\n await contributionMaterializer.ensureVectorSlot(slot);\n // Honor the `concurrent` flag materializeIndexes passes on Postgres so the\n // ANN build doesn't take a write-blocking lock on a live table. execRun is\n // autocommit, which CONCURRENTLY requires.\n const indexStatement = vectorStrategy.buildCreateIndex?.(slot, {\n concurrent: params.concurrent === true,\n });\n if (indexStatement !== undefined) {\n try {\n await execRun(indexStatement);\n } catch (error) {\n if (!isInsufficientResourcesError(error)) throw error;\n // Parallel HNSW/IVFFlat builds stage the build graph in dynamic\n // shared memory, and resource-constrained hosts reject the\n // allocation (SQLSTATE class 53 — e.g. containers with the 64MB\n // /dev/shm default fail a 50k x 384-dim HNSW build with 53100\n // from dsm_impl_posix). Retry serially: drop the INVALID\n // leftover the failed CONCURRENTLY build leaves behind (its\n // IF NOT EXISTS would otherwise mask the retry), pin the\n // strategy table to parallel_workers = 0 (maintenance builds\n // take min(storage parameter, max_parallel_maintenance_workers)),\n // rebuild in local memory, and restore the setting.\n const dropStatement = vectorStrategy.buildDropIndex?.(slot);\n if (dropStatement !== undefined) {\n await execRun(dropStatement);\n }\n const table = portableSql.identifier(\n vectorStrategy.tableName(\n slot.graphId,\n slot.nodeKind,\n slot.fieldPath,\n ),\n );\n await execRun(\n portableSql`ALTER TABLE ${table} SET (parallel_workers = 0)`,\n );\n try {\n await execRun(indexStatement);\n } finally {\n await execRun(\n portableSql`ALTER TABLE ${table} RESET (parallel_workers)`,\n );\n }\n }\n }\n },\n\n // === Fulltext Operations ===\n\n async upsertFulltext(params: UpsertFulltextParams): Promise<void> {\n const timestamp = nowIso();\n const statements = operationStrategy.buildUpsertFulltext(\n params,\n timestamp,\n );\n for (const stmt of statements) {\n await execRun(stmt);\n }\n },\n\n async deleteFulltext(params: DeleteFulltextParams): Promise<void> {\n const statements = operationStrategy.buildDeleteFulltext(params);\n for (const stmt of statements) {\n await execRun(stmt);\n }\n },\n\n async upsertFulltextBatch(\n params: UpsertFulltextBatchParams,\n ): Promise<void> {\n if (params.rows.length === 0) return;\n const timestamp = nowIso();\n // The strategy emits ONE statement over every row it is given, so\n // the bind budget is enforced here — same contract as node/edge\n // batch inserts.\n for (const rows of chunkArray(\n params.rows,\n POSTGRES_FULLTEXT_UPSERT_BATCH_SIZE,\n )) {\n const statements = operationStrategy.buildUpsertFulltextBatch(\n { ...params, rows },\n timestamp,\n );\n for (const stmt of statements) {\n await execRun(stmt);\n }\n }\n },\n\n async deleteFulltextBatch(\n params: DeleteFulltextBatchParams,\n ): Promise<void> {\n if (params.nodeIds.length === 0) return;\n for (const nodeIds of chunkArray(\n params.nodeIds,\n POSTGRES_FULLTEXT_DELETE_CHUNK_SIZE,\n )) {\n const statements = operationStrategy.buildDeleteFulltextBatch({\n ...params,\n nodeIds,\n });\n for (const stmt of statements) {\n await execRun(stmt);\n }\n }\n },\n\n async fulltextSearch(\n params: FulltextSearchParams,\n ): Promise<readonly FulltextSearchResult[]> {\n const query = operationStrategy.buildFulltextSearch(params);\n // pg returns `numeric` as a string to preserve precision; coerce at the\n // backend boundary so FulltextSearchResult.score is always `number`.\n const rows = await execAll<{\n node_id: string;\n score: number | string;\n snippet: string | null;\n }>(query);\n return rows.map((row, index) => ({\n nodeId: row.node_id,\n score: coerceNumericScore(row.score),\n rank: index + 1,\n ...(row.snippet === null ? {} : { snippet: row.snippet }),\n }));\n },\n\n async dropVectorIndex(params: DropVectorIndexParams): Promise<void> {\n if (vectorStrategy === undefined) return;\n const slot = vectorSlotFromDropIndexParams(params);\n const dropStatement = vectorStrategy.buildDropIndex?.(slot);\n if (dropStatement === undefined) return;\n try {\n await execRun(dropStatement);\n } catch (error) {\n // The per-field table (and thus its index) may never have been\n // materialized; treat a missing relation as already-dropped.\n if (!isMissingTableError(error)) throw error;\n }\n },\n\n // === Query Execution ===\n\n async execute<T>(query: CompiledRowsSql): Promise<readonly T[]> {\n // Statements the compiler branded as containing an ANN index scan\n // (inline `approximate: true`) get the same pgvector GUC wrapping\n // the search facade applies — most importantly\n // `hnsw.iterative_scan = strict_order`, without which a filtered\n // approximate query starves at the default ef_search frontier.\n // On pgvector < 0.8 the override list is empty and this falls\n // through to the plain fast path.\n const annTypes =\n isSqlFragment(query) ? annIndexScanTypes(query) : undefined;\n if (annTypes !== undefined && vectorStrategy !== undefined) {\n const overrides: SearchGucOverride[] = [];\n for (const indexType of annTypes) {\n if (indexType !== \"hnsw\" && indexType !== \"ivfflat\") continue;\n overrides.push(...(await vectorSearchGucOverrides({ indexType })));\n }\n return runVectorSearch<T>(overrides, query);\n }\n return executionAdapter.execute<T>(query);\n },\n\n compileSql(\n query: SqlFragment,\n ): Readonly<{ sql: string; params: readonly unknown[] }> {\n return executionAdapter.compile(query);\n },\n };\n\n return operationBackend;\n}\n\n/**\n * A transaction-scoped backend plus the hook that shuts its statement queue\n * at the transaction boundary. See {@link SerialExecutionAdapter.drainAndClose}.\n */\ntype BoundTransactionBackend = Readonly<{\n backend: InternalOperationBackend;\n drainAndClose: () => Promise<void>;\n}>;\n\nfunction createTransactionBackend(\n options: CreatePostgresTransactionBackendOptions,\n): BoundTransactionBackend {\n // Every statement this backend issues rides one pinned connection, which\n // can carry exactly one query at a time. Serialize them here rather than\n // relying on the driver's own queue: node-postgres deprecated\n // `client.query()` on a busy client in 8.22 and removes the queue in pg@9.\n // The wrap is unconditional because the overlap is created inside TypeGraph\n // (the node write pipeline syncs embeddings and fulltext concurrently), not\n // only by user code.\n const txExecutionAdapter = createSerialExecutionAdapter(\n createPostgresExecutionAdapter(options.db, options.adapterOptions),\n );\n\n // The transaction-scoped backend shares the outer backend's\n // contribution materializer: the per-field vector table is provisioned\n // (DDL) only by the privileged outer backend, so a tx-scoped vector op\n // only ASSERTS the durable marker (SELECT, never DDL) and can't poison\n // anything on rollback. The shared per-instance cache means a slot\n // confirmed once stays a pure `Set.has` inside every later transaction.\n const backend = createPostgresOperationBackend({\n db: options.db,\n executionAdapter: txExecutionAdapter,\n adapterOptions: options.adapterOptions,\n operationStrategy: options.operationStrategy,\n tableNames: options.tableNames,\n capabilities: options.capabilities,\n fulltextStrategy: options.fulltextStrategy,\n vectorStrategy: options.vectorStrategy,\n contributionMaterializer: options.contributionMaterializer,\n // The probe is process-wide truth, so the outer instance's is reused\n // rather than a fresh one per transaction.\n iterativeScanProbe: options.iterativeScanProbe,\n });\n\n return { backend, drainAndClose: txExecutionAdapter.drainAndClose };\n}\n\n// Re-export schema utilities\nexport type { PostgresTableNames, PostgresTables } from \"./schema/postgres\";\nexport { createPostgresTables, tables } from \"./schema/postgres\";\n"]}
1
+ {"version":3,"sources":["../src/backend/drizzle/execution/postgres-execution.ts","../src/backend/drizzle/execution/statement-queue.ts","../src/backend/drizzle/postgres.ts"],"names":["sql","tables","backend","options","chunk"],"mappings":"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","file":"chunk-IFRPHG7O.js","sourcesContent":["import { type SQL as DrizzleSql } from \"drizzle-orm\";\nimport {\n type PgDatabase,\n type PgQueryResultHKT,\n type PgTransaction,\n} from \"drizzle-orm/pg-core\";\nimport { type ExtractTablesWithRelations } from \"drizzle-orm/relations\";\n\nimport { isSqlFragment } from \"../../../query/sql-fragment\";\nimport { shouldForceCustomPlan } from \"../../../query/sql-intent\";\nimport { getOrCreateLru } from \"./lru\";\nimport {\n type CompiledSqlQuery,\n compileQueryWithDialect,\n type ExecutableSql,\n type PreparedSqlStatement,\n type SqlExecutionAdapter,\n toDrizzleSql,\n} from \"./types\";\n\n/**\n * Edge-safe: this module is loaded on Cloudflare Workers / Vercel Edge\n * via `@neondatabase/serverless`, so it must not statically import any\n * `node:*` module. Use only platform-neutral primitives.\n */\n\ntype PgQueryResult = Readonly<{\n rows: readonly unknown[];\n}>;\n\n/**\n * The wire-protocol-shaped client the fast path calls. Both the wrapped\n * node-postgres and postgres-js clients normalize to this signature; what\n * differs is whether the underlying driver gets a server-side prepared\n * statement (node-postgres path) or relies on its own internal preparation\n * (postgres-js).\n */\ntype PgQueryClient = Readonly<{\n query: (\n sqlText: string,\n params: readonly unknown[],\n ) => Promise<PgQueryResult>;\n /**\n * Executes WITHOUT a named server-side prepared statement, so the\n * server plans against the actual parameter values on every call.\n * Used for statements marked `markForceCustomPlan` (see sql-intent).\n */\n queryUnnamed: (\n sqlText: string,\n params: readonly unknown[],\n ) => Promise<PgQueryResult>;\n}>;\n\n/**\n * Minimal shape of the node-postgres / @neondatabase/serverless client\n * we rely on. Both accept either positional `query(text, values)`\n * (unnamed) or the configuration-object form `query({name, text, values})`\n * which uses a server-side prepared statement keyed by `name`.\n */\ntype NodePgQueryConfig = Readonly<{\n name: string;\n text: string;\n values: readonly unknown[];\n}>;\n\ntype NodePgClient = Readonly<{\n query: ((\n sqlText: string,\n params?: readonly unknown[],\n ) => Promise<PgQueryResult>) &\n ((config: NodePgQueryConfig) => Promise<PgQueryResult>);\n}>;\n\n/**\n * Minimal shape of the postgres-js tagged-template `Sql` client we rely on\n * for the raw fast path. `unsafe(sqlText, params)` is postgres-js's\n * parameterized-raw-SQL entry point and resolves to a row array.\n */\ntype PostgresJsClient = ((...args: readonly unknown[]) => unknown) &\n Readonly<{\n unsafe: (\n sqlText: string,\n params?: readonly unknown[],\n queryOptions?: Readonly<{ prepare?: boolean }>,\n ) => PromiseLike<readonly unknown[]>;\n }>;\n\ntype PgSessionCarrier = Readonly<{\n client?: unknown;\n constructor?: Readonly<{ name?: string }>;\n}>;\n\ntype PgClientCarrier = Readonly<{\n $client?: unknown;\n /** Drizzle's transaction handle keeps the pinned driver here. */\n session?: PgSessionCarrier;\n /** Defensive fallback for Drizzle builds exposing only the internal bag. */\n _?: Readonly<{\n session?: PgSessionCarrier;\n }>;\n}>;\n\nexport type AnyPgDatabase = PgDatabase<\n PgQueryResultHKT,\n Record<string, unknown>\n>;\n\n/**\n * A driver-agnostic Drizzle PostgreSQL transaction handle.\n *\n * Unlike {@link AnyPgDatabase}, this type cannot be satisfied by a root\n * database. It is the native handle exposed to adapter-aware stores and\n * accepted when adopting a caller-owned PostgreSQL transaction.\n */\nexport type AnyPgTransaction = PgTransaction<\n PgQueryResultHKT,\n Record<string, unknown>,\n ExtractTablesWithRelations<Record<string, unknown>>\n>;\n\nexport type PostgresExecutionAdapter = SqlExecutionAdapter;\n\nfunction hasFunctionProperty<K extends string>(\n value: unknown,\n property: K,\n): value is Readonly<Record<K, (...args: readonly unknown[]) => unknown>> {\n if (value === undefined || value === null) {\n return false;\n }\n const candidate = value as Readonly<Record<K, unknown>>;\n return typeof candidate[property] === \"function\";\n}\n\nfunction isPgNativeClient(candidate: unknown): candidate is NodePgClient {\n // pg `Pool` / `Client` and @neondatabase/serverless `Pool` / `Client`\n // are object instances with a `.query` method. We require non-callable\n // here so we don't accidentally swallow the postgres-js or neon-http\n // tagged-template clients (both callable, both also expose `.query`).\n return (\n typeof candidate === \"object\" && hasFunctionProperty(candidate, \"query\")\n );\n}\n\nfunction isPgliteClient(candidate: unknown): candidate is NodePgClient {\n // PGlite (Postgres-in-WASM) exposes `.query(sql, params, options)` like\n // node-postgres and so also satisfies `isPgNativeClient` — but it does NOT\n // accept the `{name, text, values}` named-statement config form. Passing\n // that object doesn't merely fail the call: it desyncs PGlite's single\n // wire connection, so every subsequent query errors with `08P01`. Detect\n // PGlite structurally via `dumpDataDir` (a PGlite-specific method absent on\n // pg `Pool`/`Client`) so `resolvePgClient` can route it to the unnamed\n // positional wrapper regardless of `prepareStatements`. Duck-typed with no\n // static import, keeping this module dependency-free and edge-safe.\n return (\n typeof candidate === \"object\" &&\n hasFunctionProperty(candidate, \"query\") &&\n hasFunctionProperty(candidate, \"dumpDataDir\")\n );\n}\n\nfunction transactionSession(\n carrier: PgClientCarrier,\n): PgSessionCarrier | undefined {\n return carrier.session ?? carrier._?.session;\n}\n\nfunction hasPgliteSession(carrier: PgClientCarrier): boolean {\n return transactionSession(carrier)?.constructor?.name === \"PgliteSession\";\n}\n\nfunction isPostgresJsClient(candidate: unknown): candidate is PostgresJsClient {\n // postgres-js's tagged-template Sql is callable, has `.unsafe` (raw\n // parameterized executor), and has `.begin` (transaction starter). The\n // transaction-scoped `TransactionSql` replaces `.begin` with `.savepoint`;\n // accept either so a Drizzle transaction keeps the fast path pinned.\n // Neon HTTP is also callable + has `.unsafe`, but that `.unsafe` is a\n // fragment builder rather than a query executor, so we discriminate\n // on `.begin` / `.savepoint` (postgres-js only).\n return (\n typeof candidate === \"function\" &&\n hasFunctionProperty(candidate, \"unsafe\") &&\n (hasFunctionProperty(candidate, \"begin\") ||\n hasFunctionProperty(candidate, \"savepoint\"))\n );\n}\n\n/**\n * @neondatabase/serverless's `neon(url)` HTTP-only tagged-template\n * function. Distinguishing markers vs postgres-js: `.transaction`\n * (an HTTP-batch transaction submitter) instead of `.begin`. Its\n * `.query`/`.unsafe` methods have different signatures from pg's, so\n * the fast path can't drive them safely — Drizzle's neon-http session\n * handles them correctly via the `db.execute` slow path.\n *\n * Exported so the backend factory can auto-disable the `transactions`\n * capability when this driver is detected (HTTP can't hold a session,\n * so multi-statement transactions are not available regardless).\n */\nexport function isNeonHttpClient(db: AnyPgDatabase): boolean {\n const candidate = (db as PgClientCarrier).$client;\n return (\n typeof candidate === \"function\" &&\n hasFunctionProperty(candidate, \"transaction\") &&\n !hasFunctionProperty(candidate, \"begin\")\n );\n}\n\n/**\n * Default cap on the number of distinct SQL strings tracked for\n * server-side prepared statements. Mirrors the SQLite adapter's\n * `DEFAULT_PREPARED_STATEMENT_CACHE_MAX`. High-cardinality SQL text —\n * variable-length IN-list expansions, generated aliases, custom\n * `backend.execute()` calls — would otherwise grow this map (and the\n * matching per-session prepared-statement memory inside PostgreSQL)\n * without bound.\n */\nconst DEFAULT_POSTGRES_STATEMENT_CACHE_MAX = 256;\n\n/**\n * Module-scope cache mapping each unique SQL text to a stable\n * prepared-statement name. PostgreSQL only requires statement names to\n * be unique per session, so a monotonic counter is sufficient — and\n * avoids depending on a hash primitive (`node:crypto` doesn't exist on\n * Cloudflare Workers, Web Crypto's digest is async).\n *\n * The cache is module-scope on purpose: pg `Pool` reuses connections,\n * and the same SQL text needs the same statement name across every\n * adapter that might end up driving the same connection. Without\n * shared naming, two adapters could try to register two different\n * statements under the same name on a recycled connection.\n *\n * Bounded by `cacheMax` per call (LRU eviction). The counter is\n * deliberately independent of the cache size so eviction never\n * recycles a name — a recycled name could collide with a still-cached\n * statement on a long-lived pg connection (\"prepared statement\n * already exists\" error with different text).\n */\nconst STATEMENT_NAME_CACHE = new Map<string, string>();\nlet nextStatementId = 0;\n\nfunction statementNameFor(sqlText: string, cacheMax: number): string {\n return getOrCreateLru(STATEMENT_NAME_CACHE, sqlText, cacheMax, () => {\n const name = `tg_${nextStatementId}`;\n nextStatementId += 1;\n return name;\n });\n}\n\n/**\n * Test-only: reset the module-scope statement-name state. Used to\n * isolate tests that assert on counter values or eviction behavior.\n */\nexport function resetStatementNameCacheForTests(): void {\n STATEMENT_NAME_CACHE.clear();\n nextStatementId = 0;\n}\n\n/**\n * Walks a row and replaces any `Date` instance with its ISO-string\n * equivalent. Used to normalize node-postgres / neon-serverless output\n * when we bypass Drizzle's session: pg's default type parsers return\n * `Date` objects for `timestamptz` / `timestamp` / `date` columns, but\n * TypeGraph's row contract everywhere downstream is \"timestamps come\n * back as ISO strings.\" Drizzle's session installs a per-query type\n * override that does the same thing; this is the dependency-free,\n * edge-safe equivalent.\n *\n * O(columns × rows) — negligible for the row counts TypeGraph queries\n * return (typical: 1–100 rows × 5–30 columns).\n */\nfunction normalizeRow(row: unknown): unknown {\n if (row === null || typeof row !== \"object\") return row;\n let mutated: Record<string, unknown> | undefined;\n for (const key of Object.keys(row)) {\n const value = (row as Record<string, unknown>)[key];\n if (value instanceof Date) {\n mutated ??= { ...(row as Record<string, unknown>) };\n mutated[key] = value.toISOString();\n }\n }\n return mutated ?? row;\n}\n\nfunction normalizeRows(rows: readonly unknown[]): readonly unknown[] {\n // Single-pass scan; only allocate a new array if any row contained a\n // Date that needed normalizing. Most rows on most queries don't.\n let mutated: unknown[] | undefined;\n for (let index = 0; index < rows.length; index += 1) {\n const original = rows[index];\n const normalized = normalizeRow(original);\n if (normalized !== original) {\n mutated ??= [...rows] as unknown[];\n mutated[index] = normalized;\n }\n }\n return mutated ?? rows;\n}\n\n/**\n * Wraps a node-postgres / neon-serverless client so every call goes\n * through a server-side prepared statement keyed by a stable name. The\n * first call on each connection parses + plans + executes; subsequent\n * calls with the same statement name reuse the cached plan and skip\n * both parse and plan phases. Measurable on multi-CTE TypeGraph\n * queries: 3-hop drops from ~7-12ms (parse + plan + execute every call)\n * to ~0.8ms median (execute only).\n *\n * Returned rows are normalized so that `Date` objects from default pg\n * type parsers become ISO strings, matching the row shape Drizzle's\n * session would produce. Without this, `ctx.<alias>.meta.createdAt`\n * style accessors in the SELECT-result path return Date instances,\n * breaking user code that expects strings.\n */\nfunction wrapNodePgClient(\n client: NodePgClient,\n cacheMax: number,\n): PgQueryClient {\n return {\n async query(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<PgQueryResult> {\n const result = await client.query({\n name: statementNameFor(sqlText, cacheMax),\n text: sqlText,\n values: params,\n });\n return { rows: normalizeRows(result.rows) };\n },\n async queryUnnamed(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<PgQueryResult> {\n const result = await client.query(sqlText, params);\n return { rows: normalizeRows(result.rows) };\n },\n };\n}\n\n/**\n * Variant that bypasses server-side prepared statements entirely.\n * Required for pgbouncer in transaction-pool mode (named statements\n * registered on one backend connection aren't visible on the next),\n * and useful when memory-sensitive workloads can't afford to keep\n * prepared statements warm across the pool.\n *\n * Same Date→ISO normalization as `wrapNodePgClient` so the row contract\n * downstream stays identical.\n */\nfunction wrapNodePgClientUnnamed(client: NodePgClient): PgQueryClient {\n async function queryUnnamed(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<PgQueryResult> {\n const result = await client.query(sqlText, params);\n return { rows: normalizeRows(result.rows) };\n }\n return {\n query: queryUnnamed,\n queryUnnamed,\n };\n}\n\nfunction adaptPostgresJsClient(sql: PostgresJsClient): PgQueryClient {\n async function query(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<PgQueryResult> {\n // postgres-js handles its own statement preparation internally\n // (controlled by the `prepare` connection option, default true),\n // so we don't need to name statements here ourselves.\n const rows = await sql.unsafe(sqlText, params);\n return { rows };\n }\n return {\n query,\n async queryUnnamed(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<PgQueryResult> {\n // Per-call opt-out of postgres-js's internal preparation\n // (verified: `unsafe(text, params, { prepare: false })` leaves\n // pg_prepared_statements empty), so custom-plan-preferring\n // statements are re-planned against their actual parameters on\n // every call — same contract as the node-postgres unnamed path.\n const rows = await sql.unsafe(sqlText, params, { prepare: false });\n return { rows };\n },\n };\n}\n\n/**\n * Resolves a Drizzle-wrapped PostgreSQL client to a uniform `{query}` shape\n * that the fast path can call. Supports:\n *\n * - `drizzle-orm/node-postgres` (pg Pool / Client) — wrapped to use\n * server-side prepared statements with stable counter-derived names\n * keyed by the SQL text (see `statementNameFor`). When\n * `prepareStatements` is `false`, falls back to unnamed\n * `client.query(text, values)` for pgbouncer transaction-pool\n * compatibility.\n * - `drizzle-orm/neon-serverless` (@neondatabase/serverless Pool) —\n * pg-Pool-compatible, takes the same wrapper as node-postgres\n * - `drizzle-orm/postgres-js` (postgres-js tagged-template Sql) — adapted\n * via `.unsafe(sql, params)`. Safe because Drizzle installs transparent\n * parsers on the same client instance at `drizzle()` time, so direct\n * calls and Drizzle-routed calls produce identical row shapes.\n * - `drizzle-orm/pglite` (PGlite, Postgres-in-WASM) — routed to the unnamed\n * wrapper unconditionally. PGlite's `.query` has no named-statement config\n * form (and server-side prepared statements buy nothing for an in-process\n * engine), so `prepareStatements` is ignored for it.\n *\n * Returns `undefined` for `drizzle-orm/neon-http` and any other driver we\n * don't recognize; callers fall back to `db.execute(sql)`, which goes\n * through the Drizzle session and is always correct (just without the\n * server-side prepared-statement perf win).\n */\nfunction resolvePgClient(\n db: AnyPgDatabase,\n prepareStatements: boolean,\n cacheMax: number,\n useTransactionClient: boolean,\n): PgQueryClient | undefined {\n // Order matters: neon-http and postgres-js are both callable + have\n // `.unsafe`, but neon-http's `.unsafe` is a fragment builder (not a\n // query executor) and its `.query` doesn't accept the {name, text,\n // values} config form. Skip the fast path entirely for neon-http and\n // let Drizzle's session route the call.\n if (isNeonHttpClient(db)) {\n return undefined;\n }\n const carrier = db as PgClientCarrier;\n // Top-level Drizzle databases expose `$client`. Transaction objects do not;\n // they retain the exact pinned pool/client transaction on `session.client`.\n // Reading that structural internal is what keeps trusted import on the same\n // connection that will COMMIT/ROLLBACK, instead of accidentally using the\n // outer pool while a transaction is open.\n const client =\n carrier.$client ??\n (useTransactionClient ? transactionSession(carrier)?.client : undefined);\n // Must precede `isPgNativeClient`: PGlite matches it too (object with\n // `.query`), but only the unnamed wrapper is safe for it (see\n // `isPgliteClient`).\n if (\n isPgliteClient(client) ||\n (useTransactionClient && hasPgliteSession(carrier))\n ) {\n if (!isPgNativeClient(client)) return undefined;\n return wrapNodePgClientUnnamed(client);\n }\n if (isPgNativeClient(client)) {\n return prepareStatements ?\n wrapNodePgClient(client, cacheMax)\n : wrapNodePgClientUnnamed(client);\n }\n if (isPostgresJsClient(client)) {\n // postgres-js handles its own preparation internally (controlled\n // by the driver's own `prepare` connection option) — the\n // `prepareStatements` flag here only affects the node-postgres\n // path.\n return adaptPostgresJsClient(client);\n }\n return undefined;\n}\n\n/**\n * Normalizes the result shape of `db.execute(sql)` across drivers.\n *\n * - `drizzle-orm/node-postgres` / `drizzle-orm/neon-serverless` return a\n * pg-style `{ rows, rowCount, ... }` object.\n * - `drizzle-orm/postgres-js` returns the raw postgres-js result, which is\n * a plain array of rows (with extra non-enumerable properties like\n * `count` / `command`).\n *\n * The backend contract is \"a row array.\" Normalize here so every caller\n * downstream can assume the same shape.\n */\nasync function executeDrizzleQuery<TRow>(\n db: AnyPgDatabase,\n query: DrizzleSql,\n): Promise<readonly TRow[]> {\n const result = await db.execute(query);\n if (Array.isArray(result)) {\n return result as readonly TRow[];\n }\n return (result as Readonly<{ rows: readonly TRow[] }>).rows;\n}\n\nfunction createPgPreparedStatement(\n pgClient: PgQueryClient,\n sqlText: string,\n): PreparedSqlStatement {\n return {\n async execute<TRow>(params: readonly unknown[]): Promise<readonly TRow[]> {\n const result = await pgClient.query(sqlText, params);\n return result.rows as readonly TRow[];\n },\n };\n}\n\n/**\n * Tuning options for the PostgreSQL execution fast path.\n *\n * Defaults are correct for `drizzle-orm/node-postgres` against a\n * standalone PostgreSQL or session-pooled deployment. Override when:\n *\n * - **Pooling through pgbouncer in transaction-pool mode.** Set\n * `prepareStatements: false`. Named statements registered on one\n * pooled backend connection aren't visible to the next, so the\n * server-side prepared-statement cache must be off.\n * - **High-cardinality SQL text.** If the application emits many\n * distinct compiled SQL strings (variable-length IN-list expansions,\n * custom `backend.execute()` calls, generated aliases), tune\n * `preparedStatementCacheMax` down to bound per-session memory more\n * aggressively, or up if memory is plentiful and you want fewer\n * re-PREPAREs.\n */\nexport type PostgresExecutionAdapterOptions = Readonly<{\n /**\n * When `true` (default), node-postgres / neon-serverless calls go\n * through `client.query({name, text, values})` so PostgreSQL caches\n * the parsed/planned statement per session. Set to `false` to issue\n * unnamed `client.query(text, values)` calls — required for\n * pgbouncer transaction-pool mode.\n */\n prepareStatements?: boolean;\n /**\n * Maximum number of distinct SQL strings tracked for prepared-\n * statement naming. Defaults to `DEFAULT_POSTGRES_STATEMENT_CACHE_MAX`\n * (256). Ignored when `prepareStatements` is `false`.\n */\n preparedStatementCacheMax?: number;\n /**\n * @internal Resolve Drizzle's pinned transaction client. Trusted import uses\n * this on its private adapter; ordinary transaction backends deliberately do\n * not expose a new raw-execution surface that would change routing behavior.\n */\n useTransactionClient?: boolean;\n}>;\n\nexport function createPostgresExecutionAdapter(\n db: AnyPgDatabase,\n options: PostgresExecutionAdapterOptions = {},\n): PostgresExecutionAdapter {\n const prepareStatements = options.prepareStatements ?? true;\n const cacheMax =\n options.preparedStatementCacheMax ?? DEFAULT_POSTGRES_STATEMENT_CACHE_MAX;\n const pgClient = resolvePgClient(\n db,\n prepareStatements,\n cacheMax,\n options.useTransactionClient ?? false,\n );\n\n function compile(query: ExecutableSql): CompiledSqlQuery {\n return compileQueryWithDialect(db, query, \"PostgreSQL\");\n }\n\n if (pgClient === undefined) {\n return {\n compile,\n async execute<TRow>(query: ExecutableSql): Promise<readonly TRow[]> {\n return executeDrizzleQuery<TRow>(\n db,\n isSqlFragment(query) ? toDrizzleSql(query, \"postgres\") : query,\n );\n },\n };\n }\n\n const pgQueryClient = pgClient;\n\n async function executeCompiled<TRow>(\n compiledQuery: CompiledSqlQuery,\n ): Promise<readonly TRow[]> {\n const result = await pgQueryClient.query(\n compiledQuery.sql,\n compiledQuery.params,\n );\n return result.rows as readonly TRow[];\n }\n\n return {\n compile,\n async execute<TRow>(query: ExecutableSql): Promise<readonly TRow[]> {\n // Fast path: compile via Drizzle's dialect, then execute through\n // the wrapped client directly. Bypasses Drizzle's session\n // overhead (logging spans, plan-cache bookkeeping for typed\n // queries we don't use), and on node-postgres this also enables\n // the server-side prepared-statement path because the wrapped\n // client assigns each unique SQL a stable statement name.\n const compiled = compile(query);\n if (isSqlFragment(query) && shouldForceCustomPlan(query)) {\n const result = await pgQueryClient.queryUnnamed(\n compiled.sql,\n compiled.params,\n );\n return result.rows as readonly TRow[];\n }\n return executeCompiled<TRow>(compiled);\n },\n executeCompiled,\n prepare(sqlText: string): PreparedSqlStatement {\n return createPgPreparedStatement(pgQueryClient, sqlText);\n },\n };\n}\n","/**\n * Per-connection statement serialization for transaction-scoped backends.\n *\n * A pooled backend hands every statement its own connection, so concurrent\n * work is genuinely concurrent. A transaction is the opposite: every\n * statement shares one pinned connection, and the PostgreSQL wire protocol\n * has no request pipelining a driver could use to keep two in flight. Drivers\n * paper over this with an internal queue — node-postgres queues on\n * `Client._queryQueue` — but that queue is deprecated as of `pg@8.22` and is\n * removed in `pg@9`:\n *\n * > Calling client.query() when the client is already executing a query is\n * > deprecated and will be removed in pg@9.0. Use async/await or an external\n * > async flow control mechanism instead.\n *\n * TypeGraph overlaps statements on a pinned connection by construction: the\n * node write pipeline issues embedding and fulltext sync concurrently, and\n * `store.transaction()` invites callers to `Promise.all` their writes. This\n * queue is the \"external async flow control mechanism\" the deprecation asks\n * for — it keeps the concurrency at the API surface while presenting exactly\n * one statement at a time to the connection.\n *\n * Wrapping is deliberately confined to transaction-scoped adapters. On a pool\n * the queue would serialize independent connections and destroy throughput.\n *\n * Edge-safe: no `node:*` imports (loaded on Workers via neon-serverless).\n */\nimport { TransactionClosedError } from \"../../../errors\";\nimport {\n type CompiledSqlQuery,\n type ExecutableSql,\n type PreparedSqlStatement,\n type SqlExecutionAdapter,\n} from \"./types\";\n\n/**\n * A {@link SqlExecutionAdapter} that runs one statement at a time and can be\n * shut so that late statements never reach the connection.\n */\nexport type SerialExecutionAdapter = SqlExecutionAdapter &\n Readonly<{\n runExclusive: NonNullable<SqlExecutionAdapter[\"runExclusive\"]>;\n /**\n * Waits for the statement currently on the wire, then refuses every\n * later one with a {@link TransactionClosedError}.\n *\n * Callers invoke this at the transaction boundary, before the driver\n * emits `COMMIT` / `ROLLBACK` on the same connection. The driver's control\n * statement does not travel through this queue, so without the drain it\n * would overlap a live statement; without the close, a statement the\n * callback left running could land after the pool reclaimed the\n * connection — inside an unrelated transaction.\n *\n * Idempotent.\n */\n drainAndClose: () => Promise<void>;\n }>;\n\ntype StatementQueue = Readonly<{\n /** Runs tasks one at a time, in the order they were submitted. */\n enqueue: <T>(task: () => Promise<T>) => Promise<T>;\n drainAndClose: () => Promise<void>;\n}>;\n\n/**\n * Swallows a statement's outcome so the queue's tail always fulfills. The\n * caller owns the result promise; the tail only tracks completion, and an\n * untouched rejection here would surface as an unhandled rejection.\n */\nfunction ignoreOutcome(): void {\n // Intentionally empty: see above.\n}\n\nfunction createStatementQueue(): StatementQueue {\n // Always fulfilled: a failed statement must not strand its successors, and\n // an untouched rejection here would surface as an unhandled rejection.\n let tail: Promise<void> = Promise.resolve();\n let closed = false;\n\n return {\n enqueue<T>(task: () => Promise<T>): Promise<T> {\n if (closed) return Promise.reject(new TransactionClosedError());\n // Chained synchronously, so queue order is submission order.\n const result = tail.then(() => task());\n tail = result.then(ignoreOutcome, ignoreOutcome);\n return result;\n },\n\n async drainAndClose(): Promise<void> {\n // Close first: a statement whose continuation enqueues a successor must\n // find the queue already shut, or it would slip in behind the drain.\n closed = true;\n await tail;\n },\n };\n}\n\n/**\n * Wraps `adapter` so at most one statement is in flight on its connection.\n *\n * Only the I/O members are queued. `compile` is pure — it renders a Drizzle\n * `SQL` to text and params without touching the connection — so it stays\n * synchronous and unqueued.\n *\n * The queue is a leaf: nothing it runs re-enters it, so a queued statement\n * can never wait on a statement queued behind it.\n */\nexport function createSerialExecutionAdapter(\n adapter: SqlExecutionAdapter,\n): SerialExecutionAdapter {\n const { enqueue, drainAndClose } = createStatementQueue();\n const { executeCompiled, prepare } = adapter;\n\n return {\n drainAndClose,\n\n compile(query: ExecutableSql): CompiledSqlQuery {\n return adapter.compile(query);\n },\n\n execute<TRow>(query: ExecutableSql): Promise<readonly TRow[]> {\n return enqueue(() => adapter.execute<TRow>(query));\n },\n\n runExclusive<T>(\n critical: (connection: SqlExecutionAdapter) => Promise<T>,\n ): Promise<T> {\n // One queue slot for the whole group. `critical` receives the UNQUEUED\n // adapter: re-entering the queue from inside the slot it already holds\n // would deadlock, and it needs no serializing anyway — nothing else can\n // reach the connection until the slot is released.\n return enqueue(() => critical(adapter));\n },\n\n ...(executeCompiled === undefined ?\n {}\n : {\n executeCompiled<TRow>(\n compiledQuery: CompiledSqlQuery,\n ): Promise<readonly TRow[]> {\n return enqueue(() => executeCompiled<TRow>(compiledQuery));\n },\n }),\n\n ...(prepare === undefined ?\n {}\n : {\n prepare(sqlText: string): PreparedSqlStatement {\n const statement = prepare(sqlText);\n return {\n execute<TRow>(\n params: readonly unknown[],\n ): Promise<readonly TRow[]> {\n return enqueue(() => statement.execute<TRow>(params));\n },\n };\n },\n }),\n };\n}\n","/**\n * PostgreSQL backend adapter for TypeGraph.\n *\n * Works with any Drizzle PostgreSQL database instance. Tested against:\n * - `drizzle-orm/node-postgres` (pg Pool / Client)\n * - `drizzle-orm/postgres-js` (postgres-js tagged-template client)\n * - `drizzle-orm/neon-serverless` (@neondatabase/serverless Pool / Client)\n * - `drizzle-orm/neon-http` (@neondatabase/serverless `neon(url)`) —\n * transactions are auto-disabled because HTTP can't hold a session;\n * use `drizzle-orm/neon-serverless` if you need transactional writes.\n *\n * - `drizzle-orm/pglite` (PGlite, Postgres-in-WASM) — the execution\n * fast path detects PGlite and routes it correctly (its `.query` has no\n * named-statement form). For a batteries-included in-process setup, see\n * `createLocalPgliteBackend` in `@nicia-ai/typegraph/adapters/drizzle/postgres/pglite`.\n *\n * Other pg-protocol Drizzle adapters (Vercel Postgres, Supabase via pg)\n * work unchanged because they all expose a compatible `db.execute()` /\n * `db.transaction()` surface.\n *\n * @example\n * ```typescript\n * import { drizzle } from \"drizzle-orm/node-postgres\";\n * import { Pool } from \"pg\";\n * import { createPostgresBackend, tables } from \"@nicia-ai/typegraph/adapters/drizzle/postgres\";\n *\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n * const db = drizzle(pool);\n * const backend = createPostgresBackend(db, { tables });\n * ```\n */\nimport {\n and,\n eq,\n getTableName,\n inArray,\n isNull,\n type SQL,\n sql,\n} from \"drizzle-orm\";\nimport { PgTransaction } from \"drizzle-orm/pg-core\";\n\nimport { CompilerInvariantError, ConfigurationError } from \"../../errors\";\nimport type { ResolvedSqlTableNames } from \"../../query/compiler/schema\";\nimport {\n buildFulltextCapabilities,\n type FulltextStrategy,\n tsvectorStrategy,\n} from \"../../query/dialect/fulltext-strategy\";\nimport {\n assertPgvectorEfSearch,\n pgvectorStrategy,\n} from \"../../query/dialect/vector/pgvector-strategy\";\nimport {\n assertVectorSearchLimit,\n buildVectorCapabilities,\n type VectorSlot,\n type VectorStrategy,\n} from \"../../query/dialect/vector-strategy\";\nimport {\n isSqlFragment,\n sql as portableSql,\n type SqlFragment,\n} from \"../../query/sql-fragment\";\nimport {\n annIndexScanTypes,\n type CompiledRowsSql,\n} from \"../../query/sql-intent\";\nimport { chunk as chunkArray } from \"../../utils/array\";\nimport { requireDefined } from \"../../utils/presence\";\nimport {\n isInsufficientResourcesError,\n isMissingTableError,\n} from \"../../utils/sql-errors\";\nimport { buildLiveNodeCandidates } from \"../live-node-candidates\";\nimport {\n coerceNumericScore,\n createEdgeRowMapper,\n createNodeRowMapper,\n createSchemaVersionRowMapper,\n createUniqueRowMapper,\n nowIso,\n POSTGRES_ROW_MAPPER_CONFIG,\n} from \"../row-mappers\";\nimport {\n type AdapterBackend,\n type BackendCapabilities,\n type ClaimIndexMaterializationParams,\n type CommitSchemaVersionParams,\n type ContributionMaterializationIdentity,\n type ContributionMaterializationRow,\n createBackendOverlay,\n type CreateVectorIndexParams,\n type DeleteEmbeddingParams,\n type DeleteFulltextBatchParams,\n type DeleteFulltextParams,\n type DropVectorIndexParams,\n type FulltextSearchParams,\n type FulltextSearchResult,\n type HybridSearchParams,\n type HybridSearchRow,\n type IndexMaterializationRow,\n INTERNAL_TEMPORARY_WRITES,\n type InternalTransactionOptions,\n type KindRemovalRow,\n normalizeGraphAnalyticsCapabilities,\n POSTGRES_CAPABILITIES,\n POSTGRES_MAX_BIND_PARAMETERS,\n type RecordContributionMaterializationParams,\n type RecordIndexMaterializationParams,\n type RecordKindRemovalParams,\n type ReleaseIndexMaterializationClaimParams,\n type SchemaVersionRow,\n type SetActiveVersionParams,\n type TransactionBackend,\n type TrustedImportSession,\n type UpsertEmbeddingBatchParams,\n type UpsertEmbeddingParams,\n type UpsertFulltextBatchParams,\n type UpsertFulltextParams,\n type VectorSearchParams,\n type VectorSearchResult,\n} from \"../types\";\nimport {\n buildContributionInsertValues,\n buildContributionOnConflictSet,\n type ContributionMaterializer,\n createContributionMaterializer,\n gateFulltext,\n gateFulltextMethods,\n mapContributionMaterializationRow,\n POSTGRES_CONTRIBUTION_MAT_TIMESTAMPS,\n} from \"./contribution-materializations\";\nimport { generatePgCreateTableSQL, generatePostgresDDL } from \"./ddl\";\nimport {\n type AnyPgDatabase,\n type AnyPgTransaction,\n createPostgresExecutionAdapter,\n isNeonHttpClient,\n type PostgresExecutionAdapter,\n type PostgresExecutionAdapterOptions,\n} from \"./execution/postgres-execution\";\nimport { createSerialExecutionAdapter } from \"./execution/statement-queue\";\nimport { type ExecutableSql, toDrizzleSql } from \"./execution/types\";\nimport {\n buildMaterializationInsertValues,\n buildMaterializationOnConflictSet,\n mapMaterializationRow,\n POSTGRES_INDEX_MAT_TIMESTAMPS,\n} from \"./index-materializations\";\nimport {\n buildKindRemovalInsertValues,\n buildKindRemovalOnConflictSet,\n mapKindRemovalRow,\n POSTGRES_KIND_REMOVAL_TIMESTAMPS,\n} from \"./kind-removals\";\nimport {\n assertAdoptedDialect,\n type CommonOperationBackend,\n createCommonOperationBackend,\n type InternalOperationBackend,\n} from \"./operation-backend-core\";\nimport { mapHybridSearchRow } from \"./operations/hybrid\";\nimport {\n createCachedTableExistence,\n createPostgresOperationStrategy,\n} from \"./operations/strategy\";\nimport {\n type PostgresTables,\n tables as defaultTables,\n} from \"./schema/postgres\";\nimport {\n analyzeImportedTables,\n assertTrustedImportDatabaseEmpty,\n createPostgresTrustedImportSession,\n lockPostgresTrustedImportTables,\n restoreSecondaryIndexes,\n suspendPostgresSecondaryIndexes,\n} from \"./trusted-import\";\nimport {\n EMBEDDING_UPSERT_PARAM_COUNT,\n mapVectorWriteError,\n vectorSlotFromCreateIndexParams,\n vectorSlotFromDropIndexParams,\n vectorSlotFromParams,\n} from \"./vector-runtime\";\n\n// ============================================================\n// Types\n// ============================================================\n\n/**\n * Options for creating a PostgreSQL backend.\n */\nexport type PostgresBackendOptions = Readonly<{\n /**\n * Custom table definitions. Use createPostgresTables() to customize table names.\n * Defaults to standard TypeGraph table names.\n */\n tables?: PostgresTables;\n /**\n * Fulltext strategy override. Defaults to `tsvectorStrategy`\n * (Postgres built-in `tsvector` + GIN). Pass a custom strategy here to\n * swap the entire fulltext stack — DDL, MATCH condition, rank\n * expression, and snippet generation — for alternate Postgres\n * backends like ParadeDB (`pg_search`), pg_trgm similarity, or\n * pgroonga without forking TypeGraph.\n */\n fulltext?: FulltextStrategy;\n /**\n * Vector strategy override. Defaults to `pgvectorStrategy` (pgvector's\n * `vector(N)` columns + HNSW/IVFFlat). The strategy owns per-`(kind,\n * field)` typed storage — DDL, upsert, delete, similarity search, and\n * ANN index lifecycle — and advertises `strategy.capabilities` as\n * `capabilities.vector`. Pass a custom strategy to swap the entire\n * vector stack for an alternate Postgres extension without forking\n * TypeGraph.\n *\n * Pass `false` to disable vector support entirely. The backend then\n * advertises no `capabilities.vector` and omits the embedding/search\n * methods, mirroring a SQLite connection without sqlite-vec. Required\n * for an in-process Postgres (e.g. PGlite) built without the pgvector\n * extension: the default `pgvectorStrategy` assumes `vector(N)` exists,\n * so any embedding write or `CREATE EXTENSION vector` would otherwise\n * hard-fail at runtime.\n */\n vector?: VectorStrategy | false;\n /**\n * Override specific backend capabilities. Useful when the underlying\n * driver doesn't support a feature TypeGraph would otherwise assume —\n * for example, an HTTP-only Postgres driver that can't hold a session\n * across statements would need `{ transactions: false }` so\n * TypeGraph falls through to non-transactional execution paths.\n *\n * `drizzle-orm/neon-http` is auto-detected and has `transactions`\n * disabled without an explicit override; this option exists for\n * other HTTP-style drivers and for tests that need to simulate a\n * capability gap.\n */\n capabilities?: Partial<BackendCapabilities>;\n /**\n * Use server-side prepared statements (named statements cached per\n * pg connection) on the node-postgres / neon-serverless fast path.\n * Defaults to `true`. Set to `false` when pooling through pgbouncer\n * in transaction-pool mode — pgbouncer routes successive statements\n * over different backend connections, and a `name` registered on one\n * is invisible on the next.\n *\n * No effect on `drizzle-orm/postgres-js` (handles preparation\n * internally) or `drizzle-orm/neon-http` (no fast path).\n */\n prepareStatements?: boolean;\n /**\n * Cap on the number of distinct SQL strings tracked for\n * prepared-statement naming. Defaults to 256. The cache is LRU-\n * bounded so high-cardinality SQL text (variable-length IN-lists,\n * generated aliases, `backend.execute()` calls with one-off SQL)\n * doesn't grow unbounded in either the Node process or in\n * PostgreSQL's per-session prepared-statement memory. Worst-case\n * server-side footprint is roughly `cap × pool size` statements\n * across all pooled connections. Ignored when\n * `prepareStatements` is `false`.\n */\n preparedStatementCacheMax?: number;\n}>;\n\nconst NODE_INSERT_PARAM_COUNT = 9;\nconst EDGE_INSERT_PARAM_COUNT = 12;\nconst POSTGRES_NODE_INSERT_BATCH_SIZE = Math.max(\n 1,\n Math.floor(POSTGRES_MAX_BIND_PARAMETERS / NODE_INSERT_PARAM_COUNT),\n);\nconst POSTGRES_EDGE_INSERT_BATCH_SIZE = Math.max(\n 1,\n Math.floor(POSTGRES_MAX_BIND_PARAMETERS / EDGE_INSERT_PARAM_COUNT),\n);\nconst POSTGRES_GET_NODES_ID_CHUNK_SIZE = Math.max(\n 1,\n POSTGRES_MAX_BIND_PARAMETERS - 2,\n);\nconst POSTGRES_GET_EDGES_ID_CHUNK_SIZE = Math.max(\n 1,\n POSTGRES_MAX_BIND_PARAMETERS - 1,\n);\nconst FULLTEXT_UPSERT_PARAM_COUNT = 6;\nconst FULLTEXT_DELETE_FIXED_PARAM_COUNT = 2;\nconst POSTGRES_FULLTEXT_UPSERT_BATCH_SIZE = Math.max(\n 1,\n Math.floor(POSTGRES_MAX_BIND_PARAMETERS / FULLTEXT_UPSERT_PARAM_COUNT),\n);\nconst POSTGRES_FULLTEXT_DELETE_CHUNK_SIZE = Math.max(\n 1,\n POSTGRES_MAX_BIND_PARAMETERS - FULLTEXT_DELETE_FIXED_PARAM_COUNT,\n);\nconst CHECK_UNIQUE_BATCH_FIXED_PARAM_COUNT = 3;\nconst POSTGRES_CHECK_UNIQUE_BATCH_CHUNK_SIZE = Math.max(\n 1,\n POSTGRES_MAX_BIND_PARAMETERS - CHECK_UNIQUE_BATCH_FIXED_PARAM_COUNT,\n);\nconst UNIQUE_INSERT_PARAM_COUNT = 6;\nconst POSTGRES_UNIQUE_INSERT_BATCH_SIZE = Math.max(\n 1,\n Math.floor(POSTGRES_MAX_BIND_PARAMETERS / UNIQUE_INSERT_PARAM_COUNT),\n);\n\n// ============================================================\n// Utilities\n// ============================================================\n\nconst toNodeRow = createNodeRowMapper(POSTGRES_ROW_MAPPER_CONFIG);\nconst toEdgeRow = createEdgeRowMapper(POSTGRES_ROW_MAPPER_CONFIG);\nconst toUniqueRow = createUniqueRowMapper(POSTGRES_ROW_MAPPER_CONFIG);\nconst toSchemaVersionRow = createSchemaVersionRowMapper(\n POSTGRES_ROW_MAPPER_CONFIG,\n);\n\nfunction buildPostgresCapabilities(\n fulltextStrategy: FulltextStrategy,\n vectorStrategy: VectorStrategy | undefined,\n): BackendCapabilities {\n return {\n ...POSTGRES_CAPABILITIES,\n ...(vectorStrategy === undefined ?\n {}\n : { vector: buildVectorCapabilities(vectorStrategy) }),\n fulltext: buildFulltextCapabilities(fulltextStrategy),\n };\n}\n\n// ============================================================\n// Backend Factory\n// ============================================================\n\n/**\n * Creates a TypeGraph backend for PostgreSQL databases.\n *\n * Works with any Drizzle PostgreSQL instance regardless of the underlying driver.\n *\n * @param db - A Drizzle PostgreSQL database instance\n * @param options - Backend configuration\n * @returns A GraphBackend implementation\n */\nexport function createPostgresBackend(\n db: AnyPgDatabase,\n options: PostgresBackendOptions = {},\n): AdapterBackend<AnyPgTransaction> {\n const tables = options.tables ?? defaultTables;\n const fulltextStrategy = options.fulltext ?? tsvectorStrategy;\n // pgvector is compiled into a standalone Postgres server, so it is wired\n // unconditionally by default (overridable for alternate Postgres vector\n // stacks). `vector: false` disables it — required for an in-process\n // Postgres (PGlite) built without the pgvector extension, where the\n // default strategy's `vector(N)` DDL would hard-fail.\n const vectorStrategy =\n options.vector === false ? undefined : (options.vector ?? pgvectorStrategy);\n // One probe per backend instance, shared with every transaction-scoped\n // backend so the pgvector version check runs — and its pre-0.8 warning\n // fires — at most once per backend, not once per `store.transaction()`.\n const iterativeScanProbe = createIterativeScanProbe();\n const baseCapabilities = buildPostgresCapabilities(\n fulltextStrategy,\n vectorStrategy,\n );\n // HTTP-only drivers (notably `drizzle-orm/neon-http`) can't hold a\n // session across statements, so multi-statement transactions are\n // unavailable regardless of what we declare. Auto-detect and downgrade\n // the capability so callers get correct fallback behavior without\n // having to remember to override it themselves.\n const httpOnlyOverrides =\n isNeonHttpClient(db) ?\n {\n transactions: false,\n graphAnalytics: {\n ...(baseCapabilities.graphAnalytics ?? { mathFunctions: true }),\n supported: false,\n },\n }\n : {};\n const capabilities = normalizeGraphAnalyticsCapabilities({\n ...baseCapabilities,\n ...httpOnlyOverrides,\n ...options.capabilities,\n });\n const adapterOptions: PostgresExecutionAdapterOptions = {\n ...(options.prepareStatements === undefined ?\n {}\n : { prepareStatements: options.prepareStatements }),\n ...(options.preparedStatementCacheMax === undefined ?\n {}\n : { preparedStatementCacheMax: options.preparedStatementCacheMax }),\n };\n const executionAdapter = createPostgresExecutionAdapter(db, adapterOptions);\n const tableNames: ResolvedSqlTableNames = {\n nodes: getTableName(tables.nodes),\n edges: getTableName(tables.edges),\n recordedNodes: getTableName(tables.recordedNodes),\n recordedEdges: getTableName(tables.recordedEdges),\n recordedClock: getTableName(tables.recordedClock),\n revisionOrigins: getTableName(tables.revisionOrigins),\n fulltext: tables.fulltextTableName,\n uniques: getTableName(tables.uniques),\n };\n // Pre-quote identifiers so refreshStatistics() doesn't rebuild the\n // ANALYZE statements on every call. The recorded relations are ANALYZEd\n // separately under an existence guard (see refreshStatistics): a schema\n // created before recorded-time history landed (bring-your-own-pool, no DDL\n // re-run) has no recorded tables, and Postgres fails the whole ANALYZE if any\n // named relation is missing. Per-field vector tables are created lazily and\n // live outside this base set, so they are not ANALYZEd here.\n //\n // ONE statement per table with SKIP_LOCKED, never `ANALYZE a, b, c`:\n // ANALYZE takes a ShareUpdateExclusive lock, the same class CREATE INDEX\n // CONCURRENTLY holds for its whole build — and a CIC in another session\n // waits on every regular transaction's snapshot, ANALYZE's included. An\n // ANALYZE that queues on a CIC's table lock while that CIC waits on the\n // ANALYZE's snapshot is a two-node deadlock (observed when two\n // materializeIndexes callers race). SKIP_LOCKED makes ANALYZE skip a\n // locked table instead of queuing, so it can never join a wait cycle;\n // a skipped table is covered by the next refresh or autovacuum.\n const coreAnalyzeStatements = [\n tableNames.nodes,\n tableNames.edges,\n getTableName(tables.uniques),\n tableNames.fulltext,\n ].map((name) =>\n toDrizzleSql(\n portableSql`ANALYZE (SKIP_LOCKED) ${portableSql.identifier(name)}`,\n \"postgres\",\n ),\n );\n const recordedAnalyzeTables = [\n tableNames.recordedNodes,\n tableNames.recordedEdges,\n tableNames.recordedClock,\n ] as const;\n const operationStrategy = createPostgresOperationStrategy(\n tables,\n fulltextStrategy,\n );\n\n // Whether `tableName` currently exists, via the same catalog probe `clear()`\n // uses — so refreshStatistics() never ANALYZEs a recorded relation that a\n // bring-your-own-pool schema has not yet created. The Postgres probe is\n // search_path-aware, so positive results are deliberately not cached by bare\n // table name.\n const recordedTableExists = createCachedTableExistence(\n async (tableName) => {\n const rows = await executionAdapter.execute<Record<string, unknown>>(\n operationStrategy.buildTableExists(tableName),\n );\n return rows[0];\n },\n { cacheExisting: false },\n );\n\n // Durable fulltext + vector materialization (#135): the dialect-specific\n // marker-table primitives. Orchestration (materialize / assert /\n // per-instance cache) lives once in `createContributionMaterializer`,\n // shared by the outer backend and every transaction-scoped backend so a\n // slot's marker is resolved at most once per process. Built before\n // `operations` so the operation backend's vector methods can assert/\n // ensure through it instead of issuing DDL on the hot path.\n const matTable = tables.contributionMaterializations;\n\n async function ensureContributionMaterializationsTableImpl(): Promise<void> {\n await db.execute(sql.raw(generatePgCreateTableSQL(matTable)));\n }\n\n async function getContributionMaterializationRow(\n identity: ContributionMaterializationIdentity,\n ): Promise<ContributionMaterializationRow | undefined> {\n const rows = await db\n .select()\n .from(matTable)\n .where(\n and(\n eq(matTable.graphId, identity.graphId),\n eq(matTable.logicalName, identity.logicalName),\n eq(matTable.owner, identity.owner),\n eq(matTable.tableName, identity.tableName),\n ),\n );\n const row = rows[0];\n if (row === undefined) return undefined;\n return mapContributionMaterializationRow(\n row,\n POSTGRES_CONTRIBUTION_MAT_TIMESTAMPS.decode,\n );\n }\n\n async function getContributionMaterializationRows(\n graphId: string,\n ): Promise<readonly ContributionMaterializationRow[]> {\n const rows = await db\n .select()\n .from(matTable)\n .where(eq(matTable.graphId, graphId));\n return rows.map((row) =>\n mapContributionMaterializationRow(\n row,\n POSTGRES_CONTRIBUTION_MAT_TIMESTAMPS.decode,\n ),\n );\n }\n\n async function recordContributionMaterializationRow(\n params: RecordContributionMaterializationParams,\n ): Promise<void> {\n await db\n .insert(matTable)\n .values(\n buildContributionInsertValues(\n params,\n POSTGRES_CONTRIBUTION_MAT_TIMESTAMPS.encode,\n ),\n )\n .onConflictDoUpdate({\n target: [\n matTable.graphId,\n matTable.logicalName,\n matTable.owner,\n matTable.tableName,\n ],\n set: buildContributionOnConflictSet(\n matTable.materializedAt,\n params.materializedAt,\n ),\n });\n }\n\n async function deleteContributionMaterializationRow(\n identity: ContributionMaterializationIdentity,\n ): Promise<void> {\n await db\n .delete(matTable)\n .where(\n and(\n eq(matTable.graphId, identity.graphId),\n eq(matTable.logicalName, identity.logicalName),\n eq(matTable.owner, identity.owner),\n eq(matTable.tableName, identity.tableName),\n ),\n );\n }\n\n const contributionMaterializer = createContributionMaterializer({\n dialect: \"postgres\",\n fulltextStrategy,\n fulltextTableName: tables.fulltextTableName,\n vectorStrategy,\n execDdl: async (statement) => {\n await db.execute(sql.raw(statement));\n },\n ensureMarkerTable: ensureContributionMaterializationsTableImpl,\n getMarkers: getContributionMaterializationRows,\n recordMarker: recordContributionMaterializationRow,\n deleteMarker: deleteContributionMaterializationRow,\n });\n\n const operations = createPostgresOperationBackend({\n db,\n executionAdapter,\n adapterOptions,\n operationStrategy,\n tableNames,\n capabilities,\n fulltextStrategy,\n vectorStrategy,\n contributionMaterializer,\n iterativeScanProbe,\n });\n\n /**\n * Runs `fn` inside a Postgres transaction, holding an\n * `pg_advisory_xact_lock` keyed on the graph id. The advisory lock\n * serializes all schema commits per-graph: the read-then-write CAS in\n * `commitSchemaVersion` is safe even for the initial-commit case\n * where there is no row yet to `SELECT ... FOR UPDATE`.\n *\n * Refuses on backends that don't support transactions\n * (`drizzle-orm/neon-http`). The orphan-row crash window cannot be\n * eliminated without atomicity, so silent best-effort degradation is\n * worse than a typed error.\n */\n function runSchemaWriteTransaction<T>(\n graphId: string,\n fn: (tx: CommonOperationBackend) => Promise<T>,\n ): Promise<T> {\n if (!capabilities.transactions) {\n throw new ConfigurationError(\n \"commitSchemaVersion and setActiveVersion require atomic transactions, \" +\n \"but this Postgres backend does not provide them. The drizzle-orm/neon-http \" +\n \"driver communicates over HTTP and cannot hold a session across statements; \" +\n \"use drizzle-orm/neon-serverless (websocket) for transactional writes.\",\n {\n backend: \"postgres\",\n capability: \"transactions\",\n supportsTransactions: false,\n },\n );\n }\n\n return db.transaction(async (tx) => {\n // Advisory lock: hashtext($graphId) is collision-tolerant for the\n // size of an active graph set; collisions just serialize unrelated\n // graphs which is harmless. Held until the transaction commits.\n await tx.execute(sql`SELECT pg_advisory_xact_lock(hashtext(${graphId}))`);\n // Advisory lock is held here, so the schema-write-capable\n // InternalOperationBackend is used intentionally (see its type).\n const { backend: txBackend, drainAndClose } = createTransactionBackend({\n db: tx,\n adapterOptions,\n operationStrategy,\n tableNames,\n capabilities,\n fulltextStrategy,\n vectorStrategy,\n contributionMaterializer,\n iterativeScanProbe,\n });\n try {\n return await fn(txBackend);\n } finally {\n await drainAndClose();\n }\n });\n }\n\n // Shared by `transaction()` (TypeGraph opens the tx) and\n // `adoptTransaction()` (#134 — the caller already opened it): bind a\n // tx-scoped backend to the *literal* `tx` client and gate fulltext on\n // the durable marker (a cached SELECT, never DDL).\n function bindTransactionBackend(tx: AnyPgTransaction): Readonly<{\n backend: TransactionBackend;\n drainAndClose: () => Promise<void>;\n }> {\n const { backend, drainAndClose } = createTransactionBackend({\n db: tx,\n adapterOptions,\n operationStrategy,\n tableNames,\n capabilities,\n fulltextStrategy,\n vectorStrategy,\n contributionMaterializer,\n iterativeScanProbe,\n });\n return {\n backend: gateFulltext(\n backend,\n contributionMaterializer.assertInitialized,\n ),\n drainAndClose,\n };\n }\n\n const backend: AdapterBackend<AnyPgTransaction> = {\n ...operations,\n\n ...((\n capabilities.transactions &&\n executionAdapter.executeCompiled !== undefined\n ) ?\n {\n async trustedImport<T>(\n fn: (session: TrustedImportSession) => Promise<T>,\n ): Promise<T> {\n return backend.transactionWithNative(async (tx, rawSql) => {\n const trustedExecutionAdapter = createPostgresExecutionAdapter(\n rawSql,\n { ...adapterOptions, useTransactionClient: true },\n );\n const executeCompiled = trustedExecutionAdapter.executeCompiled;\n if (executeCompiled === undefined) {\n throw new ConfigurationError(\n \"Trusted import could not bind raw execution to the PostgreSQL transaction.\",\n { capability: \"trustedImport\", dialect: \"postgres\" },\n );\n }\n const trustedTx = createBackendOverlay(tx, {\n executeRaw<T>(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<readonly T[]> {\n return executeCompiled<T>({ params, sql: sqlText });\n },\n });\n await lockPostgresTrustedImportTables(trustedTx, tableNames);\n await assertTrustedImportDatabaseEmpty(trustedTx, tableNames);\n const indexDefinitions = await suspendPostgresSecondaryIndexes(\n trustedTx,\n tableNames,\n );\n const result = await fn(\n createPostgresTrustedImportSession(trustedTx, tableNames),\n );\n await restoreSecondaryIndexes(trustedTx, indexDefinitions);\n await analyzeImportedTables(trustedTx, tableNames);\n return result;\n });\n },\n }\n : {}),\n\n async bootstrapTables(): Promise<void> {\n const statements = generatePostgresDDL(tables, fulltextStrategy);\n for (const statement of statements) {\n await db.execute(sql.raw(statement));\n }\n },\n\n async ensureRevisionOriginsTable(): Promise<void> {\n await db.execute(\n sql.raw(generatePgCreateTableSQL(tables.revisionOrigins)),\n );\n },\n\n // Every fulltext-touching method asserts the durable marker instead\n // of lazily emitting DDL. Steady state performs zero ensure; an\n // uninitialized database throws `StoreNotInitializedError` loudly\n // rather than self-healing on a read/write path (#135). Shared\n // verbatim with the tx-scoped gate via `gateFulltextMethods`.\n ...gateFulltextMethods(\n operations,\n contributionMaterializer.assertInitialized,\n ),\n\n async executeDdl(ddl: string): Promise<void> {\n await db.execute(sql.raw(ddl));\n },\n\n async ensureIndexMaterializationsTable(): Promise<void> {\n await db.execute(\n sql.raw(generatePgCreateTableSQL(tables.indexMaterializations)),\n );\n // Deployments created before the build-claim columns existed get\n // them additively; fresh installs already have them from the\n // CREATE TABLE above.\n const tableName = getTableName(tables.indexMaterializations);\n await db.execute(\n sql.raw(\n `ALTER TABLE \"${tableName}\" ADD COLUMN IF NOT EXISTS \"building_since\" timestamptz;`,\n ),\n );\n await db.execute(\n sql.raw(\n `ALTER TABLE \"${tableName}\" ADD COLUMN IF NOT EXISTS \"claim_token\" text;`,\n ),\n );\n },\n\n async claimIndexMaterialization(\n params: ClaimIndexMaterializationParams,\n ): Promise<boolean> {\n const t = tables.indexMaterializations;\n // Atomic claim: insert a fresh claim row, or take over an existing\n // row only when no live claim is on it (NULL or lease-expired\n // building_since). The WHERE on the conflict update makes losing\n // racers see zero returned rows — the row's own atomicity is the\n // mutex, so this works identically through pools and across\n // processes (unlike session advisory locks, which pin a\n // connection).\n const rows = await db.execute(sql`\n INSERT INTO ${t} (\n \"index_name\", \"graph_id\", \"entity\", \"kind\", \"signature\",\n \"schema_version\", \"last_attempted_at\", \"building_since\",\n \"claim_token\"\n )\n VALUES (\n ${params.indexName}, ${params.graphId}, ${params.entity},\n ${params.kind}, ${params.signature}, ${params.schemaVersion},\n now(), now(), ${params.token}\n )\n ON CONFLICT (\"index_name\") DO UPDATE SET\n \"building_since\" = now(),\n \"claim_token\" = EXCLUDED.\"claim_token\"\n WHERE ${t}.\"building_since\" IS NULL\n OR ${t}.\"building_since\" < now() - (${params.leaseMs} * interval '1 millisecond')\n RETURNING \"index_name\"\n `);\n const result = rows;\n const returned =\n Array.isArray(result) ? result : (\n ((result as Readonly<{ rows?: readonly unknown[] }>).rows ?? [])\n );\n return returned.length > 0;\n },\n\n async releaseIndexMaterializationClaim(\n params: ReleaseIndexMaterializationClaimParams,\n ): Promise<void> {\n const t = tables.indexMaterializations;\n // Token-guarded: a lease-expired claim taken over by another\n // materializer must not be released by the original holder.\n await db.execute(sql`\n UPDATE ${t}\n SET \"building_since\" = NULL, \"claim_token\" = NULL\n WHERE \"index_name\" = ${params.indexName}\n AND \"claim_token\" = ${params.token}\n `);\n },\n\n async getIndexMaterialization(\n indexName: string,\n ): Promise<IndexMaterializationRow | undefined> {\n const t = tables.indexMaterializations;\n const rows = await db.select().from(t).where(eq(t.indexName, indexName));\n const row = rows[0];\n if (row === undefined) return undefined;\n return mapMaterializationRow(row, POSTGRES_INDEX_MAT_TIMESTAMPS.decode);\n },\n\n async getIndexMaterializations(\n statusKeys: readonly string[],\n ): Promise<readonly IndexMaterializationRow[]> {\n if (statusKeys.length === 0) return [];\n const t = tables.indexMaterializations;\n const rows = await db\n .select()\n .from(t)\n .where(inArray(t.indexName, [...statusKeys]));\n return rows.map((row) =>\n mapMaterializationRow(row, POSTGRES_INDEX_MAT_TIMESTAMPS.decode),\n );\n },\n\n async recordIndexMaterialization(\n params: RecordIndexMaterializationParams,\n ): Promise<void> {\n const t = tables.indexMaterializations;\n await db\n .insert(t)\n .values(\n buildMaterializationInsertValues(\n params,\n POSTGRES_INDEX_MAT_TIMESTAMPS.encode,\n ),\n )\n .onConflictDoUpdate({\n target: t.indexName,\n set: buildMaterializationOnConflictSet(params.materializedAt),\n });\n },\n\n async ensureContributionMaterializationsTable(): Promise<void> {\n await ensureContributionMaterializationsTableImpl();\n },\n\n async getContributionMaterialization(\n identity: ContributionMaterializationIdentity,\n ): Promise<ContributionMaterializationRow | undefined> {\n return getContributionMaterializationRow(identity);\n },\n\n async recordContributionMaterialization(\n params: RecordContributionMaterializationParams,\n ): Promise<void> {\n await recordContributionMaterializationRow(params);\n },\n\n async assertRuntimeContributionsInitialized(\n graphId: string,\n ): Promise<void> {\n await contributionMaterializer.assertInitialized(graphId);\n },\n\n async ensureKindRemovalsTable(): Promise<void> {\n await db.execute(sql.raw(generatePgCreateTableSQL(tables.kindRemovals)));\n },\n\n async getPendingKindRemovals(\n graphId: string,\n ): Promise<readonly KindRemovalRow[]> {\n const t = tables.kindRemovals;\n const rows = await db\n .select()\n .from(t)\n .where(and(eq(t.graphId, graphId), isNull(t.removedAt)));\n return rows.map((row) =>\n mapKindRemovalRow(row, POSTGRES_KIND_REMOVAL_TIMESTAMPS.decode),\n );\n },\n\n async getAllKindRemovals(\n graphId: string,\n ): Promise<readonly KindRemovalRow[]> {\n const t = tables.kindRemovals;\n const rows = await db.select().from(t).where(eq(t.graphId, graphId));\n return rows.map((row) =>\n mapKindRemovalRow(row, POSTGRES_KIND_REMOVAL_TIMESTAMPS.decode),\n );\n },\n\n async recordKindRemoval(params: RecordKindRemovalParams): Promise<void> {\n const t = tables.kindRemovals;\n await db\n .insert(t)\n .values(\n buildKindRemovalInsertValues(\n params,\n POSTGRES_KIND_REMOVAL_TIMESTAMPS.encode,\n ),\n )\n .onConflictDoUpdate({\n target: [t.graphId, t.kindName, t.entity, t.schemaVersion],\n set: buildKindRemovalOnConflictSet(t.removedAt, params.removedAt),\n });\n },\n\n async ensureReconciliationMarkersTable(): Promise<void> {\n await db.execute(\n sql.raw(generatePgCreateTableSQL(tables.reconciliationMarkers)),\n );\n },\n\n async ensureRuntimeContributions(graphId: string): Promise<void> {\n await contributionMaterializer.ensureRuntimeContributions(graphId);\n },\n\n /**\n * Superseded by `ensureRuntimeContributions(graphId)` (#129).\n * Retained as a thin back-compat wrapper for callers predating\n * #129; #135 routed it through the durable-marker writer.\n */\n async ensureFulltextTable(graphId: string): Promise<void> {\n await contributionMaterializer.ensureRuntimeContributions(graphId);\n },\n\n // Vector counterparts of the runtime-contribution methods. Present\n // only when a vector strategy is wired (omitted under `vector: false`,\n // mirroring the embedding/search methods), so a no-vector backend\n // doesn't advertise vector materialization it can't perform.\n ...(vectorStrategy === undefined ?\n {}\n : {\n async ensureVectorSlotContribution(\n slot: VectorSlot,\n options_?: Readonly<{ force?: boolean; onDrift?: \"throw\" | \"skip\" }>,\n ): Promise<void> {\n await contributionMaterializer.ensureVectorSlot(slot, options_);\n },\n\n async ensureVectorSlotContributions(\n slots: readonly VectorSlot[],\n options_?: Readonly<{ force?: boolean; onDrift?: \"throw\" | \"skip\" }>,\n ): Promise<void> {\n await contributionMaterializer.ensureVectorSlots(slots, options_);\n },\n\n async assertVectorSlotInitialized(slot: VectorSlot): Promise<void> {\n await contributionMaterializer.assertVectorSlot(slot);\n },\n\n async assertVectorSlotsInitialized(\n slots: readonly VectorSlot[],\n ): Promise<void> {\n await contributionMaterializer.assertVectorSlots(slots);\n },\n\n async deleteVectorSlotContribution(slot: VectorSlot): Promise<void> {\n await contributionMaterializer.dropVectorSlot(slot);\n },\n }),\n\n async getReconciliationMarker(\n graphId: string,\n ): Promise<number | undefined> {\n const t = tables.reconciliationMarkers;\n const rows = await db.select().from(t).where(eq(t.graphId, graphId));\n return rows[0]?.reconciledToVersion;\n },\n\n async setReconciliationMarker(\n graphId: string,\n version: number,\n ): Promise<void> {\n const t = tables.reconciliationMarkers;\n await db\n .insert(t)\n .values({ graphId, reconciledToVersion: version })\n .onConflictDoUpdate({\n target: t.graphId,\n set: { reconciledToVersion: version },\n });\n },\n\n async refreshStatistics(): Promise<void> {\n // Scoped to TypeGraph-managed tables only — we don't touch\n // unrelated tables in the same database. Without fresh stats\n // after a bulk load the planner can pick a reverse-index scan\n // with a filter (5ms forward traversal instead of 0.5ms) until\n // autovacuum catches up. Sequential per-table statements — see\n // coreAnalyzeStatements for why they are never combined.\n for (const statement of coreAnalyzeStatements) {\n await db.execute(statement);\n }\n // The recorded relations may be absent on a schema created before\n // recorded-time history landed (bring-your-own-pool, no DDL re-run).\n // Postgres fails an ANALYZE naming a missing relation, so ANALYZE\n // only the recorded tables that exist.\n const tablePresence = await Promise.all(\n recordedAnalyzeTables.map(async (tableName) => ({\n tableName,\n exists: await recordedTableExists(tableName),\n })),\n );\n const presentRecordedTables = tablePresence\n .filter((entry) => entry.exists)\n .map((entry) => entry.tableName);\n for (const tableName of presentRecordedTables) {\n await db.execute(\n toDrizzleSql(\n portableSql`ANALYZE (SKIP_LOCKED) ${portableSql.identifier(tableName)}`,\n \"postgres\",\n ),\n );\n }\n },\n\n async commitSchemaVersion(\n params: CommitSchemaVersionParams,\n ): Promise<SchemaVersionRow> {\n return runSchemaWriteTransaction(params.graphId, (target) =>\n target.commitSchemaVersion(params),\n );\n },\n\n async setActiveVersion(params: SetActiveVersionParams): Promise<void> {\n await runSchemaWriteTransaction(params.graphId, (target) =>\n target.setActiveVersion(params),\n );\n },\n\n async transaction<T>(\n fn: (tx: TransactionBackend) => Promise<T>,\n options?: InternalTransactionOptions,\n ): Promise<T> {\n return backend.transactionWithNative((tx) => fn(tx), options);\n },\n\n async transactionWithNative<T>(\n fn: (tx: TransactionBackend, sql: AnyPgTransaction) => Promise<T>,\n options?: InternalTransactionOptions,\n ): Promise<T> {\n // #134/#135: NO DDL or ensure here. The tx-scoped backend's\n // fulltext-touching methods assert the durable contribution\n // marker (one cached SELECT — never DDL) at point of use, exactly\n // like the non-tx wrappers. A transaction that never touches\n // fulltext never asserts; one that does runs pure DML against an\n // already-materialized table, with the \"no DDL in the business\n // transaction\" guarantee backed by the durable fact.\n const temporaryWrites =\n options?.temporaryWrites === INTERNAL_TEMPORARY_WRITES;\n if (temporaryWrites && options.accessMode !== \"read_only\") {\n throw new ConfigurationError(\n \"Temporary-write transactions must be semantically read-only.\",\n { dialect: \"postgres\" },\n );\n }\n const txConfig =\n (\n options?.isolationLevel !== undefined ||\n options?.accessMode !== undefined ||\n temporaryWrites\n ) ?\n {\n ...(options.isolationLevel === undefined ?\n {}\n : {\n isolationLevel: options.isolationLevel.replace(\"_\", \" \") as\n | \"read uncommitted\"\n | \"read committed\"\n | \"repeatable read\"\n | \"serializable\",\n }),\n ...(options.accessMode === undefined && !temporaryWrites ?\n {}\n : {\n accessMode:\n temporaryWrites ?\n (\"read write\" as const)\n : (requireDefined(options.accessMode).replace(\"_\", \" \") as\n \"read only\" | \"read write\"),\n }),\n }\n : undefined;\n\n return db.transaction(async (tx) => {\n const { backend: txBackend, drainAndClose } =\n bindTransactionBackend(tx);\n try {\n return await fn(txBackend, tx);\n } finally {\n // Drizzle emits COMMIT / ROLLBACK on this same pinned connection the\n // instant the callback settles, and those control statements do not\n // travel through the backend's statement queue. Wait for whatever is\n // on the wire, and refuse anything the callback left running — a\n // `Promise.all` that rejects orphans its siblings, whose statements\n // would otherwise overlap the ROLLBACK and then land on a connection\n // the pool had already handed to somebody else.\n await drainAndClose();\n }\n }, txConfig);\n },\n\n adoptTransaction(externalTx: AnyPgTransaction): TransactionBackend {\n // #134: cross-store atomicity is unsafe without real rollback —\n // the caller's relational write on `externalTx` *would* still\n // commit even though the graph write could not be undone. Refuse\n // loudly rather than silently degrade.\n if (!capabilities.transactions) {\n throw new ConfigurationError(\n \"Cross-store atomicity is unavailable on this Postgres backend: \" +\n \"its driver does not support transactions (drizzle-orm/neon-http, \" +\n \"Cloudflare D1). Adopting an external transaction here would let \" +\n \"the caller's relational write commit with no way to roll back \" +\n \"the graph write. Use a node-postgres or neon-serverless \" +\n \"(Pool/WebSocket) connection for cross-store transactions.\",\n {\n backend: \"postgres\",\n capability: \"transactions\",\n supportsTransactions: false,\n },\n );\n }\n assertAdoptedDialect<AnyPgTransaction>(\n externalTx,\n PgTransaction,\n \"postgres\",\n );\n // The caller owns BEGIN/COMMIT/ROLLBACK via its own\n // `db.transaction(...)`. We adopt the literal `tx` client and run\n // pure DML on it — no transaction is opened or closed here, and no\n // DDL is emitted inside the caller's business transaction.\n //\n // Statements still serialize onto the pinned connection, but the queue\n // is never closed: only the caller knows when their transaction ends,\n // so it is on them to await every graph write before committing.\n return bindTransactionBackend(externalTx).backend;\n },\n\n async close(): Promise<void> {\n // Drizzle doesn't expose a close method\n // Users manage connection lifecycle themselves\n },\n };\n\n return backend;\n}\n\n/**\n * Memoized \"does this server's pgvector support the iterative scan (>= 0.8)?\"\n * probe, plus a one-shot warning when it does not.\n *\n * Created once per {@link createPostgresBackend} and shared with every\n * transaction-scoped operation backend, so the probe query runs once and the\n * pre-0.8 warning fires once per backend instance rather than once per\n * `store.transaction()`. The answer is connection-independent\n * (`pg_extension.extversion`), so caching it across connections is sound.\n */\nexport type IterativeScanProbe = Readonly<{\n isSupported: (\n execAll: <T>(query: SQL) => Promise<readonly T[]>,\n ) => Promise<boolean>;\n}>;\n\n/**\n * Exported for unit testing the memoization / warn-once behavior in isolation;\n * production code reaches it only through {@link createPostgresBackend}.\n */\nexport function createIterativeScanProbe(): IterativeScanProbe {\n let probe: Promise<boolean> | undefined;\n let warned = false;\n\n function warnUnavailable(version: string): void {\n if (warned) return;\n warned = true;\n if (typeof console === \"undefined\" || typeof console.warn !== \"function\") {\n return;\n }\n console.warn(\n `[typegraph] pgvector ${version} has no iterative scan (added in 0.8), ` +\n \"so a filtered approximate vector search stays ef_search-bounded and \" +\n \"can return fewer rows than `limit` while more matches exist. Upgrade \" +\n \"pgvector to >= 0.8, or use an exact search (`approximate: false`) \" +\n \"where a full page matters.\",\n );\n }\n\n return {\n isSupported(execAll) {\n // Probing the GUC directly is unreliable — extension GUCs register only\n // once the extension library has loaded into the session, so a fresh\n // pooled connection reports NULL even on 0.8+. `extversion` is truth.\n probe ??= (async () => {\n try {\n const [row] = await execAll<{ v: string | null }>(\n sql`SELECT extversion AS v FROM pg_extension WHERE extname = 'vector'`,\n );\n if (typeof row?.v !== \"string\") return false;\n const [major = 0, minor = 0] = row.v\n .split(\".\")\n .map((part) => Number.parseInt(part, 10));\n const supported = major > 0 || (major === 0 && minor >= 8);\n if (!supported) warnUnavailable(row.v);\n return supported;\n } catch {\n return false;\n }\n })();\n return probe;\n },\n };\n}\n\ntype CreatePostgresOperationBackendOptions = Readonly<{\n db: AnyPgDatabase;\n executionAdapter: PostgresExecutionAdapter;\n /**\n * Adapter tuning (prepared-statement cache settings). Used to bind a\n * fresh, equivalently-configured adapter to a transaction client when\n * a per-search `efSearch` override opens its own transaction.\n */\n adapterOptions?: PostgresExecutionAdapterOptions | undefined;\n operationStrategy: ReturnType<typeof createPostgresOperationStrategy>;\n tableNames: ResolvedSqlTableNames;\n capabilities: BackendCapabilities;\n fulltextStrategy: FulltextStrategy;\n /**\n * Active vector strategy (`pgvectorStrategy` unless overridden), or\n * `undefined` when vector support is disabled (`vector: false`).\n */\n vectorStrategy: VectorStrategy | undefined;\n /**\n * Shared durable-marker materializer. The vector methods assert a\n * slot's marker (SELECT, never DDL) on the hot path and `createVectorIndex`\n * ensures it (privileged) — replacing the old in-process ensure-latch.\n * Shared across the outer backend and every transaction-scoped backend\n * so a slot's marker is resolved at most once per process.\n */\n contributionMaterializer: ContributionMaterializer;\n /**\n * Shared pgvector iterative-scan probe (memoized version check + one-shot\n * pre-0.8 warning). Owned by the top-level backend and reused by every\n * transaction backend so the warning fires once per backend instance.\n */\n iterativeScanProbe: IterativeScanProbe;\n}>;\n\ntype CreatePostgresTransactionBackendOptions = Readonly<{\n db: AnyPgDatabase;\n adapterOptions?: PostgresExecutionAdapterOptions;\n operationStrategy: ReturnType<typeof createPostgresOperationStrategy>;\n tableNames: ResolvedSqlTableNames;\n capabilities: BackendCapabilities;\n fulltextStrategy: FulltextStrategy;\n /** Active vector strategy. See {@link CreatePostgresOperationBackendOptions}. */\n vectorStrategy: VectorStrategy | undefined;\n /** Shared durable-marker materializer. See {@link CreatePostgresOperationBackendOptions}. */\n contributionMaterializer: ContributionMaterializer;\n /** Shared iterative-scan probe. See {@link CreatePostgresOperationBackendOptions}. */\n iterativeScanProbe: IterativeScanProbe;\n}>;\n\nfunction createPostgresOperationBackend(\n options: CreatePostgresOperationBackendOptions,\n): InternalOperationBackend {\n const {\n db,\n executionAdapter,\n adapterOptions,\n operationStrategy,\n tableNames,\n capabilities,\n fulltextStrategy,\n vectorStrategy,\n contributionMaterializer,\n iterativeScanProbe,\n } = options;\n\n // Route through the execution adapter so driver-specific result shapes\n // (`{rows}` for node-postgres / neon-serverless; bare array for\n // postgres-js) are normalized in one place.\n async function execAll<T>(query: ExecutableSql): Promise<readonly T[]> {\n return executionAdapter.execute<T>(query);\n }\n\n async function execGet<T>(query: ExecutableSql): Promise<T | undefined> {\n const rows = await executionAdapter.execute<T>(query);\n return rows[0];\n }\n\n async function execRun(query: ExecutableSql): Promise<void> {\n await executionAdapter.execute(query);\n }\n\n type VectorSearchRow = Readonly<{ node_id: string; score: number }>;\n\n // One warning per backend instance when `efSearch` is supplied but the\n // driver can't hold a transaction to scope `SET LOCAL` to.\n let efSearchUnsupportedWarned = false;\n function warnEfSearchUnsupported(): void {\n if (efSearchUnsupportedWarned) return;\n efSearchUnsupportedWarned = true;\n if (typeof console === \"undefined\" || typeof console.warn !== \"function\") {\n return;\n }\n console.warn(\n \"[typegraph] efSearch (hnsw.ef_search override) was ignored: this \" +\n \"Postgres backend has transactions disabled (e.g. drizzle-orm/neon-http), \" +\n \"and SET LOCAL needs a transaction to scope the override. Use a \" +\n \"transactional driver (node-postgres / neon-serverless / postgres-js) \" +\n \"to apply efSearch.\",\n );\n }\n\n /** One transaction-local GUC override applied around a vector SELECT. */\n type SearchGucOverride = Readonly<{ name: string; value: string }>;\n\n // `hnsw.iterative_scan` exists on pgvector >= 0.8. The probe + \"warn once\"\n // state lives on the top-level backend and is SHARED with every\n // transaction-scoped operation backend (see `iterativeScanProbe` in the\n // options), so a pre-0.8 server is probed and warned about once per backend\n // instance — not once per `store.transaction()`.\n function pgvectorIterativeScanSupported(): Promise<boolean> {\n return iterativeScanProbe.isSupported(execAll);\n }\n\n /**\n * The transaction-local GUC overrides for one vector search:\n *\n * - `hnsw.ef_search` when the caller supplied `efSearch` (validated\n * upstream; warned-and-skipped on transactionless drivers, where\n * `SET LOCAL` cannot be scoped).\n * - `hnsw.iterative_scan = strict_order` on HNSW slots (pgvector >= 0.8):\n * the search SQL constrains results to live candidate nodes (and\n * optionally `minScore`), and a plain HNSW scan yields only `ef_search`\n * candidates BEFORE those filters — so a filter-heavy neighborhood can\n * under-fill top-k. The iterative scan keeps yielding until `LIMIT`\n * rows pass or it hits `hnsw.max_scan_tuples` — better recall, not a\n * full-page guarantee. `strict_order` preserves the distance ordering the\n * plan relies on (`relaxed_order` may emit slightly out of order beneath\n * our LIMIT). On pgvector < 0.8 the search stays `ef_search`-bounded and\n * the backend warns once (see `warnIterativeScanUnavailable`).\n * - `ivfflat.iterative_scan = relaxed_order` on IVFFlat slots (same\n * pgvector floor): IVFFlat has no strict_order mode, so the strategy's\n * IVFFlat search SQL re-sorts the relaxed candidate set inside a\n * MATERIALIZED wrapper (see `buildSearch`) to restore exact ordering.\n */\n async function vectorSearchGucOverrides(\n params: Pick<VectorSearchParams, \"efSearch\" | \"indexType\">,\n ): Promise<readonly SearchGucOverride[]> {\n const overrides: SearchGucOverride[] = [];\n if (params.efSearch !== undefined) {\n if (capabilities.transactions) {\n overrides.push({\n name: \"hnsw.ef_search\",\n value: String(params.efSearch),\n });\n } else {\n warnEfSearchUnsupported();\n }\n }\n if (\n params.indexType === \"hnsw\" &&\n capabilities.transactions &&\n (await pgvectorIterativeScanSupported())\n ) {\n overrides.push({ name: \"hnsw.iterative_scan\", value: \"strict_order\" });\n }\n if (\n params.indexType === \"ivfflat\" &&\n capabilities.transactions &&\n (await pgvectorIterativeScanSupported())\n ) {\n overrides.push({\n name: \"ivfflat.iterative_scan\",\n value: \"relaxed_order\",\n });\n }\n return overrides;\n }\n\n /**\n * Runs the vector SELECT, applying the given GUC overrides\n * transaction-locally. `SET LOCAL` semantics (via\n * `set_config(name, value, is_local => true)`, the parameterizable form)\n * only take effect inside an explicit transaction — issued in autocommit\n * they roll off with the statement and the next pooled query (notably\n * under transaction-mode pgbouncer) sees the session default again. So\n * with overrides present we bundle `BEGIN; SET …; SELECT …; COMMIT;`\n * onto one connection. With none we take the unchanged single-statement\n * fast path and open no transaction.\n */\n /**\n * The `SET LOCAL`-scoped vector SELECT, run as one exclusive group on the\n * transaction's connection. See {@link runVectorSearch}.\n */\n async function runVectorSearchGucGroup<Row>(\n overrides: readonly SearchGucOverride[],\n query: ExecutableSql,\n ): Promise<readonly Row[]> {\n const runExclusive = executionAdapter.runExclusive;\n if (runExclusive === undefined) {\n throw new CompilerInvariantError(\n \"A transaction-scoped Postgres backend must expose runExclusive; \" +\n \"its execution adapter was not wrapped by createSerialExecutionAdapter.\",\n );\n }\n return runExclusive(async (connection) => {\n const snapshots: SearchGucOverride[] = [];\n for (const override of overrides) {\n const [setting] = await connection.execute<{ v: string }>(\n sql`SELECT current_setting(${override.name}) AS v`,\n );\n if (setting !== undefined) {\n snapshots.push({ name: override.name, value: setting.v });\n }\n await connection.execute(\n sql`SELECT set_config(${override.name}, ${override.value}, true)`,\n );\n }\n const rows = await connection.execute<Row>(query);\n // Restore only on success: a failed SELECT aborts the caller's\n // transaction, so its rollback discards the overrides anyway and a\n // restore here would just fail against the aborted tx, masking the\n // real error.\n for (const snapshot of snapshots) {\n await connection.execute(\n sql`SELECT set_config(${snapshot.name}, ${snapshot.value}, true)`,\n );\n }\n return rows;\n });\n }\n\n async function runVectorSearch<Row = VectorSearchRow>(\n overrides: readonly SearchGucOverride[],\n query: ExecutableSql,\n ): Promise<readonly Row[]> {\n if (overrides.length === 0) {\n return execAll<Row>(query);\n }\n if (db instanceof PgTransaction) {\n // Already inside the caller's transaction (low-level\n // backend.transaction / adoptTransaction). `executionAdapter` is\n // bound to this tx client, but SET LOCAL persists to the end of the\n // caller's transaction — leaking the override into their later\n // vector searches and breaking the per-search contract. Snapshot\n // the current values, apply the overrides, then restore them once\n // the SELECT has materialized so the overrides stay scoped to this\n // one search.\n //\n // The four steps are ONE critical section, not four serialized\n // statements. A transaction has a single GUC namespace, so two searches\n // that merely take turns interleave as `A snapshot → B snapshot → A set\n // → B set → A select` and `A` runs under `B`'s efSearch. `runExclusive`\n // holds the connection for the whole group; it is always present on a\n // transaction-scoped adapter (see `createTransactionBackend`).\n return runVectorSearchGucGroup(overrides, query);\n }\n return db.transaction(async (tx) => {\n // Bind an equivalently-configured adapter to the tx client so the\n // SELECT keeps the driver result-shape normalization rather than a\n // bespoke execute. A Drizzle transaction carries no `$client`, so this\n // adapter routes through Drizzle's session (no server-side prepared\n // statement) — correct either way, and the statements below are\n // sequential, so they need no serializing wrapper.\n const txAdapter = createPostgresExecutionAdapter(tx, adapterOptions);\n for (const override of overrides) {\n await txAdapter.execute(\n sql`SELECT set_config(${override.name}, ${override.value}, true)`,\n );\n }\n return txAdapter.execute<Row>(query);\n });\n }\n\n const batchConfig = {\n checkUniqueBatchChunkSize: POSTGRES_CHECK_UNIQUE_BATCH_CHUNK_SIZE,\n edgeInsertBatchSize: POSTGRES_EDGE_INSERT_BATCH_SIZE,\n // Unlike the static siblings, the embedding upsert honors a runtime\n // `maxBindParameters` override so its chunk size tracks the connection's\n // actual bind budget.\n embeddingUpsertBatchSize: Math.max(\n 1,\n Math.floor(\n (capabilities.maxBindParameters ?? POSTGRES_MAX_BIND_PARAMETERS) /\n EMBEDDING_UPSERT_PARAM_COUNT,\n ),\n ),\n getEdgesChunkSize: POSTGRES_GET_EDGES_ID_CHUNK_SIZE,\n getNodesChunkSize: POSTGRES_GET_NODES_ID_CHUNK_SIZE,\n nodeInsertBatchSize: POSTGRES_NODE_INSERT_BATCH_SIZE,\n uniqueInsertBatchSize: POSTGRES_UNIQUE_INSERT_BATCH_SIZE,\n };\n\n const commonBackend = createCommonOperationBackend({\n batchConfig,\n execution: {\n execAll,\n execGet,\n execRun,\n },\n nowIso,\n operationStrategy,\n rowMappers: {\n toEdgeRow,\n toNodeRow,\n toSchemaVersionRow,\n toUniqueRow,\n },\n tableExistenceCache: { cacheExisting: false },\n });\n\n const executeCompiled = executionAdapter.executeCompiled;\n const executeRawMethod: Pick<TransactionBackend, \"executeRaw\"> =\n executeCompiled === undefined ?\n {}\n : {\n async executeRaw<T>(\n sqlText: string,\n params: readonly unknown[],\n ): Promise<readonly T[]> {\n return executeCompiled<T>({ params, sql: sqlText });\n },\n };\n\n // Embedding write/search methods are present only when a vector strategy\n // is wired. With `vector: false` (e.g. PGlite without pgvector) they are\n // omitted, so `capabilities.vector` is absent and the store never routes\n // embedding work here — mirroring a SQLite connection without sqlite-vec.\n const vectorEmbeddingMethods =\n vectorStrategy === undefined ?\n {}\n : {\n async upsertEmbedding(params: UpsertEmbeddingParams): Promise<void> {\n const slot = vectorSlotFromParams(params);\n // Assert the slot's durable marker (SELECT, cached) — never DDL.\n // The per-field table is provisioned by the privileged migrator\n // (`createStoreWithSchema` → `materializeVectorContributions`), so\n // a least-privilege runtime role writes embeddings without CREATE.\n await contributionMaterializer.assertVectorSlot(slot);\n const statements = vectorStrategy.buildUpsert(slot, params, nowIso());\n try {\n for (const statement of statements) {\n await execRun(statement);\n }\n } catch (error) {\n throw mapVectorWriteError(error, params);\n }\n },\n\n async upsertEmbeddingBatch(\n params: UpsertEmbeddingBatchParams,\n ): Promise<void> {\n if (params.rows.length === 0) return;\n const slot = vectorSlotFromParams(params);\n // Same SELECT-only marker assert as the single-row path — never DDL.\n await contributionMaterializer.assertVectorSlot(slot);\n // Last-write-wins dedupe: a multi-row upsert cannot affect one\n // row twice.\n const rowsById = new Map(\n params.rows.map((row) => [row.nodeId, row] as const),\n );\n const rows = [...rowsById.values()];\n const timestamp = nowIso();\n try {\n for (const chunk of chunkArray(\n rows,\n batchConfig.embeddingUpsertBatchSize,\n )) {\n const statements =\n vectorStrategy.buildUpsertBatch === undefined ?\n chunk.flatMap((row) =>\n vectorStrategy.buildUpsert(\n slot,\n {\n graphId: params.graphId,\n nodeKind: params.nodeKind,\n nodeId: row.nodeId,\n fieldPath: params.fieldPath,\n embedding: row.embedding,\n dimensions: params.dimensions,\n metric: params.metric,\n indexType: params.indexType,\n },\n timestamp,\n ),\n )\n : vectorStrategy.buildUpsertBatch(\n slot,\n { ...params, rows: chunk },\n timestamp,\n );\n for (const statement of statements) {\n await execRun(statement);\n }\n }\n } catch (error) {\n throw mapVectorWriteError(error, params);\n }\n },\n\n async deleteEmbedding(params: DeleteEmbeddingParams): Promise<void> {\n // Assert the slot's durable marker before deleting. A delete can\n // run before any embedding was ever written for the field (e.g. a\n // node hard-deleted having never carried one); the per-field table\n // was provisioned at boot, so the DELETE targets an existing\n // (possibly empty) table and is a clean no-op — never a DELETE\n // against a missing relation, which would abort an enclosing\n // Postgres transaction. SELECT-only assert, never DDL.\n const slot = vectorSlotFromParams(params);\n await contributionMaterializer.assertVectorSlot(slot);\n const statements = vectorStrategy.buildDelete(slot, params);\n for (const statement of statements) {\n await execRun(statement);\n }\n },\n\n async vectorSearch(\n params: VectorSearchParams,\n ): Promise<readonly VectorSearchResult[]> {\n assertVectorSearchLimit(params.limit);\n // Validate `efSearch` against pgvector's `hnsw.ef_search` ceiling\n // before `runVectorSearch` applies it via `set_config`.\n assertPgvectorEfSearch(params.efSearch);\n const slot = vectorSlotFromParams(params);\n // Deliberately NOT marker-gated: search is read-only (no DDL\n // hazard to gate), and its params carry the caller's runtime\n // metric override, which legitimately diverges from the\n // provisioned shape on strategies that bake the metric into the\n // DDL (sqlite-vec; pgvector's table DDL is metric-free but the\n // contract is kept identical across dialects). An unprovisioned\n // slot surfaces the engine's missing-relation error — the same\n // contract as a query-builder `similarTo()` predicate;\n // `createVerifiedStore` catches both at attach.\n const query = vectorStrategy.buildSearch(\n slot,\n params,\n // Store-compiled candidates (predicates + subclass + currency)\n // take precedence; the live-node default covers direct backend use.\n params.candidates ??\n buildLiveNodeCandidates(\n tableNames.nodes,\n params.graphId,\n params.nodeKind,\n nowIso(),\n ),\n );\n const gucOverrides = await vectorSearchGucOverrides(params);\n let rows: readonly { node_id: string; score: number }[];\n try {\n rows = await runVectorSearch(gucOverrides, query);\n } catch (error) {\n // A query vector whose dimension no longer matches the stored\n // column surfaces the same typed error as the write path.\n throw mapVectorWriteError(error, params);\n }\n return rows.map((row) => ({\n nodeId: row.node_id,\n score: row.score,\n }));\n },\n // Single-statement hybrid needs ROW_NUMBER(); a capability\n // profile that disables window functions keeps the store's\n // multi-statement fallback by simply not exposing the member.\n ...(capabilities.windowFunctions ?\n {\n async hybridSearch(\n params: HybridSearchParams,\n ): Promise<readonly HybridSearchRow[]> {\n assertVectorSearchLimit(params.limit);\n // Source depths get the same boundary validation the fallback\n // path applies (vectorSearch validates its limit; the fulltext\n // depth is validated inside buildFulltextSearch).\n assertVectorSearchLimit(params.vector.k);\n assertPgvectorEfSearch(params.vector.efSearch);\n const slot = vectorSlotFromParams({\n graphId: params.graphId,\n nodeKind: params.nodeKind,\n fieldPath: params.vector.fieldPath,\n dimensions: params.vector.dimensions,\n metric: params.vector.metric,\n indexType: params.vector.indexType,\n });\n // Read-only, not marker-gated — see vectorSearch above.\n const candidates =\n params.candidates ??\n buildLiveNodeCandidates(\n tableNames.nodes,\n params.graphId,\n params.nodeKind,\n nowIso(),\n );\n const vectorParams: VectorSearchParams = {\n graphId: params.graphId,\n nodeKind: params.nodeKind,\n fieldPath: params.vector.fieldPath,\n queryEmbedding: params.vector.queryEmbedding,\n metric: params.vector.metric,\n dimensions: params.vector.dimensions,\n indexType: params.vector.indexType,\n limit: params.vector.k,\n ...(params.vector.minScore === undefined ?\n {}\n : { minScore: params.vector.minScore }),\n };\n // The vector leg references the statement's shared\n // tg_hybrid_cand CTE; the actual candidates SQL is emitted\n // once by buildHybridSearch.\n const vectorSql = vectorStrategy.buildSearch(\n slot,\n vectorParams,\n portableSql.raw(\"SELECT node_id FROM tg_hybrid_cand\"),\n );\n const statement = operationStrategy.buildHybridSearch(\n { ...params, candidates },\n toDrizzleSql(vectorSql, \"postgres\"),\n params.vector.metric === \"cosine\",\n );\n const gucOverrides = await vectorSearchGucOverrides({\n indexType: params.vector.indexType,\n ...(params.vector.efSearch === undefined ?\n {}\n : { efSearch: params.vector.efSearch }),\n });\n let raw: readonly Record<string, unknown>[];\n try {\n raw = await runVectorSearch<Record<string, unknown>>(\n gucOverrides,\n statement,\n );\n } catch (error) {\n throw mapVectorWriteError(error, vectorParams);\n }\n return raw.map((row) => mapHybridSearchRow(row, toNodeRow));\n },\n }\n : {}),\n };\n\n const operationBackend: InternalOperationBackend = {\n ...commonBackend,\n ...executeRawMethod,\n ...vectorEmbeddingMethods,\n capabilities,\n fulltextStrategy,\n ...(vectorStrategy === undefined ? {} : { vectorStrategy }),\n dialect: \"postgres\",\n tableNames,\n\n // === Vector Index Operations ===\n\n async createVectorIndex(params: CreateVectorIndexParams): Promise<void> {\n if (vectorStrategy === undefined) return;\n const slot = vectorSlotFromCreateIndexParams(params);\n // Ensure the per-field table + its durable marker first (privileged,\n // idempotent), then create its ANN index. pgvector's `ownedTables`\n // builds the table only — the HNSW/IVFFlat index is created here (and\n // only here) so it picks up the declared `m`/`ef_construction`/`lists`\n // from `slot.indexParams` rather than defaults.\n await contributionMaterializer.ensureVectorSlot(slot);\n // Honor the `concurrent` flag materializeIndexes passes on Postgres so the\n // ANN build doesn't take a write-blocking lock on a live table. execRun is\n // autocommit, which CONCURRENTLY requires.\n const indexStatement = vectorStrategy.buildCreateIndex?.(slot, {\n concurrent: params.concurrent === true,\n });\n if (indexStatement !== undefined) {\n try {\n await execRun(indexStatement);\n } catch (error) {\n if (!isInsufficientResourcesError(error)) throw error;\n // Parallel HNSW/IVFFlat builds stage the build graph in dynamic\n // shared memory, and resource-constrained hosts reject the\n // allocation (SQLSTATE class 53 — e.g. containers with the 64MB\n // /dev/shm default fail a 50k x 384-dim HNSW build with 53100\n // from dsm_impl_posix). Retry serially: drop the INVALID\n // leftover the failed CONCURRENTLY build leaves behind (its\n // IF NOT EXISTS would otherwise mask the retry), pin the\n // strategy table to parallel_workers = 0 (maintenance builds\n // take min(storage parameter, max_parallel_maintenance_workers)),\n // rebuild in local memory, and restore the setting.\n const dropStatement = vectorStrategy.buildDropIndex?.(slot);\n if (dropStatement !== undefined) {\n await execRun(dropStatement);\n }\n const table = portableSql.identifier(\n vectorStrategy.tableName(\n slot.graphId,\n slot.nodeKind,\n slot.fieldPath,\n ),\n );\n await execRun(\n portableSql`ALTER TABLE ${table} SET (parallel_workers = 0)`,\n );\n try {\n await execRun(indexStatement);\n } finally {\n await execRun(\n portableSql`ALTER TABLE ${table} RESET (parallel_workers)`,\n );\n }\n }\n }\n },\n\n // === Fulltext Operations ===\n\n async upsertFulltext(params: UpsertFulltextParams): Promise<void> {\n const timestamp = nowIso();\n const statements = operationStrategy.buildUpsertFulltext(\n params,\n timestamp,\n );\n for (const stmt of statements) {\n await execRun(stmt);\n }\n },\n\n async deleteFulltext(params: DeleteFulltextParams): Promise<void> {\n const statements = operationStrategy.buildDeleteFulltext(params);\n for (const stmt of statements) {\n await execRun(stmt);\n }\n },\n\n async upsertFulltextBatch(\n params: UpsertFulltextBatchParams,\n ): Promise<void> {\n if (params.rows.length === 0) return;\n const timestamp = nowIso();\n // The strategy emits ONE statement over every row it is given, so\n // the bind budget is enforced here — same contract as node/edge\n // batch inserts.\n for (const rows of chunkArray(\n params.rows,\n POSTGRES_FULLTEXT_UPSERT_BATCH_SIZE,\n )) {\n const statements = operationStrategy.buildUpsertFulltextBatch(\n { ...params, rows },\n timestamp,\n );\n for (const stmt of statements) {\n await execRun(stmt);\n }\n }\n },\n\n async deleteFulltextBatch(\n params: DeleteFulltextBatchParams,\n ): Promise<void> {\n if (params.nodeIds.length === 0) return;\n for (const nodeIds of chunkArray(\n params.nodeIds,\n POSTGRES_FULLTEXT_DELETE_CHUNK_SIZE,\n )) {\n const statements = operationStrategy.buildDeleteFulltextBatch({\n ...params,\n nodeIds,\n });\n for (const stmt of statements) {\n await execRun(stmt);\n }\n }\n },\n\n async fulltextSearch(\n params: FulltextSearchParams,\n ): Promise<readonly FulltextSearchResult[]> {\n const query = operationStrategy.buildFulltextSearch(params);\n // pg returns `numeric` as a string to preserve precision; coerce at the\n // backend boundary so FulltextSearchResult.score is always `number`.\n const rows = await execAll<{\n node_id: string;\n score: number | string;\n snippet: string | null;\n }>(query);\n return rows.map((row, index) => ({\n nodeId: row.node_id,\n score: coerceNumericScore(row.score),\n rank: index + 1,\n ...(row.snippet === null ? {} : { snippet: row.snippet }),\n }));\n },\n\n async dropVectorIndex(params: DropVectorIndexParams): Promise<void> {\n if (vectorStrategy === undefined) return;\n const slot = vectorSlotFromDropIndexParams(params);\n const dropStatement = vectorStrategy.buildDropIndex?.(slot);\n if (dropStatement === undefined) return;\n try {\n await execRun(dropStatement);\n } catch (error) {\n // The per-field table (and thus its index) may never have been\n // materialized; treat a missing relation as already-dropped.\n if (!isMissingTableError(error)) throw error;\n }\n },\n\n // === Query Execution ===\n\n async execute<T>(query: CompiledRowsSql): Promise<readonly T[]> {\n // Statements the compiler branded as containing an ANN index scan\n // (inline `approximate: true`) get the same pgvector GUC wrapping\n // the search facade applies — most importantly\n // `hnsw.iterative_scan = strict_order`, without which a filtered\n // approximate query starves at the default ef_search frontier.\n // On pgvector < 0.8 the override list is empty and this falls\n // through to the plain fast path.\n const annTypes =\n isSqlFragment(query) ? annIndexScanTypes(query) : undefined;\n if (annTypes !== undefined && vectorStrategy !== undefined) {\n const overrides: SearchGucOverride[] = [];\n for (const indexType of annTypes) {\n if (indexType !== \"hnsw\" && indexType !== \"ivfflat\") continue;\n overrides.push(...(await vectorSearchGucOverrides({ indexType })));\n }\n return runVectorSearch<T>(overrides, query);\n }\n return executionAdapter.execute<T>(query);\n },\n\n compileSql(\n query: SqlFragment,\n ): Readonly<{ sql: string; params: readonly unknown[] }> {\n return executionAdapter.compile(query);\n },\n };\n\n return operationBackend;\n}\n\n/**\n * A transaction-scoped backend plus the hook that shuts its statement queue\n * at the transaction boundary. See {@link SerialExecutionAdapter.drainAndClose}.\n */\ntype BoundTransactionBackend = Readonly<{\n backend: InternalOperationBackend;\n drainAndClose: () => Promise<void>;\n}>;\n\nfunction createTransactionBackend(\n options: CreatePostgresTransactionBackendOptions,\n): BoundTransactionBackend {\n // Every statement this backend issues rides one pinned connection, which\n // can carry exactly one query at a time. Serialize them here rather than\n // relying on the driver's own queue: node-postgres deprecated\n // `client.query()` on a busy client in 8.22 and removes the queue in pg@9.\n // The wrap is unconditional because the overlap is created inside TypeGraph\n // (the node write pipeline syncs embeddings and fulltext concurrently), not\n // only by user code.\n const txExecutionAdapter = createSerialExecutionAdapter(\n createPostgresExecutionAdapter(options.db, options.adapterOptions),\n );\n\n // The transaction-scoped backend shares the outer backend's\n // contribution materializer: the per-field vector table is provisioned\n // (DDL) only by the privileged outer backend, so a tx-scoped vector op\n // only ASSERTS the durable marker (SELECT, never DDL) and can't poison\n // anything on rollback. The shared per-instance cache means a slot\n // confirmed once stays a pure `Set.has` inside every later transaction.\n const backend = createPostgresOperationBackend({\n db: options.db,\n executionAdapter: txExecutionAdapter,\n adapterOptions: options.adapterOptions,\n operationStrategy: options.operationStrategy,\n tableNames: options.tableNames,\n capabilities: options.capabilities,\n fulltextStrategy: options.fulltextStrategy,\n vectorStrategy: options.vectorStrategy,\n contributionMaterializer: options.contributionMaterializer,\n // The probe is process-wide truth, so the outer instance's is reused\n // rather than a fresh one per transaction.\n iterativeScanProbe: options.iterativeScanProbe,\n });\n\n return { backend, drainAndClose: txExecutionAdapter.drainAndClose };\n}\n\n// Re-export schema utilities\nexport type { PostgresTableNames, PostgresTables } from \"./schema/postgres\";\nexport { createPostgresTables, tables } from \"./schema/postgres\";\n"]}