pgexplain 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/LICENSE +21 -0
- package/README.md +338 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +3205 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +335 -0
- package/dist/index.js +2075 -0
- package/dist/index.js.map +1 -0
- package/package.json +92 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/diagnostics/diagnostic.ts","../src/diagnostics/catalog.ts","../src/config.ts","../src/core/schema.ts","../src/core/parse.ts","../src/core/metrics.ts","../src/util/format.ts","../src/advisor/rules/util.ts","../src/advisor/rules/bitmap-lossy.ts","../src/advisor/rules/cartesian-product.ts","../src/advisor/rules/correlated-subplan.ts","../src/advisor/rules/could-be-index-only.ts","../src/advisor/rules/filter-could-be-index-cond.ts","../src/advisor/rules/hash-spill-disk.ts","../src/advisor/rules/high-filter-discard.ts","../src/advisor/rules/index-only-heap-fetches.ts","../src/advisor/rules/low-cache-hit.ts","../src/advisor/rules/nested-loop-large-outer.ts","../src/advisor/rules/row-misestimate.ts","../src/advisor/rules/seq-scan-large.ts","../src/advisor/rules/significant-jit.ts","../src/advisor/rules/sort-spill-disk.ts","../src/advisor/rules/trigger-time.ts","../src/advisor/rules/workers-not-launched.ts","../src/advisor/rules/index.ts","../src/advisor/index.ts","../src/input/redact.ts","../src/report/tree.ts","../src/report/json.ts","../src/report/html.ts","../src/report/markdown.ts","../src/util/color.ts","../src/report/terminal.ts","../src/report/render.ts","../src/index.ts","../src/input/stdin.ts","../src/input/source.ts","../src/commands/emit.ts","../src/commands/analyze.ts","../src/commands/completion.ts","../src/core/diff.ts","../src/report/diff.ts","../src/commands/diff.ts","../src/util/log.ts","../src/db/version.ts","../src/db/explain.ts","../src/db/client.ts","../src/commands/run.ts","../src/diagnostics/print.ts","../src/cli.ts"],"names":["DOCS","bottlenecks","heat","text","readFile","join","writeFile","FORMATS","selectStatement"],"mappings":"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","file":"cli.js","sourcesContent":["{\n \"name\": \"pgexplain\",\n \"version\": \"0.1.0\",\n \"description\": \"Turn PostgreSQL EXPLAIN (ANALYZE) output into human-readable reports and detect plan anti-patterns — every finding tells you exactly how to fix it.\",\n \"keywords\": [\n \"postgres\",\n \"postgresql\",\n \"explain\",\n \"explain-analyze\",\n \"query-plan\",\n \"performance\",\n \"advisor\",\n \"linter\",\n \"cli\",\n \"database\"\n ],\n \"license\": \"MIT\",\n \"author\": \"\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/losefor/pg-explain\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/losefor/pg-explain/issues\"\n },\n \"homepage\": \"https://github.com/losefor/pg-explain#readme\",\n \"type\": \"module\",\n \"engines\": {\n \"node\": \">=22\"\n },\n \"bin\": {\n \"pg-explain\": \"./dist/cli.js\",\n \"pgexplain\": \"./dist/cli.js\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\",\n \"CHANGELOG.md\"\n ],\n \"sideEffects\": false,\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"biome check .\",\n \"lint:fix\": \"biome check --write .\",\n \"format\": \"biome format --write .\",\n \"test\": \"vitest run --project unit\",\n \"test:watch\": \"vitest\",\n \"test:e2e\": \"pnpm run build && vitest run --project e2e\",\n \"test:integration\": \"vitest run --project integration\",\n \"test:cov\": \"vitest run --project unit --coverage\",\n \"smoke\": \"node dist/cli.js --version\",\n \"prepublishOnly\": \"pnpm run build && pnpm run typecheck && pnpm run lint && pnpm run test\",\n \"release\": \"changeset publish\",\n \"version\": \"changeset version\",\n \"changeset\": \"changeset\"\n },\n \"dependencies\": {\n \"citty\": \"^0.2.2\",\n \"picocolors\": \"^1.1.1\",\n \"zod\": \"^4.4.3\"\n },\n \"optionalDependencies\": {\n \"pg\": \"^8.22.0\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.5.1\",\n \"@changesets/cli\": \"^2.31.0\",\n \"@types/node\": \"^22.10.0\",\n \"@types/pg\": \"^8.15.0\",\n \"@vitest/coverage-v8\": \"^4.1.9\",\n \"execa\": \"^9.5.0\",\n \"testcontainers\": \"^12.0.4\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^6.0.3\",\n \"vitest\": \"^4.1.9\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"packageManager\": \"pnpm@9.7.1\"\n}\n","import type { Diagnostic, Remediation, Severity } from \"../core/model.ts\";\nimport type { ExitCode } from \"../util/exit.ts\";\n\n/**\n * An error that carries a fully-actionable Diagnostic and a process exit code.\n * cli.ts catches these, renders the diagnostic to stderr, and exits with `exitCode`.\n * Anything NOT an AppError that reaches the top level becomes PGX_INTERNAL.\n */\nexport class AppError extends Error {\n readonly diagnostic: Diagnostic;\n readonly exitCode: ExitCode;\n\n constructor(diagnostic: Diagnostic, exitCode: ExitCode, cause?: unknown) {\n super(diagnostic.title);\n this.name = \"AppError\";\n this.diagnostic = diagnostic;\n this.exitCode = exitCode;\n if (cause !== undefined) this.cause = cause;\n }\n}\n\n/** Convenience constructor for plan-domain findings (used by advisor rules). */\nexport function finding(\n code: string,\n severity: Severity,\n parts: {\n title: string;\n detail: string;\n cause: string;\n remediation: Remediation;\n docsUrl?: string;\n location?: Diagnostic[\"location\"];\n meta?: Diagnostic[\"meta\"];\n },\n): Diagnostic {\n return { code, domain: \"plan\", severity, ...parts };\n}\n\nconst SEVERITY_RANK: Record<Severity, number> = { error: 0, warn: 1, info: 2 };\n\n/** Sort by severity (error first), keeping input order within a severity (stable). */\nexport function bySeverity(a: Diagnostic, b: Diagnostic): number {\n return SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity];\n}\n\nexport function maxSeverity(a: Severity, b: Severity): Severity {\n return SEVERITY_RANK[a] <= SEVERITY_RANK[b] ? a : b;\n}\n\n/** True when `s` is at least as severe as `threshold` (error ≥ warn ≥ info). */\nexport function severityAtLeast(s: Severity, threshold: Severity): boolean {\n return SEVERITY_RANK[s] <= SEVERITY_RANK[threshold];\n}\n\n/**\n * Remove secrets from any string before it is logged, shown, or written.\n * Targets:\n * - userinfo passwords in connection URLs: postgres://user:secret@host → user:***@host\n * - libpq keyword form: password=secret → password=***\n * - PG* env-style: PGPASSWORD=secret → PGPASSWORD=***\n * - URL query params: ?password=secret&sslmode=… → ?password=***&…\n */\nexport function scrubCredentials(input: string): string {\n if (!input) return input;\n return input\n .replace(/(\\b[a-z][a-z0-9+.-]*:\\/\\/[^:/?#@\\s]+:)([^@\\s]+)(@)/gi, \"$1***$3\")\n .replace(/\\bpassword\\s*=\\s*'[^']*'/gi, \"password='***'\")\n .replace(/(\\bpassword\\s*=\\s*)([^\\s&'\"]+)/gi, \"$1***\")\n .replace(/(\\bPGPASSWORD\\s*=\\s*)([^\\s&'\"]+)/gi, \"$1***\");\n}\n","import type { Diagnostic, DiagnosticLocation, Severity } from \"../core/model.ts\";\nimport { ExitCode } from \"../util/exit.ts\";\nimport { AppError } from \"./diagnostic.ts\";\n\nconst DOCS = \"https://www.postgresql.org/docs/current\";\n\ninterface OpSpec {\n severity: Severity;\n exit: ExitCode;\n title: string;\n detail: string;\n cause: string;\n remediation: Diagnostic[\"remediation\"];\n docsUrl?: string;\n}\n\n/**\n * The operational error catalog. Every entry tells the developer WHAT happened,\n * WHY, and HOW to fix it. Codes are stable and greppable; they never change meaning.\n * Dynamic specifics (host, user, db, timeout) are injected via `overrides.detail`.\n */\nconst CATALOG = {\n PGX_AUTH_FAILED: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"Authentication failed\",\n detail: \"The server rejected the supplied credentials.\",\n cause:\n \"The password or role is wrong, or pg_hba.conf does not permit this role from your host.\",\n remediation: {\n summary: \"Verify the credentials and supply the password safely (never on the command line).\",\n steps: [\n \"Confirm the username and password are correct.\",\n \"Provide the password via PGPASSWORD or ~/.pgpass instead of the command line.\",\n \"Check that pg_hba.conf allows this role from your client host.\",\n ],\n commands: [\n { label: \"Set password via env\", shell: \"export PGPASSWORD=<password>\" },\n {\n label: \"Or store it (chmod 600)\",\n shell: 'echo \"<host>:<port>:<db>:<user>:<password>\" >> ~/.pgpass && chmod 600 ~/.pgpass',\n },\n ],\n },\n docsUrl: `${DOCS}/auth-pg-hba-conf.html`,\n },\n\n PGX_HOST_UNREACHABLE: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"Cannot reach the PostgreSQL server\",\n detail: \"DNS resolution failed or the TCP connection was refused.\",\n cause:\n \"Wrong host/port, the server is down, or a firewall/VPN/security group is blocking the port.\",\n remediation: {\n summary: \"Verify the host and port, then probe reachability.\",\n steps: [\n \"Double-check --host and --port (or the DSN) for typos.\",\n \"Confirm the server is running and accepts TCP connections.\",\n \"Check VPN, firewall, and cloud security-group rules for the port.\",\n ],\n commands: [{ label: \"Probe reachability\", shell: \"pg_isready -h <host> -p <port>\" }],\n },\n docsUrl: `${DOCS}/libpq-connect.html`,\n },\n\n PGX_DB_NOT_FOUND: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"Database does not exist\",\n detail: \"The named database was not found on the server.\",\n cause: \"The database name is misspelled or the database has not been created.\",\n remediation: {\n summary: \"List the available databases and correct the name.\",\n commands: [\n { label: \"List databases\", shell: \"psql -h <host> -U <user> -l\" },\n { label: \"Re-run with the right name\", shell: \"pg-explain run --dbname <name> ...\" },\n ],\n },\n },\n\n PGX_SSL_REQUIRED: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"Server requires SSL\",\n detail: \"The server requires an encrypted connection but a plaintext one was offered.\",\n cause: \"pg_hba.conf mandates SSL (e.g. `hostssl`) for this role/host.\",\n remediation: {\n summary: \"Enable SSL on the connection.\",\n commands: [\n { label: \"Require encryption\", shell: \"pg-explain run --sslmode require ...\" },\n {\n label: \"Or verify the certificate too\",\n shell: \"pg-explain run --sslmode verify-full --sslrootcert <ca.pem> ...\",\n },\n ],\n },\n docsUrl: `${DOCS}/libpq-ssl.html`,\n },\n\n PGX_SSL_VERIFY_FAILED: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"TLS certificate verification failed\",\n detail: \"Under verify-full the certificate chain is untrusted or the hostname does not match.\",\n cause:\n \"The CA is not trusted locally, or the certificate's CN/SAN does not match the host you connect to.\",\n remediation: {\n summary: \"Point at the CA bundle and confirm the hostname matches the certificate.\",\n steps: [\n \"Provide the CA certificate the server's cert chains to.\",\n \"Confirm the certificate CN/SAN matches the --host value.\",\n \"Only fall back to `--sslmode require` (encryption without identity check) if you accept the risk.\",\n ],\n commands: [\n {\n label: \"Trust a CA\",\n shell: \"pg-explain run --sslmode verify-full --sslrootcert <ca.pem> ...\",\n },\n ],\n },\n docsUrl: `${DOCS}/libpq-ssl.html`,\n },\n\n PGX_CONN_TIMEOUT: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"Connection timed out\",\n detail: \"The connect handshake did not complete within the connect deadline.\",\n cause: \"High network latency, an overloaded server, or a firewall silently dropping packets.\",\n remediation: {\n summary: \"Raise the connect budget and investigate the network path.\",\n commands: [\n { label: \"Increase connect timeout\", shell: \"pg-explain run --connect-timeout 30s ...\" },\n ],\n },\n docsUrl: `${DOCS}/libpq-connect.html`,\n },\n\n PGX_PERMISSION_DENIED: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"Permission denied\",\n detail: \"The connecting role lacks a privilege the query needs.\",\n cause:\n \"EXPLAIN must plan the query, which requires SELECT (and any referenced privileges) on the relations.\",\n remediation: {\n summary: \"Grant the missing privilege, or connect with a role that already has it.\",\n commands: [\n { label: \"Grant SELECT (run as owner)\", sql: \"GRANT SELECT ON <table> TO <role>;\" },\n ],\n },\n docsUrl: `${DOCS}/sql-grant.html`,\n },\n\n PGX_RELATION_NOT_FOUND: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"Relation does not exist\",\n detail: \"A table or view referenced by the query was not found.\",\n cause: \"The name is misspelled, or it lives in a schema that is not on the search_path.\",\n remediation: {\n summary: \"Schema-qualify the relation or set the search_path.\",\n steps: [\"Check spelling and the schema.\", \"List tables with `\\\\dt` in psql.\"],\n commands: [{ label: \"Set the search path\", sql: \"SET search_path = <schema>, public;\" }],\n },\n },\n\n PGX_STATEMENT_TIMEOUT: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"Statement timeout reached\",\n detail: \"statement_timeout fired while EXPLAIN ANALYZE was executing the query.\",\n cause: \"The query genuinely takes longer than the configured statement_timeout to run.\",\n remediation: {\n summary: \"Raise the timeout, or avoid executing the query at all.\",\n steps: [\n \"Raise the per-run statement timeout.\",\n \"Or get an estimate-only plan that never executes (drop --analyze).\",\n \"Or reduce measurement overhead with --timing off.\",\n ],\n commands: [\n { label: \"Raise the timeout\", shell: \"pg-explain run --statement-timeout 60s ...\" },\n ],\n },\n docsUrl: `${DOCS}/runtime-config-client.html#GUC-STATEMENT-TIMEOUT`,\n },\n\n PGX_LOCK_TIMEOUT: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"Lock timeout reached\",\n detail: \"lock_timeout elapsed while waiting to acquire a lock on a relation.\",\n cause: \"Another transaction holds a conflicting lock on a relation the query touches.\",\n remediation: {\n summary: \"Raise the lock timeout, identify the blocker, or retry off-peak.\",\n commands: [\n { label: \"Raise the lock timeout\", shell: \"pg-explain run --lock-timeout 30s ...\" },\n {\n label: \"Find blockers\",\n sql: \"SELECT * FROM pg_locks l JOIN pg_stat_activity a USING (pid) WHERE NOT l.granted;\",\n },\n ],\n },\n docsUrl: `${DOCS}/runtime-config-client.html#GUC-LOCK-TIMEOUT`,\n },\n\n PGX_QUERY_CANCELED: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"Query was canceled\",\n detail: \"The query was canceled by an administrator or a signal before completing.\",\n cause:\n \"An admin pg_cancel_backend call, a resource group, or a pool limit canceled the statement.\",\n remediation: {\n summary: \"Re-run the command; if it recurs, check for admin cancellation or pool limits.\",\n },\n },\n\n PGX_UNSUPPORTED_PG_VERSION: {\n severity: \"error\",\n exit: ExitCode.Usage,\n title: \"EXPLAIN option not supported by this server\",\n detail: \"A requested EXPLAIN option requires a newer PostgreSQL major version.\",\n cause:\n \"Options are version-gated (e.g. SETTINGS≥12, WAL≥13, GENERIC_PLAN≥16, SERIALIZE/MEMORY≥17).\",\n remediation: {\n summary:\n \"Drop the unsupported option, target a newer server, or let pg-explain auto-omit it.\",\n commands: [{ label: \"Auto-omit unsupported options\", shell: \"pg-explain run --compat ...\" }],\n },\n docsUrl: `${DOCS}/sql-explain.html`,\n },\n\n PGX_INVALID_EXPLAIN_OPTION: {\n severity: \"error\",\n exit: ExitCode.Usage,\n title: \"Invalid EXPLAIN option combination\",\n detail: \"The server rejected an EXPLAIN option or a mutually-exclusive combination.\",\n cause:\n \"Some options require ANALYZE (WAL, SERIALIZE, TIMING) and GENERIC_PLAN is incompatible with ANALYZE.\",\n remediation: {\n summary: \"Fix the option combination; see `pg-explain --help` for valid combinations.\",\n steps: [\n \"WAL/SERIALIZE/TIMING require --analyze.\",\n \"GENERIC_PLAN cannot be combined with --analyze.\",\n ],\n },\n docsUrl: `${DOCS}/sql-explain.html`,\n },\n\n PGX_MALFORMED_JSON: {\n severity: \"error\",\n exit: ExitCode.Parse,\n title: \"Input is not valid JSON\",\n detail: \"The plan input could not be parsed as JSON.\",\n cause: \"The input was truncated when captured, or it is not EXPLAIN (FORMAT JSON) output.\",\n remediation: {\n summary: \"Validate the input and make sure it is FORMAT JSON output.\",\n commands: [{ label: \"Validate JSON\", shell: \"jq . plan.json\" }],\n },\n },\n\n PGX_UNEXPECTED_PLAN_SHAPE: {\n severity: \"error\",\n exit: ExitCode.Parse,\n title: \"Input is not an EXPLAIN plan\",\n detail: \"The JSON parsed but does not contain a recognizable EXPLAIN plan tree.\",\n cause: \"The 'Plan' node is missing — this may be query result rows rather than a plan.\",\n remediation: {\n summary: \"Regenerate the plan with FORMAT JSON and pipe that in.\",\n commands: [\n { label: \"Capture a plan\", sql: \"EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) <your query>;\" },\n ],\n },\n docsUrl: `${DOCS}/sql-explain.html`,\n },\n\n PGX_EMPTY_INPUT: {\n severity: \"error\",\n exit: ExitCode.Input,\n title: \"No plan input received\",\n detail: \"stdin and the named file were both empty.\",\n cause: \"No plan was piped in and no query/file was provided.\",\n remediation: {\n summary: \"Pipe a plan, or provide SQL to run.\",\n commands: [\n { label: \"Analyze a saved plan\", shell: \"pg-explain < plan.json\" },\n { label: \"Or run a query\", shell: 'pg-explain run --query \"<sql>\" --dsn <dsn>' },\n ],\n },\n },\n\n PGX_NON_SELECT_REFUSED: {\n severity: \"error\",\n exit: ExitCode.Usage,\n title: \"Refusing to ANALYZE a data-modifying statement\",\n detail: \"EXPLAIN ANALYZE executes the statement, and this one would modify data.\",\n cause:\n \"INSERT/UPDATE/DELETE/MERGE/DDL run for real under ANALYZE; running it could change your data.\",\n remediation: {\n summary:\n \"Use --force to run it inside an automatically rolled-back transaction, or drop --analyze.\",\n steps: [\n \"With --force, pg-explain wraps it as `BEGIN; <stmt>; ROLLBACK;` so nothing is committed.\",\n \"Without --analyze you get an estimate-only plan that never executes.\",\n ],\n commands: [\n {\n label: \"Run safely (auto-rollback)\",\n shell: \"pg-explain run --force --file mutation.sql --dsn <dsn>\",\n },\n ],\n },\n },\n\n PGX_MULTIPLE_STATEMENTS: {\n severity: \"error\",\n exit: ExitCode.Usage,\n title: \"Multiple SQL statements found\",\n detail: \"The input contains more than one statement; pg-explain analyzes one at a time.\",\n cause: \"A .sql file or --query string contained several semicolon-separated statements.\",\n remediation: {\n summary: \"Select one statement, or split them into separate invocations.\",\n commands: [\n {\n label: \"Pick the Nth statement (1-based)\",\n shell: \"pg-explain run --statement 2 --file queries.sql --dsn <dsn>\",\n },\n ],\n },\n },\n\n PGX_COST_ONLY_PLAN: {\n severity: \"info\",\n exit: ExitCode.Success,\n title: \"Cost-only plan — estimate-vs-actual checks unavailable\",\n detail: \"This plan has cost estimates but no actual row/time data.\",\n cause: \"It was produced by plain EXPLAIN (without ANALYZE), so runtime behavior is unknown.\",\n remediation: {\n summary: \"Re-run with ANALYZE to unlock estimate-vs-actual, timing, and spill findings.\",\n commands: [\n { label: \"Capture actuals\", sql: \"EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) <query>;\" },\n ],\n },\n docsUrl: `${DOCS}/using-explain.html#USING-EXPLAIN-ANALYZE`,\n },\n\n PGX_NO_BUFFERS: {\n severity: \"info\",\n exit: ExitCode.Success,\n title: \"No BUFFERS data — cache/I/O analysis skipped\",\n detail: \"Buffer counters are absent, so cache-hit ratio and I/O findings cannot be computed.\",\n cause: \"The plan was captured without BUFFERS.\",\n remediation: {\n summary: \"Add BUFFERS to surface shared/temp block usage and the cache-hit ratio.\",\n commands: [\n { label: \"Capture buffers\", sql: \"EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) <query>;\" },\n ],\n },\n },\n\n PGX_EMPTY_PLAN: {\n severity: \"info\",\n exit: ExitCode.Success,\n title: \"Nothing to analyze\",\n detail: \"The plan has no scans or joins to evaluate (e.g. a bare Result node).\",\n cause: \"The query is trivial and has no tuning surface.\",\n remediation: { summary: \"Confirm this is the query you intended to profile.\" },\n },\n\n PGX_PG_DRIVER_MISSING: {\n severity: \"error\",\n exit: ExitCode.Usage,\n title: \"The 'pg' driver is not installed\",\n detail: \"The run command needs the PostgreSQL driver, which is an optional dependency.\",\n cause:\n \"pgexplain ships 'pg' as optional so plan-only use stays dependency-free; it isn't installed here.\",\n remediation: {\n summary:\n \"Install the pg driver, then re-run. (Plan-only analysis from a file/stdin needs no driver.)\",\n commands: [\n { label: \"with pnpm\", shell: \"pnpm add pg\" },\n { label: \"with npm\", shell: \"npm install pg\" },\n ],\n },\n },\n\n PGX_QUERY_FAILED: {\n severity: \"error\",\n exit: ExitCode.Database,\n title: \"The query could not be planned or executed\",\n detail: \"PostgreSQL returned an error while running EXPLAIN.\",\n cause:\n \"The statement has a syntax error, references something invalid, or hit a server-side limit.\",\n remediation: {\n summary:\n \"Read the server message below, fix the statement, and re-run. Test it in psql first if unsure.\",\n commands: [{ label: \"Try it directly\", shell: 'psql \"<dsn>\" -c \"EXPLAIN <your statement>\"' }],\n },\n docsUrl: `${DOCS}/sql-explain.html`,\n },\n\n PGX_INTERNAL: {\n severity: \"error\",\n exit: ExitCode.Internal,\n title: \"pg-explain hit an unexpected error\",\n detail: \"This is a bug in pg-explain, not in your query or plan.\",\n cause: \"An unhandled condition was reached.\",\n remediation: {\n summary: \"Re-run with --debug for a credential-scrubbed stack trace, then file an issue.\",\n commands: [\n { label: \"Show the trace\", shell: \"pg-explain --debug ...\" },\n { label: \"Report your version\", shell: \"pg-explain --version\" },\n ],\n },\n },\n} satisfies Record<string, OpSpec>;\n\nexport type OpCode = keyof typeof CATALOG;\n\n/** Every operational code, for iteration (docs generation, completeness tests). */\nexport const OP_CODES = Object.keys(CATALOG) as OpCode[];\n\ninterface OpOverrides {\n /** Replace the default detail with situation-specific text (will be credential-scrubbed by the caller). */\n detail?: string;\n meta?: Diagnostic[\"meta\"];\n location?: DiagnosticLocation;\n}\n\n/** Build the Diagnostic for an operational code (used for info-level, non-fatal notices). */\nexport function opDiagnostic(code: OpCode, overrides: OpOverrides = {}): Diagnostic {\n const spec: OpSpec = CATALOG[code];\n const diag: Diagnostic = {\n code,\n domain: \"operational\",\n severity: spec.severity,\n title: spec.title,\n detail: overrides.detail ?? spec.detail,\n cause: spec.cause,\n remediation: spec.remediation,\n };\n if (spec.docsUrl) diag.docsUrl = spec.docsUrl;\n if (overrides.location) diag.location = overrides.location;\n if (overrides.meta) diag.meta = overrides.meta;\n return diag;\n}\n\n/** Build a throwable AppError for an operational code, with the correct exit code. */\nexport function opError(code: OpCode, overrides: OpOverrides = {}, cause?: unknown): AppError {\n return new AppError(opDiagnostic(code, overrides), CATALOG[code].exit, cause);\n}\n\nexport function exitCodeFor(code: OpCode): ExitCode {\n return CATALOG[code].exit;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { Severity, Thresholds } from \"./core/model.ts\";\nimport { opError } from \"./diagnostics/catalog.ts\";\n\nexport interface RuleConfig {\n enabled?: boolean;\n severity?: Severity;\n}\n\nexport interface PgExplainConfig {\n thresholds: Thresholds;\n /** Per-rule enable/disable and severity overrides, keyed by rule id. */\n rules: Record<string, RuleConfig>;\n}\n\nexport const DEFAULT_THRESHOLDS: Thresholds = {\n seqScanRows: 100_000,\n nestedLoopOuterRows: 10_000,\n filterDiscardRatio: 0.9,\n filterRemovedAbs: 10_000,\n misestimateFactor: 10,\n heapFetchRatio: 0.1,\n heapFetchAbs: 1_000,\n correlatedLoops: 1_000,\n jitPct: 25,\n triggerPct: 10,\n lowCacheHitRatio: 0.9,\n};\n\nexport const DEFAULT_CONFIG: PgExplainConfig = {\n thresholds: { ...DEFAULT_THRESHOLDS },\n rules: {},\n};\n\nconst CONFIG_FILES = [\".pgexplainrc.json\", \".pgexplainrc\"];\n\n/** A partial config as it appears in a config file (all fields optional). */\ninterface PartialConfig {\n thresholds?: Partial<Thresholds>;\n rules?: Record<string, RuleConfig>;\n}\n\nfunction merge(partial: PartialConfig): PgExplainConfig {\n return {\n thresholds: { ...DEFAULT_THRESHOLDS, ...(partial.thresholds ?? {}) },\n rules: { ...(partial.rules ?? {}) },\n };\n}\n\nasync function readJson(path: string): Promise<unknown> {\n let text: string;\n try {\n text = await readFile(path, \"utf8\");\n } catch (err) {\n throw opError(\n \"PGX_EMPTY_INPUT\",\n {\n detail: `Could not read config '${path}': ${err instanceof Error ? err.message : String(err)}`,\n },\n err,\n );\n }\n try {\n return JSON.parse(text);\n } catch (err) {\n throw opError(\n \"PGX_MALFORMED_JSON\",\n {\n detail: `Config '${path}' is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n },\n err,\n );\n }\n}\n\n/**\n * Load config: an explicit --config path, else a `.pgexplainrc[.json]` or a\n * `pgExplain` key in package.json in cwd. Missing config is fine (returns defaults);\n * an unreadable/invalid explicit path is an actionable error.\n */\nexport async function loadConfig(\n explicitPath: string | undefined,\n cwd = process.cwd(),\n): Promise<PgExplainConfig> {\n if (explicitPath) return merge((await readJson(explicitPath)) as PartialConfig);\n\n for (const name of CONFIG_FILES) {\n try {\n const text = await readFile(join(cwd, name), \"utf8\");\n return merge(JSON.parse(text) as PartialConfig);\n } catch {\n // not present / unreadable — try the next source\n }\n }\n\n try {\n const pkg = JSON.parse(await readFile(join(cwd, \"package.json\"), \"utf8\")) as {\n pgExplain?: PartialConfig;\n };\n if (pkg.pgExplain) return merge(pkg.pgExplain);\n } catch {\n // no package.json or no key — fall through to defaults\n }\n\n return { ...DEFAULT_CONFIG, thresholds: { ...DEFAULT_THRESHOLDS }, rules: {} };\n}\n","import { z } from \"zod\";\n\n/**\n * Version-tolerant validation for EXPLAIN (FORMAT JSON) output.\n *\n * We only assert the *shape* we depend on (\"Node Type\" + recursive \"Plans\"); every\n * other field is accepted and preserved via looseObject so plans from PG 14 → 18\n * validate identically. Field access happens against the original parsed JSON (the\n * `raw` node), so unknown/new fields are never lost.\n */\nconst PlanNodeSchema = z.looseObject({\n \"Node Type\": z.string(),\n get Plans() {\n return z.array(PlanNodeSchema).optional();\n },\n});\n\nconst StatementSchema = z.looseObject({\n Plan: PlanNodeSchema,\n \"Planning Time\": z.number().optional(),\n \"Execution Time\": z.number().optional(),\n Triggers: z.array(z.looseObject({})).optional(),\n JIT: z.looseObject({}).optional(),\n Settings: z.record(z.string(), z.unknown()).optional(),\n});\n\n/** EXPLAIN FORMAT JSON is an array of statements (usually one). */\nexport const ExplainOutputSchema = z.array(StatementSchema).min(1);\n\nexport type ExplainOutput = z.infer<typeof ExplainOutputSchema>;\nexport type ExplainStatement = z.infer<typeof StatementSchema>;\n","import { opError } from \"../diagnostics/catalog.ts\";\nimport type { JitInfo, PlanNode, PlanTree, RawPlan, TriggerInfo } from \"./model.ts\";\nimport { ExplainOutputSchema } from \"./schema.ts\";\n\n// ── safe field readers ────────────────────────────────────────────────────────\n\nfunction num(raw: RawPlan, key: string): number | undefined {\n const v = raw[key];\n return typeof v === \"number\" ? v : undefined;\n}\n\nfunction str(raw: RawPlan, key: string): string | undefined {\n const v = raw[key];\n return typeof v === \"string\" ? v : undefined;\n}\n\nfunction strArray(raw: RawPlan, key: string): string[] | undefined {\n const v = raw[key];\n if (Array.isArray(v) && v.every((x) => typeof x === \"string\")) return v as string[];\n if (typeof v === \"string\") return [v];\n return undefined;\n}\n\n// ── JSON parse with line/column for actionable malformed-input errors ─────────\n\nfunction parseJsonWithLocation(input: string): unknown {\n try {\n return JSON.parse(input);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n let line: number | undefined;\n let col: number | undefined;\n\n const lc = message.match(/line (\\d+) column (\\d+)/i);\n if (lc?.[1] && lc[2]) {\n line = Number(lc[1]);\n col = Number(lc[2]);\n } else {\n const pos = message.match(/position (\\d+)/i);\n if (pos?.[1]) {\n const offset = Number(pos[1]);\n const before = input.slice(0, offset);\n line = before.split(\"\\n\").length;\n col = offset - before.lastIndexOf(\"\\n\");\n }\n }\n\n const where = line && col ? ` (line ${line}, col ${col})` : \"\";\n throw opError(\n \"PGX_MALFORMED_JSON\",\n {\n detail: `The plan input could not be parsed as JSON${where}: ${message}`,\n location: line && col ? { kind: \"input\", line, col } : { kind: \"input\" },\n },\n err,\n );\n }\n}\n\n// ── normalization ─────────────────────────────────────────────────────────────\n\nfunction normalizeNode(raw: RawPlan, nextId: () => number): PlanNode {\n const node: PlanNode = {\n id: nextId(),\n nodeType: raw[\"Node Type\"],\n planRows: num(raw, \"Plan Rows\") ?? 0,\n children: [],\n metrics: {},\n raw,\n };\n\n assign(node, {\n parentRelationship: str(raw, \"Parent Relationship\"),\n subplanName: str(raw, \"Subplan Name\"),\n relationName: str(raw, \"Relation Name\"),\n schema: str(raw, \"Schema\"),\n alias: str(raw, \"Alias\"),\n indexName: str(raw, \"Index Name\"),\n planWidth: num(raw, \"Plan Width\"),\n startupCost: num(raw, \"Startup Cost\"),\n totalCost: num(raw, \"Total Cost\"),\n actualRows: num(raw, \"Actual Rows\"),\n actualLoops: num(raw, \"Actual Loops\"),\n actualStartupTime: num(raw, \"Actual Startup Time\"),\n actualTotalTime: num(raw, \"Actual Total Time\"),\n filter: str(raw, \"Filter\"),\n rowsRemovedByFilter: num(raw, \"Rows Removed by Filter\"),\n indexCond: str(raw, \"Index Cond\"),\n recheckCond: str(raw, \"Recheck Cond\"),\n rowsRemovedByIndexRecheck: num(raw, \"Rows Removed by Index Recheck\"),\n heapFetches: num(raw, \"Heap Fetches\"),\n hashCond: str(raw, \"Hash Cond\"),\n joinType: str(raw, \"Join Type\"),\n joinFilter: str(raw, \"Join Filter\"),\n rowsRemovedByJoinFilter: num(raw, \"Rows Removed by Join Filter\"),\n output: strArray(raw, \"Output\"),\n sortMethod: str(raw, \"Sort Method\"),\n sortSpaceType: str(raw, \"Sort Space Type\"),\n sortSpaceUsed: num(raw, \"Sort Space Used\"),\n sortKey: strArray(raw, \"Sort Key\"),\n hashBuckets: num(raw, \"Hash Buckets\"),\n originalHashBuckets: num(raw, \"Original Hash Buckets\"),\n hashBatches: num(raw, \"Hash Batches\"),\n originalHashBatches: num(raw, \"Original Hash Batches\"),\n peakMemoryUsage: num(raw, \"Peak Memory Usage\"),\n diskUsage: num(raw, \"Disk Usage\"),\n exactHeapBlocks: num(raw, \"Exact Heap Blocks\"),\n lossyHeapBlocks: num(raw, \"Lossy Heap Blocks\"),\n sharedHitBlocks: num(raw, \"Shared Hit Blocks\"),\n sharedReadBlocks: num(raw, \"Shared Read Blocks\"),\n sharedDirtiedBlocks: num(raw, \"Shared Dirtied Blocks\"),\n sharedWrittenBlocks: num(raw, \"Shared Written Blocks\"),\n localHitBlocks: num(raw, \"Local Hit Blocks\"),\n localReadBlocks: num(raw, \"Local Read Blocks\"),\n tempReadBlocks: num(raw, \"Temp Read Blocks\"),\n tempWrittenBlocks: num(raw, \"Temp Written Blocks\"),\n ioReadTime: num(raw, \"I/O Read Time\"),\n ioWriteTime: num(raw, \"I/O Write Time\"),\n workersPlanned: num(raw, \"Workers Planned\"),\n workersLaunched: num(raw, \"Workers Launched\"),\n });\n\n const childPlans = raw.Plans;\n if (Array.isArray(childPlans)) {\n for (const child of childPlans) {\n node.children.push(normalizeNode(child, nextId));\n }\n }\n return node;\n}\n\n/** Copy only the defined keys, so optional fields stay absent (not `undefined`). */\nfunction assign<T extends object>(target: T, fields: Partial<T>): void {\n for (const [k, v] of Object.entries(fields)) {\n if (v !== undefined) (target as Record<string, unknown>)[k] = v;\n }\n}\n\nfunction parseTriggers(raw: unknown): TriggerInfo[] {\n if (!Array.isArray(raw)) return [];\n return raw.map((t) => {\n const r = t as RawPlan;\n const info: TriggerInfo = {};\n assign(info, {\n name: str(r, \"Trigger Name\"),\n constraintName: str(r, \"Constraint Name\"),\n relation: str(r, \"Relation\"),\n calls: num(r, \"Calls\"),\n time: num(r, \"Time\"),\n });\n return info;\n });\n}\n\nfunction parseJit(raw: unknown): JitInfo | undefined {\n if (!raw || typeof raw !== \"object\") return undefined;\n const r = raw as RawPlan;\n const timing = r.Timing as RawPlan | undefined;\n const jit: JitInfo = {};\n const functions = num(r, \"Functions\");\n if (functions !== undefined) jit.functions = functions;\n if (timing && typeof timing === \"object\") {\n jit.timing = {\n total: num(timing, \"Total\"),\n generation: num(timing, \"Generation\"),\n inlining: num(timing, \"Inlining\"),\n optimization: num(timing, \"Optimization\"),\n emission: num(timing, \"Emission\"),\n };\n }\n return jit;\n}\n\n/**\n * Parse EXPLAIN (FORMAT JSON) text into one PlanTree per statement.\n * Accepts the standard `[{ \"Plan\": … }]`, a bare statement object, or a bare plan node.\n * Throws AppError(PGX_MALFORMED_JSON | PGX_UNEXPECTED_PLAN_SHAPE) with a location.\n */\nexport function parseExplainJson(input: string): PlanTree[] {\n const json = parseJsonWithLocation(input);\n\n // Normalize the accepted shapes into the canonical array-of-statements.\n let candidate: unknown = json;\n if (json && typeof json === \"object\" && !Array.isArray(json)) {\n const obj = json as Record<string, unknown>;\n candidate = \"Plan\" in obj ? [obj] : \"Node Type\" in obj ? [{ Plan: obj }] : json;\n }\n\n const result = ExplainOutputSchema.safeParse(candidate);\n if (!result.success) {\n throw opError(\"PGX_UNEXPECTED_PLAN_SHAPE\", {\n detail: `The JSON is valid but is not an EXPLAIN plan: ${result.error.issues[0]?.message ?? \"missing 'Plan' node\"}.`,\n location: { kind: \"input\" },\n });\n }\n\n return result.data.map((stmt): PlanTree => {\n let id = 0;\n const root = normalizeNode(stmt.Plan as RawPlan, () => id++);\n const hasAnalyze = root.actualLoops !== undefined || stmt[\"Execution Time\"] !== undefined;\n const hasBuffers = root.sharedHitBlocks !== undefined || root.sharedReadBlocks !== undefined;\n\n const tree: PlanTree = {\n root,\n triggers: parseTriggers(stmt.Triggers),\n hasAnalyze,\n hasBuffers,\n raw: stmt.Plan as RawPlan,\n };\n if (stmt[\"Planning Time\"] !== undefined) tree.planningTime = stmt[\"Planning Time\"];\n if (stmt[\"Execution Time\"] !== undefined) tree.executionTime = stmt[\"Execution Time\"];\n const jit = parseJit(stmt.JIT);\n if (jit) tree.jit = jit;\n if (stmt.Settings) tree.settings = stmt.Settings as Record<string, string>;\n return tree;\n });\n}\n\n/** Depth-first pre-order walk (root first). Used by metrics and the advisor. */\nexport function walk(node: PlanNode, visit: (n: PlanNode) => void): void {\n visit(node);\n for (const child of node.children) walk(child, visit);\n}\n\n/** Flatten a tree to an array in pre-order. */\nexport function flatten(node: PlanNode): PlanNode[] {\n const out: PlanNode[] = [];\n walk(node, (n) => out.push(n));\n return out;\n}\n","import type { PlanNode, PlanTree } from \"./model.ts\";\nimport { flatten, walk } from \"./parse.ts\";\n\n/**\n * Fill `node.metrics` for every node. All row/time figures are PER-LOOP corrected:\n * Postgres reports \"Actual Rows\"/\"Actual Total Time\" as the average of a single loop,\n * so the true total is `× \"Actual Loops\"`. Buffer counters are already cumulative and\n * are NOT multiplied. No-ops cleanly on cost-only plans (leaves metrics empty).\n */\nexport function computeMetrics(tree: PlanTree): void {\n // Pass 1 — per-node quantities that don't depend on siblings/children.\n walk(tree.root, (node) => {\n const { actualRows, actualLoops, actualTotalTime } = node;\n\n if (actualRows !== undefined && actualLoops !== undefined) {\n node.metrics.totalRows = actualRows * actualLoops;\n }\n if (actualTotalTime !== undefined && actualLoops !== undefined) {\n node.metrics.inclusiveMs = actualTotalTime * actualLoops;\n }\n\n // Estimate vs actual (only meaningful with actuals).\n if (node.metrics.totalRows !== undefined) {\n const est = Math.max(node.planRows, 1);\n const act = Math.max(node.metrics.totalRows, 1);\n node.metrics.estimateFactor = est >= act ? est / act : act / est;\n node.metrics.estimateDirection =\n node.planRows > node.metrics.totalRows\n ? \"over\"\n : node.metrics.totalRows > node.planRows\n ? \"under\"\n : \"accurate\";\n }\n\n // Cache-hit ratio from shared buffers (cumulative — no ×loops).\n const hit = node.sharedHitBlocks ?? 0;\n const read = node.sharedReadBlocks ?? 0;\n node.metrics.cacheHitRatio = hit + read > 0 ? hit / (hit + read) : null;\n\n // Filter discard ratio (per-loop corrected).\n if (node.rowsRemovedByFilter !== undefined && actualLoops !== undefined) {\n const removed = node.rowsRemovedByFilter * actualLoops;\n const kept = node.metrics.totalRows ?? 0;\n const denom = removed + kept;\n if (denom > 0) node.metrics.filterDiscardRatio = removed / denom;\n }\n\n // Bitmap lossy ratio.\n if (node.lossyHeapBlocks !== undefined) {\n const lossy = node.lossyHeapBlocks;\n const exact = node.exactHeapBlocks ?? 0;\n const denom = lossy + exact;\n if (denom > 0) node.metrics.lossyRatio = lossy / denom;\n }\n });\n\n // Pass 2 — self time = inclusive − Σ(children inclusive), clamped ≥ 0.\n walk(tree.root, (node) => {\n if (node.metrics.inclusiveMs === undefined) return;\n let childrenMs = 0;\n for (const child of node.children) childrenMs += child.metrics.inclusiveMs ?? 0;\n node.metrics.selfMs = Math.max(node.metrics.inclusiveMs - childrenMs, 0);\n });\n\n // Pass 3 — % of total execution time.\n const totalMs = executionMs(tree);\n if (totalMs && totalMs > 0) {\n walk(tree.root, (node) => {\n if (node.metrics.selfMs !== undefined) {\n node.metrics.pctOfTotal = (100 * node.metrics.selfMs) / totalMs;\n }\n });\n }\n}\n\n/** Total execution time in ms: prefer the reported value, else the root's inclusive time. */\nexport function executionMs(tree: PlanTree): number | undefined {\n return tree.executionTime ?? tree.root.metrics.inclusiveMs;\n}\n\n/** Top N nodes by self time (the real bottlenecks), descending. */\nexport function bottlenecks(tree: PlanTree, n = 5): PlanNode[] {\n return flatten(tree.root)\n .filter((node) => node.metrics.selfMs !== undefined)\n .sort((a, b) => (b.metrics.selfMs ?? 0) - (a.metrics.selfMs ?? 0))\n .slice(0, n);\n}\n\n/** A short human label for a node, e.g. \"Seq Scan on orders\". */\nexport function nodeLabel(node: PlanNode): string {\n let label = node.nodeType;\n if (node.indexName && node.relationName)\n label += ` using ${node.indexName} on ${node.relationName}`;\n else if (node.relationName) label += ` on ${node.relationName}`;\n if (node.alias && node.alias !== node.relationName) label += ` (${node.alias})`;\n return label;\n}\n","/** Locale-aware, unit-consistent formatting shared by every renderer. */\n\n/** Postgres default block size; buffer counters are in blocks. */\nconst BLOCK_BYTES = 8192;\n\nexport function fmtInt(n: number): string {\n return Math.round(n).toLocaleString(\"en-US\");\n}\n\n/** Times are milliseconds throughout. */\nexport function fmtMs(ms: number): string {\n if (ms < 1) return `${ms.toFixed(3)} ms`;\n if (ms < 1000) return `${ms.toFixed(1)} ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(2)} s`;\n const min = Math.floor(ms / 60_000);\n const sec = ((ms % 60_000) / 1000).toFixed(0);\n return `${min}m ${sec}s`;\n}\n\nexport function fmtPct(fraction0to100: number): string {\n return `${fraction0to100.toFixed(1)}%`;\n}\n\n/** Postgres reports sort/hash space in KiB. */\nexport function fmtKiB(kib: number): string {\n return fmtBytes(kib * 1024);\n}\n\n/** Buffer counters are in 8 KiB blocks. */\nexport function fmtBlocks(blocks: number): string {\n return `${fmtInt(blocks)} blk (${fmtBytes(blocks * BLOCK_BYTES)})`;\n}\n\nexport function fmtBytes(bytes: number): string {\n const units = [\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\"];\n let v = bytes;\n let i = 0;\n while (v >= 1024 && i < units.length - 1) {\n v /= 1024;\n i++;\n }\n const s = i === 0 ? String(Math.round(v)) : v.toFixed(1);\n return `${s} ${units[i]}`;\n}\n\n/** Round a KiB value up to the next whole MiB (work_mem recommendations). */\nexport function roundUpMiB(kib: number, stepMiB = 4): string {\n const mib = Math.ceil(kib / 1024 / stepMiB) * stepMiB;\n return `${Math.max(mib, stepMiB)}MB`;\n}\n\nexport interface TreeGlyphs {\n branch: string;\n last: string;\n vert: string;\n space: string;\n}\n\nexport const UNICODE_TREE: TreeGlyphs = { branch: \"├─ \", last: \"└─ \", vert: \"│ \", space: \" \" };\nexport const ASCII_TREE: TreeGlyphs = { branch: \"+- \", last: \"`- \", vert: \"| \", space: \" \" };\n","import type {\n AnalysisContext,\n Diagnostic,\n DiagnosticLocation,\n PlanNode,\n Remediation,\n Rule,\n Severity,\n} from \"../../core/model.ts\";\n\nexport const DOCS = \"https://www.postgresql.org/docs/current\";\n\nexport function locationOf(node: PlanNode): DiagnosticLocation {\n const loc: DiagnosticLocation = { kind: \"node\", nodeId: node.id, nodeType: node.nodeType };\n if (node.relationName) loc.relation = node.relationName;\n return loc;\n}\n\n/**\n * Build a plan finding. The Diagnostic `code` is the rule id (a PGX_* code), severity\n * is resolved through config overrides, and the location points at the offending node.\n * Every rule goes through here so all findings carry remediation + a node location.\n */\nexport function makeFinding(\n rule: Rule,\n ctx: AnalysisContext,\n node: PlanNode,\n parts: {\n title: string;\n detail: string;\n cause: string;\n remediation: Remediation;\n docsUrl?: string;\n meta?: Diagnostic[\"meta\"];\n /** Per-finding severity fallback (e.g. underestimate→warn); config still wins. */\n severity?: Severity;\n },\n): Diagnostic {\n const d: Diagnostic = {\n code: rule.id,\n domain: \"plan\",\n severity: ctx.severityOf(rule.id, parts.severity ?? rule.defaultSeverity),\n title: parts.title,\n detail: parts.detail,\n cause: parts.cause,\n remediation: parts.remediation,\n location: locationOf(node),\n };\n if (parts.docsUrl) d.docsUrl = parts.docsUrl;\n if (parts.meta) d.meta = parts.meta;\n return d;\n}\n\n/** First child is the outer (driving) side of a join. */\nexport function outerChild(node: PlanNode): PlanNode | undefined {\n return node.children[0];\n}\n","import type { Rule } from \"../../core/model.ts\";\nimport { fmtInt } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * Bitmap heap scan whose bitmap exceeded work_mem and degraded to page granularity.\n * When the per-tuple bitmap won't fit, Postgres stores only the heap *page* numbers\n * (\"lossy\" blocks) and re-checks the index condition against every tuple on those\n * pages, reading more heap and re-evaluating the predicate. Raising work_mem keeps the\n * bitmap exact; a more selective index also shrinks it.\n */\nexport const bitmapLossy: Rule = {\n id: \"PGX_BITMAP_LOSSY\",\n title: \"Lossy bitmap heap scan\",\n defaultSeverity: \"info\",\n requiresAnalyze: true,\n check(node, ctx) {\n if (node.nodeType !== \"Bitmap Heap Scan\") return [];\n\n const lossy = node.lossyHeapBlocks ?? 0;\n if (lossy <= 0) return [];\n\n const exact = node.exactHeapBlocks ?? 0;\n const rel = node.relationName ?? \"the table\";\n const rechecked = node.rowsRemovedByIndexRecheck ?? 0;\n const recheckNote =\n rechecked > 0\n ? ` The recheck discarded ${fmtInt(rechecked)} extra rows that the lossy bitmap could not exclude.`\n : \"\";\n\n return [\n makeFinding(bitmapLossy, ctx, node, {\n title: `Lossy bitmap heap scan on ${rel} (${fmtInt(lossy)} lossy blocks)`,\n detail: `The bitmap for ${rel} held ${fmtInt(lossy)} lossy (page-granularity) blocks alongside ${fmtInt(\n exact,\n )} exact blocks, so Postgres re-checked the index condition against every tuple on the lossy pages.${recheckNote}`,\n cause:\n \"The exact (per-tuple) bitmap did not fit in work_mem, so Postgres fell back to storing whole heap pages and recheck the index condition while reading them — more heap I/O and CPU than an exact bitmap.\",\n remediation: {\n summary: `Raise work_mem for this session so the bitmap stays exact (no lossy blocks, no rechecks) on ${rel}; alternatively make the index condition more selective or add a composite index so the bitmap is smaller.`,\n steps: [\n \"Increase work_mem for the session, then re-run EXPLAIN (ANALYZE) and confirm Lossy Heap Blocks drops to 0.\",\n \"If raising work_mem is undesirable, make the index condition more selective (a more selective leading column or a composite index over the filtered columns) so fewer heap pages enter the bitmap.\",\n ],\n commands: [\n {\n label: \"Give this session more work_mem\",\n sql: \"SET work_mem = '<X>MB';\",\n },\n {\n label: \"Or shrink the bitmap with a more selective index\",\n sql: `CREATE INDEX ON ${rel} (<more selective / composite columns>);`,\n },\n ],\n },\n docsUrl: `${DOCS}/runtime-config-resource.html#GUC-WORK-MEM`,\n meta: { lossyBlocks: lossy, exactBlocks: exact },\n }),\n ];\n },\n};\n","import type { PlanNode, Rule } from \"../../core/model.ts\";\nimport { fmtInt } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/** Measured rows if available, else the planner estimate. */\nfunction rowsOf(node: PlanNode): number {\n return node.metrics.totalRows ?? node.planRows;\n}\n\n/**\n * Nested Loop with no join predicate anywhere — neither a Join Filter on the loop\n * nor an Index Cond / Recheck Cond on the inner side. Every outer row is paired with\n * every inner row, so the result is the cross product (rows ≈ outer × inner). This is\n * almost always a forgotten ON / WHERE join condition; precision is kept high by\n * requiring both sides to actually produce rows.\n */\nexport const cartesianProduct: Rule = {\n id: \"PGX_CARTESIAN_PRODUCT\",\n title: \"Cartesian product (missing join condition)\",\n defaultSeverity: \"error\",\n check(node, ctx) {\n if (node.nodeType !== \"Nested Loop\") return [];\n if (node.joinFilter) return [];\n\n const inner = node.children[1];\n if (!inner) return [];\n // A join key on the inner side (index lookup) means there IS a predicate.\n if (inner.indexCond || inner.recheckCond) return [];\n\n const outer = node.children[0];\n if (!outer) return [];\n\n const outerRows = rowsOf(outer);\n const innerRows = rowsOf(inner);\n // Single-row sides are legitimately matched against everything (e.g. a LIMIT 1\n // or aggregate); a cross product is only meaningful when both sides are sets.\n if (outerRows <= 1 || innerRows <= 1) return [];\n\n const estimated = node.metrics.totalRows === undefined;\n const product = fmtInt(outerRows * innerRows);\n\n return [\n makeFinding(cartesianProduct, ctx, node, {\n title: `Cartesian product: Nested Loop with no join condition (~${product}${estimated ? \" est.\" : \"\"} rows)`,\n detail: `The Nested Loop has no Join Filter and the inner side has no Index Cond or Recheck Cond, so each of ${fmtInt(\n outerRows,\n )} outer rows is paired with every one of ${fmtInt(innerRows)} inner rows${\n estimated ? \" (estimated — run with ANALYZE for actuals)\" : \"\"\n }.`,\n cause:\n \"No predicate links the two relations, so Postgres can only emit the full cross product. This usually means an ON or WHERE join condition was omitted (e.g. a comma join across tables).\",\n remediation: {\n summary:\n \"Add the missing join condition linking the two tables on their key columns (e.g. ON a.id = b.a_id). If a cross product is truly intended, make it explicit with CROSS JOIN and bound it with a LIMIT or aggregation.\",\n steps: [\n \"Find the two relations feeding this Nested Loop in your query.\",\n \"Add an ON (or WHERE) clause matching their key columns so the loop becomes selective.\",\n \"If you really want every combination, write CROSS JOIN explicitly and cap the size with LIMIT or an aggregate.\",\n ],\n commands: [\n {\n label: \"Add the join predicate\",\n sql: \"SELECT ...\\nFROM <outer_table> a\\nJOIN <inner_table> b ON a.<key> = b.<key>;\",\n },\n {\n label: \"Or make the cross join explicit and bounded\",\n sql: \"SELECT ...\\nFROM <outer_table> a\\nCROSS JOIN <inner_table> b\\nLIMIT <n>;\",\n },\n ],\n },\n docsUrl: `${DOCS}/queries-table-expressions.html#QUERIES-JOIN`,\n meta: { outerRows: Math.round(outerRows), innerRows: Math.round(innerRows) },\n }),\n ];\n },\n};\n","import type { Rule } from \"../../core/model.ts\";\nimport { fmtInt } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * A correlated subquery surfaces as a SubPlan node whose `actualLoops` equals the\n * number of outer rows: the planner re-executes it once per row instead of running\n * it once. Above the loop threshold this dominates execution time. The fix is to\n * de-correlate it — rewrite as a JOIN/LATERAL or hoist into a CTE evaluated once.\n */\nexport const correlatedSubplan: Rule = {\n id: \"PGX_CORRELATED_SUBPLAN\",\n title: \"Correlated subplan re-executed per row\",\n defaultSeverity: \"warn\",\n requiresAnalyze: true,\n check(node, ctx) {\n const isSubplan =\n node.parentRelationship === \"SubPlan\" || (node.subplanName?.startsWith(\"SubPlan\") ?? false);\n if (!isSubplan) return [];\n\n const loops = node.actualLoops ?? 0;\n if (loops <= ctx.thresholds.correlatedLoops) return [];\n\n const name = node.subplanName ?? \"the subplan\";\n\n return [\n makeFinding(correlatedSubplan, ctx, node, {\n title: `Correlated ${name} re-executed ${fmtInt(loops)} times`,\n detail: `${name} ran ${fmtInt(loops)} times — once per outer row — instead of being evaluated a single time.`,\n cause:\n \"The subquery references a column from the enclosing query, so the planner cannot pull it out of the per-row loop and re-runs the whole subplan for every outer row.\",\n remediation: {\n summary: `De-correlate the subquery: rewrite it as a JOIN or LATERAL join, or hoist it into a CTE/derived table evaluated once, then index the correlation key so the rewrite stays cheap.`,\n steps: [\n \"Identify the outer column the subquery references (the correlation key).\",\n \"For a scalar subquery in SELECT/WHERE, rewrite it as a LEFT JOIN to a grouped derived table, or a LATERAL join when it returns per-row results.\",\n \"For EXISTS/IN, prefer the semi-join form (EXISTS / = ANY) the planner can de-correlate into a single hash/merge join.\",\n \"Add an index on the correlation key so the resulting JOIN does not fall back to the same per-row cost.\",\n // Before (correlated, runs once per outer row):\n // SELECT o.id, (SELECT count(*) FROM events e WHERE e.order_id = o.id) AS n FROM orders o;\n // After (evaluated once, joined):\n // SELECT o.id, COALESCE(e.n, 0) AS n\n // FROM orders o\n // LEFT JOIN (SELECT order_id, count(*) AS n FROM events GROUP BY order_id) e\n // ON e.order_id = o.id;\n \"See the before/after sketch: SELECT (SELECT count(*) FROM events e WHERE e.order_id = o.id) becomes a LEFT JOIN to (SELECT order_id, count(*) FROM events GROUP BY order_id).\",\n ],\n commands: [\n {\n label: \"Index the correlation key so the de-correlated JOIN stays cheap\",\n sql: \"CREATE INDEX ON <subquery table> (<correlation key column>);\",\n },\n ],\n },\n docsUrl: `${DOCS}/queries-table-expressions.html#QUERIES-LATERAL`,\n meta: { loops },\n }),\n ];\n },\n};\n","import type { Rule } from \"../../core/model.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * Hint: an Index Scan that projects only a few columns and applies no residual\n * filter (the whole predicate lives in the Index Cond) MIGHT qualify for an\n * Index Only Scan if the index covers every selected column. We cannot see the\n * index definition from EXPLAIN, so this is low-confidence — phrased as a\n * suggestion and kept at `info`. Requires VERBOSE for the Output column list.\n */\nexport const couldBeIndexOnly: Rule = {\n id: \"PGX_COULD_BE_INDEX_ONLY\",\n title: \"Index scan may be eligible for index-only\",\n defaultSeverity: \"info\",\n check(node, ctx) {\n if (node.nodeType !== \"Index Scan\") return [];\n if (!node.indexName) return [];\n // A residual Filter means columns beyond the index are needed for the\n // predicate, so it cannot become index-only — skip those.\n if (node.filter) return [];\n // Need VERBOSE output to know which columns are projected.\n if (!node.output || node.output.length === 0) return [];\n // Only hint for a small, plausibly-coverable column set.\n if (node.output.length > 4) return [];\n\n const rel = node.relationName ?? \"the table\";\n const cols = node.output;\n const colList = cols.join(\", \");\n const includeCols = cols.join(\", \");\n\n return [\n makeFinding(couldBeIndexOnly, ctx, node, {\n title: `Index Scan using ${node.indexName} on ${rel} may be eligible for index-only`,\n detail: `This Index Scan projects only ${cols.length} column${\n cols.length === 1 ? \"\" : \"s\"\n } (${colList}) and applies no residual filter, so its predicate is fully resolved by ${node.indexName}. If that index also covers the selected columns, Postgres could use an Index Only Scan and skip the heap entirely.`,\n cause:\n \"An Index Scan still visits the table heap to fetch the projected columns. When every selected column is contained in the index (as a key or INCLUDE column) and the visibility map is current, Postgres can answer from the index alone (Index Only Scan).\",\n remediation: {\n summary: `Add the selected columns (${includeCols}) to ${node.indexName} as INCLUDE columns so it covers the query, then keep the visibility map current with VACUUM so Postgres can switch ${rel} to an Index Only Scan.`,\n steps: [\n \"Confirm which columns the index already covers (\\\\d <index> in psql) — this hint assumes VERBOSE Output and cannot read the index definition.\",\n \"If any projected column is missing, recreate the index with those columns as INCLUDE (non-key) columns.\",\n \"Run VACUUM so the visibility map is set; Index Only Scans fall back to heap fetches on pages not marked all-visible.\",\n ],\n commands: [\n {\n label: \"Create a covering index\",\n sql: `CREATE INDEX ON ${rel} (<key columns from the Index Cond>) INCLUDE (${includeCols});`,\n },\n {\n label: \"Keep the visibility map current\",\n sql: `VACUUM ${rel};`,\n },\n ],\n },\n docsUrl: `${DOCS}/indexes-index-only-scans.html`,\n meta: { outputColumns: cols.length },\n }),\n ];\n },\n};\n","import type { Rule } from \"../../core/model.ts\";\nimport { fmtInt } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * An index/bitmap scan that still applies a residual Filter after the index lookup.\n * The Filter is evaluated on every heap row the index returned; folding those columns\n * into the index lets Postgres apply them as an Index Cond during traversal, skipping\n * the rows entirely. This is a hint (severity info): a non-sargable predicate cannot be\n * indexed, so the fix is phrased around making the filter index-friendly.\n */\nexport const filterCouldBeIndexCond: Rule = {\n id: \"PGX_FILTER_COULD_BE_INDEX_COND\",\n title: \"Filter could be an index condition\",\n defaultSeverity: \"info\",\n requiresAnalyze: true,\n check(node, ctx) {\n const indexed =\n node.nodeType === \"Index Scan\" ||\n node.nodeType === \"Index Only Scan\" ||\n node.nodeType === \"Bitmap Heap Scan\";\n if (!indexed) return [];\n if (!node.filter) return [];\n if (!node.indexCond && !node.recheckCond) return [];\n if ((node.rowsRemovedByFilter ?? 0) <= 0) return [];\n\n const rel = node.relationName ?? \"the table\";\n const cond = node.indexCond ?? node.recheckCond ?? \"\";\n const loops = node.actualLoops ?? 1;\n const removed = (node.rowsRemovedByFilter ?? 0) * loops;\n\n return [\n makeFinding(filterCouldBeIndexCond, ctx, node, {\n title: `Residual filter on ${rel} could be an index condition`,\n detail: `${node.nodeType} on ${rel} used the index for ${cond} but then applied Filter ${node.filter} to the fetched rows, discarding ${fmtInt(removed)} of them.`,\n cause: `The Filter columns are not part of the index, so Postgres must fetch each row the index matched and re-check the predicate in the executor instead of skipping non-matching entries during the index traversal.`,\n remediation: {\n summary: `Extend the index on ${rel} to include the Filter columns from ${node.filter} as trailing key columns, so the predicate is applied as an Index Cond during traversal instead of as a post-fetch Filter.`,\n steps: [\n `Confirm the Filter ${node.filter} is sargable — no functions or implicit casts wrapping the column.`,\n \"Append the filter columns after the existing key columns so the index still serves the original lookup.\",\n \"Re-run EXPLAIN (ANALYZE) and check the Filter moved into the Index Cond with no Rows Removed by Filter.\",\n ],\n commands: [\n {\n label: \"Extend the index with the filter columns\",\n sql: `CREATE INDEX ON ${rel} (<existing key columns>, <filter columns>);`,\n },\n ],\n },\n docsUrl: `${DOCS}/indexes-multicolumn.html`,\n meta: { rowsRemovedByFilter: Math.round(removed) },\n }),\n ];\n },\n};\n","import type { Rule } from \"../../core/model.ts\";\nimport { fmtInt, fmtKiB, roundUpMiB } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * A Hash node split its build side into multiple batches, meaning the hash table did\n * not fit in work_mem and spilled to disk. The ideal is a single batch; more batches\n * than originally planned (hashBatches > originalHashBatches) means Postgres also had\n * to re-partition at runtime after under-sizing the build side.\n */\nexport const hashSpillDisk: Rule = {\n id: \"PGX_HASH_SPILL_DISK\",\n title: \"Hash join spilled to disk\",\n defaultSeverity: \"warn\",\n requiresAnalyze: true,\n check(node, ctx) {\n if (node.nodeType !== \"Hash\") return [];\n\n const hashBatches = node.hashBatches ?? 1;\n if (hashBatches <= 1) return [];\n\n const originalHashBatches = node.originalHashBatches ?? hashBatches;\n const repartitioned = hashBatches > originalHashBatches;\n\n // Size work_mem to hold the whole build side (peak memory + what spilled) with headroom.\n const peakKiB = node.peakMemoryUsage ?? 0;\n const diskKiB = node.diskUsage ?? 0;\n const workMemRecommended = roundUpMiB((peakKiB + diskKiB) * 1.2);\n\n return [\n makeFinding(hashSpillDisk, ctx, node, {\n title: `Hash build side spilled to disk (${fmtInt(hashBatches)} batches)`,\n detail: `The hash table was split into ${fmtInt(hashBatches)} batches${\n repartitioned ? ` (up from ${fmtInt(originalHashBatches)} planned)` : \"\"\n }, so the build side did not fit in work_mem and overflowed to temporary files${\n diskKiB > 0 ? ` (${fmtKiB(diskKiB)} written to disk)` : \"\"\n }.`,\n cause: repartitioned\n ? \"Postgres had to add batches at runtime because the build side was larger than estimated — usually a row underestimate sized work_mem too small.\"\n : \"The build (hash) side was larger than work_mem, forcing the hash join to partition it across disk-backed batches.\",\n remediation: {\n summary: `Raise work_mem to about ${workMemRecommended} so the build side fits in a single batch, and make sure the SMALLER input is the hash/build side (a wrong build side usually comes from a row underestimate — fix the stats). Reducing build-side rows also avoids the spill.`,\n steps: [\n `Set work_mem high enough to hold the build side in one batch (~${workMemRecommended} here) at session or role scope, not globally — every sort/hash node can use work_mem, so a global bump can exhaust memory.`,\n \"Confirm the smaller relation is on the build (Hash) side; if Postgres chose the larger side, a row underestimate is likely — re-run ANALYZE or raise statistics targets so the planner picks the smaller build side.\",\n \"Alternatively, filter or aggregate the build side earlier so fewer rows need to be hashed.\",\n ],\n commands: [\n {\n label: \"Raise work_mem for this session\",\n sql: `SET work_mem = '${workMemRecommended}';`,\n },\n {\n label: \"Or set it for a specific role\",\n sql: `ALTER ROLE <role> SET work_mem = '${workMemRecommended}';`,\n },\n {\n label: \"Refresh planner statistics on the build-side table\",\n sql: \"ANALYZE <build_side_table>;\",\n },\n ],\n },\n docsUrl: `${DOCS}/runtime-config-resource.html#GUC-WORK-MEM`,\n meta: { hashBatches, workMemRecommended },\n }),\n ];\n },\n};\n","import type { Rule } from \"../../core/model.ts\";\nimport { fmtInt, fmtPct } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * A node reads many rows then throws most of them away via a post-read Filter. The\n * discarded rows were still fetched and examined, so the work is wasted. Pushing the\n * predicate into an index turns the Filter into an Index Cond, letting Postgres skip\n * the non-matching rows entirely instead of reading and rejecting them.\n */\nexport const highFilterDiscard: Rule = {\n id: \"PGX_HIGH_FILTER_DISCARD\",\n title: \"Filter discards most rows read\",\n defaultSeverity: \"warn\",\n requiresAnalyze: true,\n check(node, ctx) {\n const ratio = node.metrics.filterDiscardRatio;\n if (ratio === undefined || ratio <= ctx.thresholds.filterDiscardRatio) return [];\n\n const removed = (node.rowsRemovedByFilter ?? 0) * (node.actualLoops ?? 1);\n if (removed <= ctx.thresholds.filterRemovedAbs) return [];\n\n const rel = node.relationName ?? \"the table\";\n const kept = node.metrics.totalRows ?? 0;\n const discardPct = ratio * 100;\n const filter = node.filter ?? \"the filter predicate\";\n\n return [\n makeFinding(highFilterDiscard, ctx, node, {\n title: `Filter on ${rel} discards ${fmtPct(discardPct)} of rows read`,\n detail: `Postgres read this node's rows then dropped ${fmtInt(removed)} of them (${fmtPct(\n discardPct,\n )}), keeping only ${fmtInt(kept)}, via the post-read filter ${filter}.`,\n cause: `The predicate ${filter} is evaluated as a Filter after the rows are fetched, so every discarded row was still read and examined — work no index condition narrowed.`,\n remediation: {\n summary: `Move ${filter} into an index on ${rel} so the predicate becomes an Index Cond instead of a post-read Filter, letting Postgres skip the non-matching rows. For a low-cardinality predicate, a partial index keyed on the discarded condition is smaller and faster.`,\n steps: [\n \"Identify the column(s) referenced by the filter above.\",\n \"Ensure the predicate is sargable (no function-wrapping or implicit casts on the indexed column).\",\n \"Use a plain index when the columns are selective across queries; use a partial index when the same constant predicate is always applied.\",\n ],\n commands: [\n {\n label: \"Index the filter columns\",\n sql: `CREATE INDEX ON ${rel} (<filter columns>);`,\n },\n {\n label: \"Or a partial index for a fixed low-cardinality predicate\",\n sql: `CREATE INDEX ON ${rel} (<filter columns>) WHERE <predicate>;`,\n },\n ],\n },\n docsUrl: `${DOCS}/indexes-partial.html`,\n meta: { discardPct: Math.round(discardPct) },\n }),\n ];\n },\n};\n","import type { Rule } from \"../../core/model.ts\";\nimport { fmtInt } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * Index-only scan that still hit the heap. Each heap fetch means the visibility map\n * marked that page as not all-visible, so Postgres had to read the table row to check\n * visibility — defeating the index-only optimization. The usual cause is a table that\n * has not been vacuumed recently enough relative to its write rate.\n */\nexport const indexOnlyHeapFetches: Rule = {\n id: \"PGX_INDEX_ONLY_HEAP_FETCHES\",\n title: \"Index-only scan with heap fetches\",\n defaultSeverity: \"info\",\n requiresAnalyze: true,\n check(node, ctx) {\n if (node.nodeType !== \"Index Only Scan\") return [];\n\n const heapFetches = node.heapFetches ?? 0;\n if (heapFetches <= 0) return [];\n\n const rows = Math.max(node.metrics.totalRows ?? 1, 1);\n const ratio = heapFetches / rows;\n if (ratio <= ctx.thresholds.heapFetchRatio && heapFetches <= ctx.thresholds.heapFetchAbs) {\n return [];\n }\n\n const rel = node.relationName ?? \"the table\";\n\n return [\n makeFinding(indexOnlyHeapFetches, ctx, node, {\n title: `Index-only scan on ${rel} did ${fmtInt(heapFetches)} heap fetches`,\n detail: `The index-only scan on ${rel} fell back to the heap ${fmtInt(heapFetches)} times for ${fmtInt(\n rows,\n )} rows produced. Each fetch is an extra table page read the index-only path was meant to avoid.`,\n cause: `Heap fetches happen when the visibility map does not mark the pages as all-visible, so Postgres must read the table row to confirm visibility. This usually means ${rel} has not been vacuumed recently enough for its write/update rate.`,\n remediation: {\n summary: `Run VACUUM (or VACUUM ANALYZE) on ${rel} to refresh the visibility map so the index-only scan can skip the heap. For a high-churn table, lower autovacuum_vacuum_scale_factor so autovacuum keeps the map current.`,\n steps: [\n `VACUUM ${rel} to update the visibility map; add ANALYZE if statistics are also stale.`,\n \"If heap fetches keep returning, the table is updated faster than autovacuum runs — make autovacuum more aggressive on it.\",\n \"Confirm the scan stays index-only afterwards by re-running EXPLAIN (ANALYZE) and checking Heap Fetches drops toward 0.\",\n ],\n commands: [\n {\n label: \"Refresh the visibility map\",\n sql: `VACUUM (ANALYZE) ${rel};`,\n },\n {\n label: \"Keep the map current on a high-churn table\",\n sql: `ALTER TABLE ${rel} SET (autovacuum_vacuum_scale_factor = 0.02);`,\n },\n ],\n },\n docsUrl: `${DOCS}/indexes-index-only-scans.html`,\n meta: { heapFetches },\n }),\n ];\n },\n};\n","import { nodeLabel } from \"../../core/metrics.ts\";\nimport type { Rule } from \"../../core/model.ts\";\nimport { fmtBlocks, fmtPct } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/** Below this many disk-read blocks the cold-cache noise outweighs any real signal. */\nconst MIN_READ_BLOCKS = 1000;\n\n/**\n * Low shared-buffer cache hit ratio: the node fetched many pages from disk rather\n * than from PostgreSQL's buffer cache. This is often just a cold cache on the first\n * run, so the finding is informational and leads with \"re-run to confirm\" before\n * suggesting shared_buffers sizing or a more selective index.\n */\nexport const lowCacheHit: Rule = {\n id: \"PGX_LOW_CACHE_HIT\",\n title: \"Low cache hit ratio (heavy disk reads)\",\n defaultSeverity: \"info\",\n requiresBuffers: true,\n check(node, ctx) {\n const ratio = node.metrics.cacheHitRatio;\n const readBlocks = node.sharedReadBlocks ?? 0;\n if (ratio == null) return [];\n if (ratio >= ctx.thresholds.lowCacheHitRatio) return [];\n if (readBlocks <= MIN_READ_BLOCKS) return [];\n\n const label = nodeLabel(node);\n const rel = node.relationName;\n const ratioPct = ratio * 100;\n\n return [\n makeFinding(lowCacheHit, ctx, node, {\n title: `Low cache hit ratio at ${label} (${fmtPct(ratioPct)})`,\n detail: `${label} served only ${fmtPct(ratioPct)} of its shared-buffer accesses from cache, reading ${fmtBlocks(readBlocks)} from disk.`,\n cause:\n \"The pages this node needed were not resident in shared_buffers, so PostgreSQL had to read them from disk. On a first run this is an expected cold cache; if it persists, the working set is larger than the cache or the scan touches more pages than necessary.\",\n remediation: {\n summary: `Re-run the query to check whether this is just a cold cache — the ratio should climb on a warm run. If it stays low, the working set exceeds shared_buffers: size shared_buffers/effective_cache_size to your RAM, or add a selective index on ${rel ?? \"the scanned relation\"} so far fewer pages are read.`,\n steps: [\n \"Run the same EXPLAIN (ANALYZE, BUFFERS) a second time; a much higher hit ratio means the first run was a cold cache and no action is needed.\",\n \"If the ratio stays low, check whether shared_buffers (and effective_cache_size for planner costing) are sized to the machine's RAM.\",\n \"If the node reads far more pages than the rows it returns, add a selective index so only matching pages are fetched.\",\n ],\n commands: [\n {\n label: \"Inspect current buffer-cache sizing\",\n sql: \"SHOW shared_buffers; SHOW effective_cache_size;\",\n },\n {\n label: \"Reduce pages read with a selective index\",\n sql: `CREATE INDEX ON ${rel ?? \"<table>\"} (<predicate columns>);`,\n },\n ],\n },\n docsUrl: `${DOCS}/runtime-config-resource.html#GUC-SHARED-BUFFERS`,\n meta: { cacheHitPct: Math.round(ratioPct * 10) / 10, readBlocks },\n }),\n ];\n },\n};\n","import { nodeLabel } from \"../../core/metrics.ts\";\nimport type { Rule } from \"../../core/model.ts\";\nimport { fmtInt } from \"../../util/format.ts\";\nimport { DOCS, makeFinding, outerChild } from \"./util.ts\";\n\n/**\n * Nested loop whose outer (driving) side produced many rows. A nested loop runs the\n * inner subtree once per outer row, so a large outer side multiplies the inner cost.\n * The planner usually picks this only when it expects few outer rows — so the root\n * cause is normally a cardinality misestimate. Fix the estimate first (so it switches\n * to a hash/merge join); if the estimate is right, index the inner join key.\n */\nexport const nestedLoopLargeOuter: Rule = {\n id: \"PGX_NESTED_LOOP_LARGE_OUTER\",\n title: \"Nested loop with a large outer side\",\n defaultSeverity: \"warn\",\n requiresAnalyze: true,\n check(node, ctx) {\n if (node.nodeType !== \"Nested Loop\") return [];\n\n const outer = outerChild(node);\n const outerRows = outer?.metrics.totalRows;\n if (outerRows === undefined || outerRows <= ctx.thresholds.nestedLoopOuterRows) return [];\n\n const outerLabel = outer ? nodeLabel(outer) : \"the outer side\";\n const inner = node.children[1];\n const innerLabel = inner ? nodeLabel(inner) : \"the inner side\";\n const innerCond = inner?.indexCond ?? inner?.joinFilter ?? inner?.filter ?? node.joinFilter;\n const misestimated = outer?.metrics.estimateDirection === \"under\";\n\n return [\n makeFinding(nestedLoopLargeOuter, ctx, node, {\n title: `Nested loop driven by ${fmtInt(outerRows)} outer rows (${outerLabel})`,\n detail: `The nested loop's outer side (${outerLabel}) produced ${fmtInt(\n outerRows,\n )} rows, so its inner side (${innerLabel}) is re-executed roughly that many times.`,\n cause: misestimated\n ? `The planner expected far fewer outer rows than the ${fmtInt(\n outerRows,\n )} that actually came back, so it chose a per-row nested loop where a single hash/merge join would have been cheaper.`\n : `A nested loop probes the inner side once per outer row; with ${fmtInt(\n outerRows,\n )} outer rows that is ${fmtInt(outerRows)} inner executions.`,\n remediation: {\n summary: `Fix the outer-side row estimate first — re-ANALYZE ${\n outer?.relationName ?? \"the driving table\"\n }, raise its column statistics, or add extended statistics — so the planner switches to a hash or merge join. If the estimate is already accurate, add an index on the inner join key (${\n innerCond ?? \"<inner join column>\"\n }) so each of the ${fmtInt(outerRows)} probes is cheap.`,\n steps: [\n \"Compare the outer node's estimated vs actual rows: a large gap means the estimate is the real problem.\",\n \"Refresh statistics so the planner sees the true cardinality and can prefer a hash/merge join.\",\n \"If columns are correlated, create extended (multivariate) statistics on them.\",\n \"If estimates are already correct, index the inner join key so each probe is an index lookup, not a scan.\",\n \"As a last resort to confirm the diagnosis, test with `SET enable_nestloop = off` for this query only.\",\n ],\n commands: [\n {\n label: \"Refresh planner statistics on the driving table\",\n sql: `ANALYZE ${outer?.relationName ?? \"<outer table>\"};`,\n },\n {\n label: \"Increase statistics target on the misestimated column, then re-ANALYZE\",\n sql: `ALTER TABLE ${\n outer?.relationName ?? \"<outer table>\"\n } ALTER COLUMN <column> SET STATISTICS 1000;\\nANALYZE ${\n outer?.relationName ?? \"<outer table>\"\n };`,\n },\n {\n label: \"Add extended statistics for correlated columns\",\n sql: `CREATE STATISTICS ${\n outer?.relationName ?? \"<outer table>\"\n }_stats (dependencies, ndistinct) ON <col_a>, <col_b> FROM ${\n outer?.relationName ?? \"<outer table>\"\n };\\nANALYZE ${outer?.relationName ?? \"<outer table>\"};`,\n },\n {\n label: \"If estimates are correct, index the inner join key\",\n sql: `CREATE INDEX ON ${\n inner?.relationName ?? \"<inner table>\"\n } (<inner join column>);`,\n },\n {\n label: \"Confirm the diagnosis by disabling nested loops for this query only\",\n sql: \"SET enable_nestloop = off;\",\n },\n ],\n },\n docsUrl: `${DOCS}/runtime-config-query.html`,\n meta: { outerRows: Math.round(outerRows) },\n }),\n ];\n },\n};\n","import type { Rule } from \"../../core/model.ts\";\nimport { fmtInt } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * The planner's row estimate is wildly off from the actual row count. Bad estimates\n * cascade into bad join/sort/memory choices, so a large factor — especially an\n * underestimate feeding a nested loop or hash — is a leading cause of slow plans.\n * Usually it means statistics are stale or too coarse for the predicate.\n */\nexport const rowMisestimate: Rule = {\n id: \"PGX_ROW_MISESTIMATE\",\n title: \"Row count misestimate\",\n defaultSeverity: \"info\",\n requiresAnalyze: true,\n check(node, ctx) {\n const { estimateFactor, estimateDirection, totalRows } = node.metrics;\n if (estimateFactor === undefined) return [];\n if (estimateFactor < ctx.thresholds.misestimateFactor) return [];\n if (estimateDirection === undefined || estimateDirection === \"accurate\") return [];\n\n // Cut noise: a 20× error on 3 rows is irrelevant; only care at real volume.\n const rows = Math.max(totalRows ?? 0, node.planRows);\n if (rows < 100) return [];\n\n const factor = Math.round(estimateFactor);\n const rel = node.relationName;\n const onRel = rel ? ` on ${rel}` : \"\";\n const target = rel ?? \"the underlying table\";\n const under = estimateDirection === \"under\";\n const direction = under ? \"underestimate\" : \"overestimate\";\n\n const actual = totalRows ?? 0;\n const detail = `Postgres estimated ${fmtInt(node.planRows)} rows but ${fmtInt(actual)} were produced — a ${fmtInt(factor)}x ${direction}${onRel}.`;\n\n return [\n makeFinding(rowMisestimate, ctx, node, {\n // Severity: underestimates are the dangerous ones (under-sized joins/memory).\n severity: under ? \"warn\" : \"info\",\n title: `${fmtInt(factor)}x row ${direction}${onRel}`,\n detail,\n cause:\n \"The planner's row estimate is based on statistics that are stale, missing, or too coarse for this predicate (e.g. correlated columns the planner treats as independent).\",\n remediation: {\n summary: `Refresh and sharpen statistics for ${target}: run ANALYZE ${rel ?? \"<relation>\"}, raise per-column statistics targets on the predicate columns, and add extended statistics for correlated columns so the planner estimates rows correctly.${\n under\n ? \" Underestimates feeding a nested loop or hash join are the highest priority — fix these first.\"\n : \"\"\n }`,\n steps: [\n `Refresh table statistics first; this alone often fixes the estimate.`,\n `If the column has a skewed/uneven distribution, raise its statistics target and re-ANALYZE.`,\n `If the predicate spans multiple correlated columns, create extended statistics so the planner stops assuming independence.`,\n ],\n commands: [\n {\n label: \"Refresh statistics\",\n sql: `ANALYZE ${rel ?? \"<relation>\"};`,\n },\n {\n label: \"Raise per-column statistics target\",\n sql: `ALTER TABLE ${rel ?? \"<relation>\"} ALTER COLUMN <column> SET STATISTICS 1000;\\nANALYZE ${rel ?? \"<relation>\"};`,\n },\n {\n label: \"Add extended statistics for correlated columns\",\n sql: `CREATE STATISTICS <stats_name> (dependencies, ndistinct) ON <col_a>, <col_b> FROM ${rel ?? \"<relation>\"};\\nANALYZE ${rel ?? \"<relation>\"};`,\n },\n ],\n },\n docsUrl: `${DOCS}/planner-stats.html`,\n meta: {\n estimatedRows: Math.round(node.planRows),\n actualRows: Math.round(actual),\n factor,\n direction: estimateDirection,\n },\n }),\n ];\n },\n};\n","import type { Rule } from \"../../core/model.ts\";\nimport { fmtInt } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * Sequential scan reading a large relation. Often an index would let Postgres skip\n * most of the table. If the scan genuinely needs most rows it is correct, so the fix\n * is phrased around the predicate.\n */\nexport const seqScanLarge: Rule = {\n id: \"PGX_SEQ_SCAN_LARGE\",\n title: \"Sequential scan on a large table\",\n defaultSeverity: \"warn\",\n check(node, ctx) {\n if (node.nodeType !== \"Seq Scan\") return [];\n\n // Prefer measured rows; fall back to the estimate on cost-only plans.\n const rows = node.metrics.totalRows ?? node.planRows;\n if (rows < ctx.thresholds.seqScanRows) return [];\n\n const rel = node.relationName ?? \"the table\";\n const estimated = node.metrics.totalRows === undefined;\n const filterCols = node.filter ? ` matching ${node.filter}` : \"\";\n\n return [\n makeFinding(seqScanLarge, ctx, node, {\n title: `Sequential scan on ${rel} (${fmtInt(rows)}${estimated ? \" est.\" : \"\"} rows)`,\n detail: `Postgres read ${rel} sequentially, scanning roughly ${fmtInt(rows)} rows${\n estimated ? \" (estimated — run with ANALYZE for actuals)\" : \"\"\n }.`,\n cause: node.filter\n ? `A row filter (${node.filter}) is applied after reading every row, so no index narrowed the scan.`\n : \"No index condition narrowed the scan, so the whole relation was read.\",\n remediation: {\n summary: `Add an index covering the WHERE/JOIN predicate on ${rel} so Postgres can skip non-matching rows. If the query genuinely needs most of the table, the seq scan is correct — reduce the rows touched instead.`,\n steps: [\n \"Identify the selective columns in the WHERE/JOIN predicate.\",\n \"Ensure they are sargable (no function-wrapping or implicit casts on the column).\",\n \"If selectivity is low, a partial index (WHERE …) may be better.\",\n ],\n commands: [\n {\n label: \"Index the predicate columns\",\n sql: `CREATE INDEX ON ${rel} (<predicate columns>)${filterCols ? \" -- columns from the filter above\" : \"\"};`,\n },\n ],\n },\n docsUrl: `${DOCS}/indexes-intro.html`,\n meta: { rows: Math.round(rows) },\n }),\n ];\n },\n};\n","import { executionMs } from \"../../core/metrics.ts\";\nimport type { Rule } from \"../../core/model.ts\";\nimport { fmtMs, fmtPct } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * JIT compilation time dominates total execution. Common on short queries whose plan\n * cost crossed `jit_above_cost`: the one-off cost of generating/optimizing machine code\n * outweighs the runtime it saves, so the query would have been faster with JIT off.\n * Tree-level rule — only acts at the root.\n */\nexport const significantJit: Rule = {\n id: \"PGX_SIGNIFICANT_JIT\",\n title: \"JIT compilation dominates execution\",\n defaultSeverity: \"info\",\n requiresAnalyze: true,\n check(node, ctx) {\n if (node !== ctx.tree.root) return [];\n\n const t = ctx.tree.jit?.timing;\n const jitTotal =\n t?.total ??\n (t?.generation ?? 0) + (t?.inlining ?? 0) + (t?.optimization ?? 0) + (t?.emission ?? 0);\n const execMs = executionMs(ctx.tree);\n if (!execMs || jitTotal <= 0) return [];\n\n const jitPct = (100 * jitTotal) / execMs;\n if (jitPct <= ctx.thresholds.jitPct) return [];\n\n return [\n makeFinding(significantJit, ctx, node, {\n title: `JIT compilation took ${fmtMs(jitTotal)} (${fmtPct(jitPct)} of execution)`,\n detail: `JIT spent ${fmtMs(jitTotal)} generating, optimizing, and emitting machine code, out of ${fmtMs(\n execMs,\n )} total execution time. The compilation overhead outweighs the runtime it saved.`,\n cause:\n \"The plan's estimated cost crossed jit_above_cost, so Postgres JIT-compiled the query — but the query is too short for compilation to pay off, often because a row overestimate inflated the cost.\",\n remediation: {\n summary:\n \"Raise jit_above_cost (and jit_inline_above_cost / jit_optimize_above_cost) so short queries skip JIT, or disable JIT for this session with SET jit = off. Then investigate why the cost estimate is high enough to trigger JIT — frequently a row overestimate fixable with ANALYZE.\",\n steps: [\n \"Confirm the query is consistently short-running before tuning — JIT pays off on long, CPU-bound queries.\",\n \"Raise jit_above_cost above this plan's total cost so similar queries skip JIT entirely.\",\n \"If only inlining/optimization are expensive, raise jit_inline_above_cost / jit_optimize_above_cost instead of disabling JIT.\",\n \"Check the planner's row estimates against actuals — an overestimate that inflates cost is the usual reason a cheap query triggers JIT; run ANALYZE on the relations involved.\",\n ],\n commands: [\n { label: \"Disable JIT for this session\", sql: \"SET jit = off;\" },\n {\n label: \"Raise the JIT cost thresholds\",\n sql: \"SET jit_above_cost = <above this plan's total cost>;\\nSET jit_inline_above_cost = <higher>;\\nSET jit_optimize_above_cost = <higher>;\",\n },\n {\n label: \"Refresh statistics if the cost is driven by a row overestimate\",\n sql: \"ANALYZE <table>;\",\n },\n ],\n },\n docsUrl: `${DOCS}/runtime-config-query.html#GUC-JIT-ABOVE-COST`,\n meta: { jitMs: Math.round(jitTotal), jitPct: Math.round(jitPct) },\n }),\n ];\n },\n};\n","import type { Rule } from \"../../core/model.ts\";\nimport { fmtKiB, roundUpMiB } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * A Sort node spilled to disk because it exceeded work_mem. External merge sorts do\n * extra temp-file I/O and are far slower than an in-memory quicksort. Either raise\n * work_mem for this query, or feed the sort pre-ordered rows via a matching index.\n */\nexport const sortSpillDisk: Rule = {\n id: \"PGX_SORT_SPILL_DISK\",\n title: \"Sort spilled to disk\",\n defaultSeverity: \"warn\",\n requiresAnalyze: true,\n check(node, ctx) {\n if (node.nodeType !== \"Sort\") return [];\n\n const onDisk =\n node.sortSpaceType === \"Disk\" ||\n (node.sortMethod !== undefined && /external/i.test(node.sortMethod));\n if (!onDisk) return [];\n\n // Recommend ~2.2× the disk footprint (sort overhead vs. raw data) rounded up to MiB.\n const usedKiB = node.sortSpaceUsed ?? 0;\n const workMemRecommended = roundUpMiB(usedKiB > 0 ? usedKiB * 2.2 : 0);\n const usedText = usedKiB > 0 ? ` using ${fmtKiB(usedKiB)} of temp space` : \"\";\n const method = node.sortMethod ? ` (${node.sortMethod})` : \"\";\n const orderBy =\n node.sortKey && node.sortKey.length > 0 ? node.sortKey.join(\", \") : \"<ORDER BY columns>\";\n\n const summary =\n usedKiB > 0\n ? `Raise work_mem for this query so the sort stays in memory, e.g. SET work_mem = '${workMemRecommended}' at session or role scope (do NOT raise it globally without accounting for max_connections — each connection can allocate work_mem several times over). Alternatively, add an index on (${orderBy}) so rows arrive pre-sorted and the Sort node disappears.`\n : `Raise work_mem for this query so the sort stays in memory, e.g. SET work_mem = '64MB' at session or role scope (do NOT raise it globally without accounting for max_connections — each connection can allocate work_mem several times over). Alternatively, add an index on (${orderBy}) so rows arrive pre-sorted and the Sort node disappears.`;\n\n return [\n makeFinding(sortSpillDisk, ctx, node, {\n title: `Sort spilled to disk${usedText}`,\n detail: `The Sort node ran an external merge sort on disk${method}${usedText}, because the data exceeded work_mem.`,\n cause:\n \"work_mem was too small to hold the sort set, so Postgres wrote sorted runs to temporary files and merged them — adding temp-file I/O that an in-memory sort avoids.\",\n remediation: {\n summary,\n steps: [\n \"Set work_mem at session or role scope for this workload, not cluster-wide.\",\n `Size it above the spilled footprint${usedKiB > 0 ? ` (~${fmtKiB(usedKiB)}); ${workMemRecommended} leaves headroom` : \"\"}.`,\n `Or add an index on (${orderBy}) so the sort is satisfied by an ordered scan and removed entirely.`,\n ],\n commands: [\n {\n label: \"Raise work_mem for this session\",\n sql: `SET work_mem = '${usedKiB > 0 ? workMemRecommended : \"64MB\"}';`,\n },\n {\n label: \"Or set it per role\",\n sql: `ALTER ROLE <role> SET work_mem = '${usedKiB > 0 ? workMemRecommended : \"64MB\"}';`,\n },\n {\n label: \"Or add an index matching the sort key\",\n sql: `CREATE INDEX ON <table> (${orderBy});`,\n },\n ],\n },\n docsUrl: `${DOCS}/runtime-config-resource.html#GUC-WORK-MEM`,\n meta: { sortSpaceUsedKiB: Math.round(usedKiB), workMemRecommended },\n }),\n ];\n },\n};\n","import { executionMs } from \"../../core/metrics.ts\";\nimport type { Rule } from \"../../core/model.ts\";\nimport { fmtMs, fmtPct } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * Triggers consume a significant fraction of execution time. Trigger work (FK\n * constraint checks, AFTER triggers, etc.) runs outside the plan tree, so it is\n * invisible in the node timings and easy to miss. We surface it when the summed\n * trigger time crosses `triggerPct` of total execution time.\n */\nexport const triggerTime: Rule = {\n id: \"PGX_TRIGGER_TIME\",\n title: \"Triggers consume significant time\",\n defaultSeverity: \"info\",\n requiresAnalyze: true,\n check(node, ctx) {\n // Tree-level rule — act only at the root.\n if (node !== ctx.tree.root) return [];\n\n const triggers = ctx.tree.triggers;\n const execMs = executionMs(ctx.tree);\n const triggerTotal = triggers.reduce((s, t) => s + (t.time ?? 0), 0);\n if (!triggers.length || !execMs || triggerTotal <= 0) return [];\n\n const pct = (100 * triggerTotal) / execMs;\n if (pct <= ctx.thresholds.triggerPct) return [];\n\n // Name the heaviest trigger so the message is concrete.\n const worst = triggers.reduce((a, b) => ((b.time ?? 0) > (a.time ?? 0) ? b : a));\n const worstLabel = worst.name ?? worst.constraintName ?? \"a trigger\";\n const onRel = worst.relation ? ` on ${worst.relation}` : \"\";\n\n return [\n makeFinding(triggerTime, ctx, node, {\n title: `Triggers consumed ${fmtMs(triggerTotal)} (${fmtPct(pct)} of execution)`,\n detail: `Trigger execution took ${fmtMs(triggerTotal)} of the ${fmtMs(\n execMs,\n )} total — ${fmtPct(pct)} of the time is spent outside the plan tree (heaviest: \"${worstLabel}\"${onRel}).`,\n cause:\n \"Time spent firing triggers (often foreign-key constraint checks or AFTER triggers) is not attributed to any plan node, so it is invisible in the node timings even though it dominates the statement.\",\n remediation: {\n summary: `Index the foreign-key columns involved in the constraint checks so each row's lookup is cheap, and review the trigger function bodies for per-row inefficiency. For bulk loads, defer constraints (SET CONSTRAINTS ALL DEFERRED) or disable and replay triggers around the batch.`,\n steps: [\n \"Confirm both the referencing and referenced FK columns are indexed — an FK check does a lookup on the referenced key for every row, and a missing index makes it a full scan per row.\",\n \"Inspect each trigger function body for per-row work that could be batched or removed.\",\n \"For bulk INSERT/UPDATE/COPY, defer FK constraints until commit, or temporarily disable user triggers and replay the work once after the batch.\",\n ],\n commands: [\n {\n label: \"Index the referencing FK column(s) so constraint checks are cheap\",\n sql: `CREATE INDEX ON <referencing_table> (<fk_columns>);`,\n },\n {\n label: \"Defer FK constraint checks to commit for a bulk load\",\n sql: `BEGIN;\\nSET CONSTRAINTS ALL DEFERRED;\\n-- bulk INSERT/UPDATE/COPY here\\nCOMMIT;`,\n },\n {\n label: \"Disable user triggers around a batch, then re-enable\",\n sql: `ALTER TABLE <table> DISABLE TRIGGER USER;\\n-- bulk work here\\nALTER TABLE <table> ENABLE TRIGGER USER;`,\n },\n ],\n },\n docsUrl: `${DOCS}/sql-createtrigger.html`,\n meta: { triggerMs: Math.round(triggerTotal), triggerPct: Math.round(pct) },\n }),\n ];\n },\n};\n","import type { Rule } from \"../../core/model.ts\";\nimport { fmtInt } from \"../../util/format.ts\";\nimport { DOCS, makeFinding } from \"./util.ts\";\n\n/**\n * A Gather / Gather Merge node asked for more parallel workers than it got. Postgres\n * caps the total number of background workers globally (max_worker_processes /\n * max_parallel_workers), so a busy server can starve a query of the workers it planned\n * for, leaving the parallel plan running mostly serial. This is informational: if the\n * plan was not actually faster in parallel, fewer workers may be fine.\n */\nexport const workersNotLaunched: Rule = {\n id: \"PGX_WORKERS_NOT_LAUNCHED\",\n title: \"Parallel workers planned but not launched\",\n defaultSeverity: \"info\",\n requiresAnalyze: true,\n check(node, ctx) {\n if (node.nodeType !== \"Gather\" && node.nodeType !== \"Gather Merge\") return [];\n if (node.workersPlanned === undefined || node.workersLaunched === undefined) return [];\n if (node.workersLaunched >= node.workersPlanned) return [];\n\n const planned = node.workersPlanned;\n const launched = node.workersLaunched;\n const shortfall = planned - launched;\n\n return [\n makeFinding(workersNotLaunched, ctx, node, {\n title: `${node.nodeType} got ${fmtInt(launched)} of ${fmtInt(planned)} planned workers`,\n detail: `This ${node.nodeType} planned for ${fmtInt(planned)} parallel worker${\n planned === 1 ? \"\" : \"s\"\n } but only ${fmtInt(launched)} were launched (${fmtInt(shortfall)} short), so part of the work ran serially.`,\n cause:\n \"The global background-worker pool was exhausted: max_worker_processes or max_parallel_workers was already saturated (often by other concurrent parallel queries) when this node tried to start its workers.\",\n remediation: {\n summary: `Raise max_parallel_workers and max_worker_processes so the pool can supply the ${fmtInt(\n planned,\n )} workers this query plans for, and confirm max_parallel_workers_per_gather permits them. If parallelism is not actually speeding this query up, the shortfall is harmless.`,\n steps: [\n \"Check current limits: max_worker_processes, max_parallel_workers, max_parallel_workers_per_gather.\",\n \"max_parallel_workers must be <= max_worker_processes; raise both together (max_worker_processes change needs a restart).\",\n \"Look for other concurrent parallel queries saturating the shared pool during peak load.\",\n \"If a serial plan is no slower here, leave the settings alone — this is informational.\",\n ],\n commands: [\n {\n label: \"Enlarge the global parallel-worker pool\",\n sql: \"ALTER SYSTEM SET max_parallel_workers = '<N>';\\nALTER SYSTEM SET max_worker_processes = '<N+>';\\nSELECT pg_reload_conf();\",\n },\n {\n label: \"Allow more workers per Gather\",\n sql: \"ALTER SYSTEM SET max_parallel_workers_per_gather = '<N>';\\nSELECT pg_reload_conf();\",\n },\n {\n label: \"Inspect the current settings\",\n sql: \"SELECT name, setting FROM pg_settings WHERE name IN ('max_worker_processes', 'max_parallel_workers', 'max_parallel_workers_per_gather');\",\n },\n ],\n },\n docsUrl: `${DOCS}/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS`,\n meta: { planned, launched },\n }),\n ];\n },\n};\n","import type { Rule } from \"../../core/model.ts\";\nimport { bitmapLossy } from \"./bitmap-lossy.ts\";\nimport { cartesianProduct } from \"./cartesian-product.ts\";\nimport { correlatedSubplan } from \"./correlated-subplan.ts\";\nimport { couldBeIndexOnly } from \"./could-be-index-only.ts\";\nimport { filterCouldBeIndexCond } from \"./filter-could-be-index-cond.ts\";\nimport { hashSpillDisk } from \"./hash-spill-disk.ts\";\nimport { highFilterDiscard } from \"./high-filter-discard.ts\";\nimport { indexOnlyHeapFetches } from \"./index-only-heap-fetches.ts\";\nimport { lowCacheHit } from \"./low-cache-hit.ts\";\nimport { nestedLoopLargeOuter } from \"./nested-loop-large-outer.ts\";\nimport { rowMisestimate } from \"./row-misestimate.ts\";\nimport { seqScanLarge } from \"./seq-scan-large.ts\";\nimport { significantJit } from \"./significant-jit.ts\";\nimport { sortSpillDisk } from \"./sort-spill-disk.ts\";\nimport { triggerTime } from \"./trigger-time.ts\";\nimport { workersNotLaunched } from \"./workers-not-launched.ts\";\n\n/**\n * Every advisor rule, in display order (most actionable structural issues first).\n * Rule ids ARE the PGX_* diagnostic codes (greppable, config-keyed). One file per rule.\n */\nexport const ALL_RULES: Rule[] = [\n cartesianProduct,\n seqScanLarge,\n nestedLoopLargeOuter,\n highFilterDiscard,\n sortSpillDisk,\n hashSpillDisk,\n correlatedSubplan,\n rowMisestimate,\n filterCouldBeIndexCond,\n couldBeIndexOnly,\n indexOnlyHeapFetches,\n bitmapLossy,\n workersNotLaunched,\n lowCacheHit,\n significantJit,\n triggerTime,\n];\n","import { DEFAULT_CONFIG, type PgExplainConfig } from \"../config.ts\";\nimport { bottlenecks, executionMs, nodeLabel } from \"../core/metrics.ts\";\nimport type {\n AnalysisContext,\n AnalysisResult,\n Diagnostic,\n PlanTree,\n Severity,\n} from \"../core/model.ts\";\nimport { flatten } from \"../core/parse.ts\";\nimport { bySeverity, maxSeverity } from \"../diagnostics/diagnostic.ts\";\nimport { fmtMs } from \"../util/format.ts\";\nimport { ALL_RULES } from \"./rules/index.ts\";\n\n/**\n * Run every enabled rule over the tree and assemble the result. Assumes\n * computeMetrics(tree) has already run. Rules that need data the plan lacks\n * (ANALYZE/BUFFERS) are skipped so cost-only plans degrade gracefully.\n */\nexport function runAdvisor(\n tree: PlanTree,\n config: PgExplainConfig = DEFAULT_CONFIG,\n): AnalysisResult {\n const ctx: AnalysisContext = {\n tree,\n thresholds: config.thresholds,\n severityOf: (id, fallback) => config.rules[id]?.severity ?? fallback,\n isEnabled: (id) => config.rules[id]?.enabled !== false,\n };\n\n const nodes = flatten(tree.root);\n const diagnostics: Diagnostic[] = [];\n\n for (const rule of ALL_RULES) {\n if (!ctx.isEnabled(rule.id)) continue;\n if (rule.requiresAnalyze && !tree.hasAnalyze) continue;\n if (rule.requiresBuffers && !tree.hasBuffers) continue;\n for (const node of nodes) {\n for (const finding of rule.check(node, ctx)) diagnostics.push(finding);\n }\n }\n\n diagnostics.sort(bySeverity);\n\n let worst: Severity | null = null;\n for (const d of diagnostics) worst = worst === null ? d.severity : maxSeverity(worst, d.severity);\n\n const bn = bottlenecks(tree, 5);\n return {\n tree,\n diagnostics,\n bottlenecks: bn,\n verdict: buildVerdict(tree, diagnostics, bn),\n worstSeverity: worst,\n };\n}\n\nfunction buildVerdict(\n tree: PlanTree,\n diagnostics: Diagnostic[],\n bn: AnalysisResult[\"bottlenecks\"],\n): string {\n const counts: Record<Severity, number> = { error: 0, warn: 0, info: 0 };\n for (const d of diagnostics) counts[d.severity]++;\n\n const parts: string[] = [];\n if (counts.error) parts.push(`${counts.error} critical`);\n if (counts.warn) parts.push(`${counts.warn} warning${counts.warn > 1 ? \"s\" : \"\"}`);\n if (counts.info) parts.push(`${counts.info} note${counts.info > 1 ? \"s\" : \"\"}`);\n const findings = parts.length ? parts.join(\", \") : \"no issues found\";\n\n const top = bn[0];\n let bottleneck = \"\";\n if (top?.metrics.selfMs !== undefined) {\n const pct =\n top.metrics.pctOfTotal !== undefined\n ? ` (${top.metrics.pctOfTotal.toFixed(0)}% of time)`\n : \"\";\n bottleneck = ` — top cost: ${nodeLabel(top)}${pct}`;\n }\n\n const ms = executionMs(tree);\n const timing = ms !== undefined ? ` Total ${fmtMs(ms)}.` : \" Cost-only plan (no timing).\";\n return `${findings}${bottleneck}.${timing}`;\n}\n","import type { PlanNode, PlanTree } from \"../core/model.ts\";\nimport { walk } from \"../core/parse.ts\";\n\n/**\n * Strip literal values out of a plan so a shared report or CI artifact can't leak\n * real data. VERBOSE output and filter/condition expressions embed constants\n * (e.g. `status = 'shipped'`, `amount > 1000`) — those become `'?'` / `N`.\n *\n * ponytail: regex over expression strings, not a SQL parser. Catches string and\n * numeric literals, which is where real values live; identifiers/operators stay.\n */\nexport function redactExpression(expr: string): string {\n return expr\n .replace(/'(?:[^']|'')*'/g, \"'?'\") // string literals (with '' escapes)\n .replace(/\\b\\d+(?:\\.\\d+)?\\b/g, \"N\"); // numeric literals\n}\n\nconst EXPR_FIELDS = [\n \"filter\",\n \"indexCond\",\n \"recheckCond\",\n \"hashCond\",\n \"joinFilter\",\n] as const satisfies readonly (keyof PlanNode)[];\n\nfunction redactNode(node: PlanNode): void {\n for (const field of EXPR_FIELDS) {\n const value = node[field];\n if (typeof value === \"string\") (node[field] as string) = redactExpression(value);\n }\n if (node.output) node.output = node.output.map(redactExpression);\n if (node.sortKey) node.sortKey = node.sortKey.map(redactExpression);\n}\n\n/** Redact every expression field in the tree, in place. */\nexport function redactPlanTree(tree: PlanTree): void {\n walk(tree.root, redactNode);\n}\n","import { executionMs, nodeLabel } from \"../core/metrics.ts\";\nimport type { PlanNode, PlanTree } from \"../core/model.ts\";\nimport { fmtInt, fmtMs, type TreeGlyphs } from \"../util/format.ts\";\n\nexport interface TreeLine {\n node: PlanNode;\n /** Indentation + branch glyphs already applied. */\n prefix: string;\n}\n\n/** Lay out the plan as indented lines. Shared by the markdown/terminal/text renderers. */\nexport function treeLines(tree: PlanTree, glyphs: TreeGlyphs): TreeLine[] {\n const lines: TreeLine[] = [];\n const recurse = (node: PlanNode, indent: string, isLast: boolean, isRoot: boolean): void => {\n const connector = isRoot ? \"\" : isLast ? glyphs.last : glyphs.branch;\n lines.push({ node, prefix: indent + connector });\n const childIndent = isRoot ? \"\" : indent + (isLast ? glyphs.space : glyphs.vert);\n node.children.forEach((child, i) => {\n recurse(child, childIndent, i === node.children.length - 1, false);\n });\n };\n recurse(tree.root, \"\", true, true);\n return lines;\n}\n\n/** A compact, plain-text metric summary for one node (no color). */\nexport function nodeSummary(node: PlanNode): string {\n const m = node.metrics;\n const parts: string[] = [];\n\n if (m.totalRows !== undefined) {\n let rows = `rows=${fmtInt(m.totalRows)}`;\n if (\n m.estimateFactor !== undefined &&\n m.estimateFactor >= 2 &&\n m.estimateDirection !== \"accurate\"\n ) {\n rows += ` (est ${fmtInt(node.planRows)}, ${m.estimateFactor.toFixed(0)}× ${m.estimateDirection})`;\n }\n parts.push(rows);\n } else {\n parts.push(`rows≈${fmtInt(node.planRows)} est`);\n }\n\n if (m.selfMs !== undefined) {\n let t = `self ${fmtMs(m.selfMs)}`;\n if (m.pctOfTotal !== undefined && m.pctOfTotal >= 1) t += ` (${m.pctOfTotal.toFixed(0)}%)`;\n parts.push(t);\n }\n\n if (node.metrics.cacheHitRatio != null) {\n parts.push(`cache ${(node.metrics.cacheHitRatio * 100).toFixed(0)}%`);\n }\n\n return parts.join(\" · \");\n}\n\nexport { executionMs, nodeLabel };\n","import { executionMs } from \"../core/metrics.ts\";\nimport type { AnalysisResult, PlanNode, Severity } from \"../core/model.ts\";\nimport { flatten } from \"../core/parse.ts\";\nimport { nodeLabel } from \"./tree.ts\";\n\n/** Bump on any breaking change to the JSON shape. Consumers can assert on it. */\nexport const JSON_SCHEMA_VERSION = 1;\n\n/** Stable, machine-readable report for CI and tooling. */\nexport function renderJson(result: AnalysisResult, pretty = true): string {\n const { tree, diagnostics, bottlenecks } = result;\n\n const counts: Record<Severity, number> = { error: 0, warn: 0, info: 0 };\n for (const d of diagnostics) counts[d.severity]++;\n\n const report = {\n schemaVersion: JSON_SCHEMA_VERSION,\n verdict: result.verdict,\n worstSeverity: result.worstSeverity,\n summary: {\n planningTimeMs: tree.planningTime ?? null,\n executionTimeMs: executionMs(tree) ?? null,\n hasAnalyze: tree.hasAnalyze,\n hasBuffers: tree.hasBuffers,\n nodeCount: flatten(tree.root).length,\n findings: counts,\n },\n diagnostics,\n bottlenecks: bottlenecks\n .filter((n) => (n.metrics.selfMs ?? 0) > 0)\n .map((n) => ({\n id: n.id,\n label: nodeLabel(n),\n nodeType: n.nodeType,\n relation: n.relationName ?? null,\n selfMs: n.metrics.selfMs ?? null,\n pctOfTotal: n.metrics.pctOfTotal ?? null,\n totalRows: n.metrics.totalRows ?? null,\n })),\n plan: serializeNode(tree.root),\n };\n\n return JSON.stringify(report, null, pretty ? 2 : 0);\n}\n\n/** Slim node for JSON: normalized fields + metrics + children, never the raw blob. */\nfunction serializeNode(node: PlanNode): Record<string, unknown> {\n const { children, metrics, raw, ...fields } = node;\n void raw;\n return { ...fields, metrics, children: children.map(serializeNode) };\n}\n","import { executionMs } from \"../core/metrics.ts\";\nimport type { AnalysisResult, Diagnostic, Severity } from \"../core/model.ts\";\nimport { fmtMs, UNICODE_TREE } from \"../util/format.ts\";\nimport { nodeLabel, nodeSummary, treeLines } from \"./tree.ts\";\n\nconst SEV: Record<Severity, { label: string; cls: string }> = {\n error: { label: \"Critical\", cls: \"sev-error\" },\n warn: { label: \"Warning\", cls: \"sev-warn\" },\n info: { label: \"Note\", cls: \"sev-info\" },\n};\n\nfunction esc(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n\n/** A single self-contained HTML file: inline CSS, no external assets, safe to email. */\nexport function renderHtml(result: AnalysisResult): string {\n const { tree, diagnostics } = result;\n const ms = executionMs(tree);\n\n const treeHtml = treeLines(tree, UNICODE_TREE)\n .map(({ node, prefix }) => {\n const pct = node.metrics.pctOfTotal ?? 0;\n const heat = pct >= 50 ? \"hot\" : pct >= 20 ? \"warm\" : pct >= 5 ? \"\" : \"cold\";\n return `<div class=\"node ${heat}\"><span class=\"glyph\">${esc(prefix)}</span><span class=\"label\">${esc(nodeLabel(node))}</span> <span class=\"meta\">${esc(nodeSummary(node))}</span></div>`;\n })\n .join(\"\\n\");\n\n const findingsHtml = diagnostics.length\n ? diagnostics.map(findingHtml).join(\"\\n\")\n : '<p class=\"ok\">No anti-patterns detected. 🎉</p>';\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>pg-explain report</title>\n<style>\n :root { color-scheme: light dark; }\n body { font: 15px/1.5 -apple-system, system-ui, sans-serif; margin: 0; padding: 2rem; max-width: 980px; margin-inline: auto; }\n h1 { font-size: 1.4rem; } h2 { font-size: 1.1rem; margin-top: 2rem; border-bottom: 1px solid #8884; padding-bottom: .3rem; }\n .verdict { padding: .75rem 1rem; border-left: 4px solid #888; background: #8881; border-radius: 4px; }\n .verdict.sev-error { border-color: #e5484d; } .verdict.sev-warn { border-color: #f5a623; } .verdict.sev-info { border-color: #4493f8; }\n table { border-collapse: collapse; width: 100%; } td, th { text-align: left; padding: .3rem .6rem; border-bottom: 1px solid #8883; }\n .tree { overflow-x: auto; } .node { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre; font-size: 13px; }\n .glyph { color: #8888; } .meta { color: #888; }\n .node.hot .label { color: #e5484d; font-weight: 700; } .node.warm .label { color: #f5a623; } .node.cold .label { opacity: .6; }\n .finding { border: 1px solid #8883; border-radius: 6px; padding: 1rem; margin: 1rem 0; }\n .finding .tag { font-size: .75rem; font-weight: 700; padding: .1rem .5rem; border-radius: 3px; color: #fff; }\n .sev-error .tag { background: #e5484d; } .sev-warn .tag { background: #f5a623; } .sev-info .tag { background: #4493f8; }\n .finding code, pre { font-family: ui-monospace, monospace; font-size: 13px; }\n pre { background: #8881; padding: .6rem .8rem; border-radius: 4px; overflow-x: auto; }\n .label-cmd { color: #888; font-size: .85rem; margin-top: .5rem; }\n .ok { color: #2e7d32; }\n</style>\n</head>\n<body>\n<h1>pg-explain report</h1>\n<div class=\"verdict ${result.worstSeverity ? SEV[result.worstSeverity].cls : \"\"}\">${esc(result.verdict)}</div>\n\n<h2>Summary</h2>\n<table>\n ${tree.planningTime !== undefined ? `<tr><th>Planning time</th><td>${esc(fmtMs(tree.planningTime))}</td></tr>` : \"\"}\n ${ms !== undefined ? `<tr><th>Execution time</th><td>${esc(fmtMs(ms))}</td></tr>` : \"\"}\n ${!tree.hasAnalyze ? \"<tr><th>Mode</th><td>cost-only (no ANALYZE)</td></tr>\" : \"\"}\n <tr><th>Findings</th><td>${diagnostics.length}</td></tr>\n</table>\n\n<h2>Plan tree</h2>\n<div class=\"tree\">\n${treeHtml}\n</div>\n\n<h2>Findings</h2>\n${findingsHtml}\n</body>\n</html>\n`;\n}\n\nfunction findingHtml(d: Diagnostic): string {\n const sev = SEV[d.severity];\n const steps = d.remediation.steps?.length\n ? `<ul>${d.remediation.steps.map((s) => `<li>${esc(s)}</li>`).join(\"\")}</ul>`\n : \"\";\n const cmds = (d.remediation.commands ?? [])\n .map((c) => {\n const body = c.sql ?? c.shell ?? \"\";\n const label = c.label ? `<div class=\"label-cmd\">${esc(c.label)}</div>` : \"\";\n return `${label}<pre><code>${esc(body)}</code></pre>`;\n })\n .join(\"\");\n const docs = d.docsUrl ? `<p>📖 <a href=\"${esc(d.docsUrl)}\">PostgreSQL docs</a></p>` : \"\";\n const meta = d.location?.relation\n ? ` <span class=\"meta\">on ${esc(d.location.relation)}</span>`\n : \"\";\n\n return `<div class=\"finding ${sev.cls}\">\n <p><span class=\"tag\">${sev.label}</span> <strong>${esc(d.title)}</strong> <code>${esc(d.code)}</code>${meta}</p>\n <p><strong>What:</strong> ${esc(d.detail)}</p>\n <p><strong>Why:</strong> ${esc(d.cause)}</p>\n <p><strong>Fix:</strong> ${esc(d.remediation.summary)}</p>\n ${steps}\n ${cmds}\n ${docs}\n</div>`;\n}\n","import { executionMs } from \"../core/metrics.ts\";\nimport type { AnalysisResult, Diagnostic, Severity } from \"../core/model.ts\";\nimport { fmtInt, fmtMs, UNICODE_TREE } from \"../util/format.ts\";\nimport { nodeLabel, nodeSummary, treeLines } from \"./tree.ts\";\n\nconst SEV_LABEL: Record<Severity, string> = {\n error: \"🔴 Critical\",\n warn: \"🟠 Warning\",\n info: \"🔵 Note\",\n};\n\nexport interface MarkdownOptions {\n tldr?: boolean;\n}\n\n/** The headline deliverable: a shareable Markdown report. */\nexport function renderMarkdown(result: AnalysisResult, opts: MarkdownOptions = {}): string {\n const { tree, diagnostics, bottlenecks } = result;\n const out: string[] = [];\n\n out.push(\"# pg-explain report\", \"\");\n out.push(`> **Verdict:** ${result.verdict}`, \"\");\n\n // Summary.\n out.push(\"## Summary\", \"\");\n const ms = executionMs(tree);\n out.push(\"| Metric | Value |\", \"| --- | --- |\");\n if (tree.planningTime !== undefined) out.push(`| Planning time | ${fmtMs(tree.planningTime)} |`);\n if (ms !== undefined) out.push(`| Execution time | ${fmtMs(ms)} |`);\n if (!tree.hasAnalyze) out.push(\"| Mode | cost-only (no ANALYZE) |\");\n out.push(`| Findings | ${summarizeCounts(diagnostics)} |`, \"\");\n\n if (opts.tldr) {\n out.push(...renderFindings(diagnostics, true));\n return `${out.join(\"\\n\").trimEnd()}\\n`;\n }\n\n // Plan tree.\n out.push(\"## Plan tree\", \"\", \"```\");\n for (const { node, prefix } of treeLines(tree, UNICODE_TREE)) {\n out.push(`${prefix}${nodeLabel(node)} — ${nodeSummary(node)}`);\n }\n out.push(\"```\", \"\");\n\n // Bottlenecks.\n const ranked = bottlenecks.filter((n) => (n.metrics.selfMs ?? 0) > 0);\n if (ranked.length) {\n out.push(\"## Bottlenecks (by self time)\", \"\");\n out.push(\"| # | Node | Self time | % of total | Rows |\", \"| --- | --- | --- | --- | --- |\");\n ranked.forEach((node, i) => {\n const pct =\n node.metrics.pctOfTotal !== undefined ? `${node.metrics.pctOfTotal.toFixed(1)}%` : \"—\";\n const rows = node.metrics.totalRows !== undefined ? fmtInt(node.metrics.totalRows) : \"—\";\n out.push(\n `| ${i + 1} | ${nodeLabel(node)} | ${fmtMs(node.metrics.selfMs ?? 0)} | ${pct} | ${rows} |`,\n );\n });\n out.push(\"\");\n }\n\n // Findings.\n out.push(...renderFindings(diagnostics, false));\n return `${out.join(\"\\n\").trimEnd()}\\n`;\n}\n\nfunction renderFindings(diagnostics: Diagnostic[], tldr: boolean): string[] {\n const out: string[] = [\"## Findings\", \"\"];\n if (diagnostics.length === 0) {\n out.push(\"No anti-patterns detected. 🎉\", \"\");\n return out;\n }\n\n for (const d of diagnostics) {\n out.push(`### ${SEV_LABEL[d.severity]} — ${d.title}`, \"\");\n out.push(`\\`${d.code}\\``, \"\");\n out.push(`**What:** ${d.detail}`, \"\");\n out.push(`**Why:** ${d.cause}`, \"\");\n out.push(`**Fix:** ${d.remediation.summary}`, \"\");\n if (!tldr) {\n if (d.remediation.steps?.length) {\n for (const step of d.remediation.steps) out.push(`- ${step}`);\n out.push(\"\");\n }\n for (const cmd of d.remediation.commands ?? []) {\n const body = cmd.sql ?? cmd.shell ?? \"\";\n const lang = cmd.sql ? \"sql\" : \"sh\";\n if (cmd.label) out.push(`_${cmd.label}:_`);\n out.push(\"```\" + lang, body, \"```\", \"\");\n }\n if (d.docsUrl) out.push(`📖 [PostgreSQL docs](${d.docsUrl})`, \"\");\n }\n }\n return out;\n}\n\nfunction summarizeCounts(diagnostics: Diagnostic[]): string {\n const counts: Record<Severity, number> = { error: 0, warn: 0, info: 0 };\n for (const d of diagnostics) counts[d.severity]++;\n if (diagnostics.length === 0) return \"none\";\n return `${counts.error} critical, ${counts.warn} warning(s), ${counts.info} note(s)`;\n}\n","// picocolors is CommonJS; import the default export and destructure (named ESM\n// imports fail at runtime). tsup keeps it external, so this resolves to the CJS module.\nimport pc from \"picocolors\";\n\nconst { createColors, isColorSupported } = pc;\n\ntype Colors = ReturnType<typeof createColors>;\n\n// picocolors already honors NO_COLOR / FORCE_COLOR / TTY. configureColor lets the\n// CLI override that with --color/--no-color.\nlet active: Colors = createColors(isColorSupported);\n\nexport function configureColor(mode: \"auto\" | \"always\" | \"never\"): void {\n active = createColors(mode === \"always\" || (mode === \"auto\" && isColorSupported));\n}\n\n/** Current color functions. Renderers call this so --no-color takes effect. */\nexport function colors(): Colors {\n return active;\n}\n","import { executionMs } from \"../core/metrics.ts\";\nimport type { AnalysisResult, Diagnostic, PlanNode, Severity } from \"../core/model.ts\";\nimport { colors } from \"../util/color.ts\";\nimport { ASCII_TREE, fmtMs, UNICODE_TREE } from \"../util/format.ts\";\nimport { nodeLabel, nodeSummary, treeLines } from \"./tree.ts\";\n\nexport interface TerminalOptions {\n /** ASCII tree glyphs + no bars; suitable for logs / screen readers. */\n ascii?: boolean;\n bars?: boolean;\n tldr?: boolean;\n}\n\nconst SEV_TAG: Record<Severity, string> = { error: \"CRITICAL\", warn: \"WARNING\", info: \"NOTE\" };\n\nfunction sevColor(sev: Severity, text: string): string {\n const c = colors();\n if (sev === \"error\") return c.red(c.bold(text));\n if (sev === \"warn\") return c.yellow(text);\n return c.cyan(text);\n}\n\n/** Heat the node label by its share of total time. */\nfunction heat(node: PlanNode, text: string): string {\n const c = colors();\n const pct = node.metrics.pctOfTotal;\n if (pct === undefined) return text;\n if (pct >= 50) return c.red(c.bold(text));\n if (pct >= 20) return c.yellow(text);\n if (pct >= 5) return text;\n return c.dim(text);\n}\n\nfunction bar(pct: number, width = 8): string {\n const filled = Math.round((pct / 100) * width);\n return \"▇\".repeat(Math.min(filled, width)) + \"▁\".repeat(Math.max(width - filled, 0));\n}\n\nexport function renderTerminal(result: AnalysisResult, opts: TerminalOptions = {}): string {\n const c = colors();\n const { tree, diagnostics, bottlenecks } = result;\n const glyphs = opts.ascii ? ASCII_TREE : UNICODE_TREE;\n const out: string[] = [];\n\n out.push(c.bold(\"pg-explain report\"));\n out.push(`${c.bold(\"Verdict:\")} ${verdictColored(result)}`);\n out.push(\"\");\n\n if (opts.tldr) {\n out.push(...findingsBlock(diagnostics, opts));\n return `${out.join(\"\\n\").trimEnd()}\\n`;\n }\n\n // Plan tree.\n out.push(c.bold(\"Plan tree\"));\n for (const { node, prefix } of treeLines(tree, glyphs)) {\n const heatBar =\n opts.bars !== false && node.metrics.pctOfTotal !== undefined\n ? ` ${c.dim(bar(node.metrics.pctOfTotal))}`\n : \"\";\n out.push(\n `${c.dim(prefix)}${heat(node, nodeLabel(node))}${heatBar} ${c.dim(nodeSummary(node))}`,\n );\n }\n out.push(\"\");\n\n // Bottlenecks.\n const ranked = bottlenecks.filter((n) => (n.metrics.selfMs ?? 0) > 0);\n if (ranked.length) {\n out.push(c.bold(\"Bottlenecks (by self time)\"));\n ranked.forEach((node, i) => {\n const pct =\n node.metrics.pctOfTotal !== undefined ? `${node.metrics.pctOfTotal.toFixed(0)}%` : \"—\";\n out.push(\n ` ${i + 1}. ${heat(node, nodeLabel(node))} — ${fmtMs(node.metrics.selfMs ?? 0)} (${pct})`,\n );\n });\n out.push(\"\");\n }\n\n out.push(...findingsBlock(diagnostics, opts));\n const ms = executionMs(tree);\n if (ms !== undefined) out.push(c.dim(`Total execution time: ${fmtMs(ms)}`));\n return `${out.join(\"\\n\").trimEnd()}\\n`;\n}\n\nfunction verdictColored(result: AnalysisResult): string {\n if (result.worstSeverity === null) return colors().green(result.verdict);\n return sevColor(result.worstSeverity, result.verdict);\n}\n\nfunction findingsBlock(diagnostics: Diagnostic[], opts: TerminalOptions): string[] {\n const c = colors();\n const out: string[] = [c.bold(\"Findings\")];\n if (diagnostics.length === 0) {\n out.push(` ${c.green(\"No anti-patterns detected.\")}`, \"\");\n return out;\n }\n for (const d of diagnostics) {\n out.push(\"\");\n out.push(\n `${sevColor(d.severity, `[${SEV_TAG[d.severity]}]`)} ${c.bold(d.title)} ${c.dim(d.code)}`,\n );\n out.push(` ${c.dim(\"What:\")} ${d.detail}`);\n out.push(` ${c.dim(\"Why: \")} ${d.cause}`);\n out.push(` ${c.dim(\"Fix: \")} ${d.remediation.summary}`);\n if (!opts.tldr) {\n for (const step of d.remediation.steps ?? []) out.push(` - ${step}`);\n for (const cmd of d.remediation.commands ?? []) {\n const body = cmd.sql ?? cmd.shell ?? \"\";\n const label = cmd.label ? `${c.dim(`${cmd.label}:`)} ` : \"\";\n out.push(` ${label}${c.green(body)}`);\n }\n if (d.docsUrl) out.push(` ${c.dim(`docs: ${d.docsUrl}`)}`);\n }\n }\n out.push(\"\");\n return out;\n}\n","import type { AnalysisResult } from \"../core/model.ts\";\nimport { renderHtml } from \"./html.ts\";\nimport { renderJson } from \"./json.ts\";\nimport { renderMarkdown } from \"./markdown.ts\";\nimport { renderTerminal } from \"./terminal.ts\";\n\nexport type Format = \"terminal\" | \"markdown\" | \"json\" | \"html\" | \"text\";\n\nexport const FORMATS: Format[] = [\"terminal\", \"markdown\", \"json\", \"html\", \"text\"];\n\nexport function isFormat(s: string): s is Format {\n return (FORMATS as string[]).includes(s);\n}\n\nexport interface RenderOptions {\n format: Format;\n /** Summary + findings only, no plan tree. */\n tldr?: boolean;\n /** ASCII tree glyphs (terminal/text). */\n ascii?: boolean;\n /** Pretty-print JSON. */\n pretty?: boolean;\n}\n\n/** Render an analysis result to the requested format. Color is configured by the caller. */\nexport function render(result: AnalysisResult, opts: RenderOptions): string {\n switch (opts.format) {\n case \"markdown\":\n return renderMarkdown(result, { tldr: opts.tldr });\n case \"json\":\n return renderJson(result, opts.pretty ?? true);\n case \"html\":\n return renderHtml(result);\n case \"text\":\n // Plain text: ASCII tree, no bars. Caller disables color for this format.\n return renderTerminal(result, { ascii: true, bars: false, tldr: opts.tldr });\n default:\n return renderTerminal(result, { ascii: opts.ascii, tldr: opts.tldr });\n }\n}\n","/**\n * Public library API. Consumers can parse, analyze, and render plans programmatically:\n *\n * import { analyze, render } from \"pgexplain\";\n * const result = analyze(explainJsonText);\n * console.log(render(result, { format: \"markdown\" }));\n */\nimport { runAdvisor } from \"./advisor/index.ts\";\nimport { DEFAULT_CONFIG, type PgExplainConfig } from \"./config.ts\";\nimport { computeMetrics } from \"./core/metrics.ts\";\nimport type { AnalysisResult, Diagnostic, PlanTree, Severity } from \"./core/model.ts\";\nimport { flatten, parseExplainJson } from \"./core/parse.ts\";\nimport { opDiagnostic, opError } from \"./diagnostics/catalog.ts\";\nimport { bySeverity, maxSeverity } from \"./diagnostics/diagnostic.ts\";\nimport { redactPlanTree } from \"./input/redact.ts\";\n\nexport interface AnalyzeOptions {\n config?: PgExplainConfig;\n /** 1-based statement index when the input holds more than one. */\n statement?: number;\n /** Strip literal values from expressions before analysis (no data leaks downstream). */\n redact?: boolean;\n}\n\n/** Parse → (redact) → compute metrics → run advisor → attach informational notices. */\nexport function analyze(input: string, options: AnalyzeOptions = {}): AnalysisResult {\n const trees = parseExplainJson(input);\n const tree = selectStatement(trees, options.statement);\n if (options.redact) redactPlanTree(tree);\n computeMetrics(tree);\n\n const result = runAdvisor(tree, options.config ?? DEFAULT_CONFIG);\n\n const notices = planNotices(tree);\n if (notices.length) {\n result.diagnostics = [...result.diagnostics, ...notices].sort(bySeverity);\n result.worstSeverity = result.diagnostics.reduce<Severity | null>(\n (worst, d) => (worst === null ? d.severity : maxSeverity(worst, d.severity)),\n null,\n );\n }\n return result;\n}\n\nfunction selectStatement(trees: PlanTree[], statement?: number): PlanTree {\n if (statement !== undefined) {\n const tree = trees[statement - 1];\n if (!tree) {\n throw opError(\"PGX_MULTIPLE_STATEMENTS\", {\n detail: `--statement ${statement} is out of range; the input has ${trees.length} statement(s).`,\n });\n }\n return tree;\n }\n const first = trees[0];\n if (!first) throw opError(\"PGX_UNEXPECTED_PLAN_SHAPE\"); // schema guarantees ≥1, defensive\n return first;\n}\n\n/** Informational diagnostics about the plan's completeness (cost-only, no buffers, …). */\nfunction planNotices(tree: PlanTree): Diagnostic[] {\n const notices: Diagnostic[] = [];\n if (!tree.hasAnalyze) notices.push(opDiagnostic(\"PGX_COST_ONLY_PLAN\"));\n else if (!tree.hasBuffers) notices.push(opDiagnostic(\"PGX_NO_BUFFERS\"));\n\n const nodes = flatten(tree.root);\n const trivial = nodes.length === 1 && /^(Result|Values? Scan)$/.test(tree.root.nodeType);\n if (trivial) notices.push(opDiagnostic(\"PGX_EMPTY_PLAN\"));\n\n return notices;\n}\n\nexport { runAdvisor } from \"./advisor/index.ts\";\nexport { DEFAULT_CONFIG, DEFAULT_THRESHOLDS, type PgExplainConfig } from \"./config.ts\";\nexport { bottlenecks, computeMetrics, executionMs, nodeLabel } from \"./core/metrics.ts\";\nexport type * from \"./core/model.ts\";\nexport { flatten, parseExplainJson, walk } from \"./core/parse.ts\";\nexport { AppError, scrubCredentials } from \"./diagnostics/diagnostic.ts\";\nexport { JSON_SCHEMA_VERSION } from \"./report/json.ts\";\nexport { FORMATS, type Format, isFormat, type RenderOptions, render } from \"./report/render.ts\";\nexport { ExitCode } from \"./util/exit.ts\";\n","/** Read all of stdin to a string, with a timeout so an idle pipe can't hang the tool. */\nexport function readStdin(timeoutMs = 30_000): Promise<string> {\n if (process.stdin.isTTY) return Promise.resolve(\"\");\n\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n const timer = setTimeout(() => {\n process.stdin.pause();\n reject(new Error(`Timed out after ${timeoutMs}ms waiting for stdin`));\n }, timeoutMs);\n\n process.stdin\n .on(\"data\", (c: Buffer) => chunks.push(c))\n .on(\"end\", () => {\n clearTimeout(timer);\n resolve(Buffer.concat(chunks).toString(\"utf8\"));\n })\n .on(\"error\", (err) => {\n clearTimeout(timer);\n reject(err);\n });\n });\n}\n","import { readFile } from \"node:fs/promises\";\nimport { opError } from \"../diagnostics/catalog.ts\";\nimport { readStdin } from \"./stdin.ts\";\n\n/**\n * Resolve plan text from --file or stdin. Fails with an actionable PGX_EMPTY_INPUT\n * when there is no input (including the interactive \"ran it with no pipe\" case).\n */\nexport async function resolvePlanInput(file?: string): Promise<string> {\n if (file) {\n let text: string;\n try {\n text = await readFile(file, \"utf8\");\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw opError(\n \"PGX_EMPTY_INPUT\",\n { detail: `Could not read file '${file}': ${msg}`, location: { kind: \"input\" } },\n err,\n );\n }\n if (!text.trim()) {\n throw opError(\"PGX_EMPTY_INPUT\", {\n detail: `File '${file}' is empty.`,\n location: { kind: \"input\" },\n });\n }\n return text;\n }\n\n if (process.stdin.isTTY) {\n throw opError(\"PGX_EMPTY_INPUT\", {\n detail: \"No --file given and stdin is a terminal (nothing was piped in).\",\n });\n }\n\n const text = await readStdin();\n if (!text.trim()) throw opError(\"PGX_EMPTY_INPUT\");\n return text;\n}\n","import { writeFile } from \"node:fs/promises\";\nimport type { AnalysisResult, Severity } from \"../core/model.ts\";\nimport { severityAtLeast } from \"../diagnostics/diagnostic.ts\";\nimport { type Format, render } from \"../report/render.ts\";\nimport { configureColor } from \"../util/color.ts\";\nimport { ExitCode } from \"../util/exit.ts\";\n\nexport interface EmitOptions {\n format: Format;\n /** Write to this file instead of stdout. */\n output?: string;\n color: \"auto\" | \"always\" | \"never\";\n ascii?: boolean;\n tldr?: boolean;\n pretty?: boolean;\n /** CI gate: exit non-zero if a finding at/above this severity exists. */\n failOn?: Severity;\n}\n\n/** Render the result, write it (stdout or --output), and return the CI-gate exit code. */\nexport async function emit(result: AnalysisResult, opts: EmitOptions): Promise<ExitCode> {\n // Color only ever applies to the terminal format; ANSI would corrupt md/json/html/text.\n configureColor(opts.format === \"terminal\" ? opts.color : \"never\");\n\n const text = render(result, {\n format: opts.format,\n tldr: opts.tldr,\n ascii: opts.ascii,\n pretty: opts.pretty,\n });\n\n if (opts.output) {\n await writeFile(opts.output, text);\n } else {\n process.stdout.write(text.endsWith(\"\\n\") ? text : `${text}\\n`);\n }\n\n return gateExit(result, opts.failOn);\n}\n\nfunction gateExit(result: AnalysisResult, failOn?: Severity): ExitCode {\n if (!failOn || result.worstSeverity === null) return ExitCode.Success;\n return severityAtLeast(result.worstSeverity, failOn) ? ExitCode.CiGate : ExitCode.Success;\n}\n","import { readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport type { PgExplainConfig } from \"../config.ts\";\nimport type { AnalysisResult } from \"../core/model.ts\";\nimport { opError } from \"../diagnostics/catalog.ts\";\nimport { severityAtLeast } from \"../diagnostics/diagnostic.ts\";\nimport { analyze } from \"../index.ts\";\nimport { resolvePlanInput } from \"../input/source.ts\";\nimport { render } from \"../report/render.ts\";\nimport { configureColor } from \"../util/color.ts\";\nimport { ExitCode } from \"../util/exit.ts\";\nimport { type EmitOptions, emit } from \"./emit.ts\";\n\nexport interface AnalyzeArgs extends EmitOptions {\n file?: string;\n statement?: number;\n redact?: boolean;\n config: PgExplainConfig;\n}\n\n/** Default command: read a plan from --file/stdin (or a directory → batch), analyze, render. */\nexport async function runAnalyze(args: AnalyzeArgs): Promise<ExitCode> {\n if (args.file && (await isDirectory(args.file))) return runBatch(args, args.file);\n\n const text = await resolvePlanInput(args.file);\n const result = analyze(text, {\n config: args.config,\n statement: args.statement,\n redact: args.redact,\n });\n return emit(result, args);\n}\n\nasync function isDirectory(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** Analyze every *.json plan file in a directory; one report each, worst gate wins. */\nasync function runBatch(args: AnalyzeArgs, dir: string): Promise<ExitCode> {\n const files = (await readdir(dir)).filter((f) => f.endsWith(\".json\")).sort();\n if (!files.length) {\n throw opError(\"PGX_EMPTY_INPUT\", {\n detail: `No .json plan files found in directory '${dir}'.`,\n });\n }\n\n configureColor(args.format === \"terminal\" ? args.color : \"never\");\n\n const jsonReports: Array<{ file: string; report: unknown }> = [];\n const textReports: string[] = [];\n let worst: ExitCode = ExitCode.Success;\n\n for (const name of files) {\n const text = await readFile(join(dir, name), \"utf8\");\n let result: AnalysisResult;\n try {\n result = analyze(text, { config: args.config, redact: args.redact });\n } catch (err) {\n // One bad file shouldn't abort the whole batch.\n process.stderr.write(\n `skipping ${name}: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n worst = ExitCode.Parse;\n continue;\n }\n\n if (gateTrips(result, args.failOn)) worst = ExitCode.CiGate;\n\n const body = render(result, {\n format: args.format,\n tldr: args.tldr,\n ascii: args.ascii,\n pretty: args.pretty,\n });\n if (args.format === \"json\") jsonReports.push({ file: name, report: JSON.parse(body) });\n else textReports.push(`\\n${\"=\".repeat(60)}\\n${name}\\n${\"=\".repeat(60)}\\n${body}`);\n }\n\n const out =\n args.format === \"json\"\n ? `${JSON.stringify(jsonReports, null, args.pretty ? 2 : 0)}\\n`\n : `${textReports.join(\"\\n\")}\\n`;\n if (args.output) await writeFile(args.output, out);\n else process.stdout.write(out);\n return worst;\n}\n\nfunction gateTrips(result: AnalysisResult, failOn?: EmitOptions[\"failOn\"]): boolean {\n if (!failOn || result.worstSeverity === null) return false;\n return severityAtLeast(result.worstSeverity, failOn);\n}\n","import { ExitCode } from \"../util/exit.ts\";\n\n/**\n * Print a shell completion script. Minimal but real: completes the subcommands,\n * formats, and the most-used flags. ponytail: static scripts, no dynamic discovery.\n */\nconst SUBCOMMANDS = \"run diff completion\";\nconst FLAGS =\n \"--format --output --tldr --redact --ascii --color --no-color --fail-on --strict --config --statement --quiet --verbose --debug --help --version\";\nconst FORMATS = \"terminal markdown json html text\";\n\nconst BASH = `# pg-explain bash completion\n_pg_explain() {\n local cur prev\n cur=\"\\${COMP_WORDS[COMP_CWORD]}\"\n prev=\"\\${COMP_WORDS[COMP_CWORD-1]}\"\n if [ \"$prev\" = \"--format\" ] || [ \"$prev\" = \"-f\" ]; then\n COMPREPLY=( $(compgen -W \"${FORMATS}\" -- \"$cur\") ); return\n fi\n if [ \"$COMP_CWORD\" -eq 1 ]; then\n COMPREPLY=( $(compgen -W \"${SUBCOMMANDS} ${FLAGS}\" -f -- \"$cur\") ); return\n fi\n COMPREPLY=( $(compgen -W \"${FLAGS}\" -f -- \"$cur\") )\n}\ncomplete -F _pg_explain pg-explain\n`;\n\nconst ZSH = `#compdef pg-explain\n# pg-explain zsh completion\n_pg_explain() {\n local -a subcmds flags\n subcmds=(${SUBCOMMANDS.split(\" \")\n .map((s) => `'${s}'`)\n .join(\" \")})\n flags=(${FLAGS.split(\" \")\n .map((f) => `'${f}'`)\n .join(\" \")})\n if (( CURRENT == 2 )); then\n _alternative \"subcmds:subcommand:(\\${subcmds})\" 'files:file:_files' \"flags:flag:(\\${flags})\"\n else\n _alternative 'files:file:_files' \"flags:flag:(\\${flags})\"\n fi\n}\ncompdef _pg_explain pg-explain\n`;\n\nconst FISH = `# pg-explain fish completion\ncomplete -c pg-explain -f\n${SUBCOMMANDS.split(\" \")\n .map((s) => `complete -c pg-explain -n '__fish_use_subcommand' -a '${s}'`)\n .join(\"\\n\")}\ncomplete -c pg-explain -l format -x -a '${FORMATS}'\n${FLAGS.split(\" \")\n .filter((f) => f.startsWith(\"--\"))\n .map((f) => `complete -c pg-explain -l '${f.replace(/^--/, \"\")}'`)\n .join(\"\\n\")}\n`;\n\nexport function runCompletion(shell: string | undefined): ExitCode {\n const scripts: Record<string, string> = { bash: BASH, zsh: ZSH, fish: FISH };\n const script = shell ? scripts[shell] : undefined;\n if (!script) {\n process.stderr.write(\n `Usage: pg-explain completion <bash|zsh|fish>\\n` +\n ` bash: pg-explain completion bash > /etc/bash_completion.d/pg-explain\\n` +\n ` zsh: pg-explain completion zsh > \"\\${fpath[1]}/_pg-explain\"\\n` +\n ` fish: pg-explain completion fish > ~/.config/fish/completions/pg-explain.fish\\n`,\n );\n return ExitCode.Usage;\n }\n process.stdout.write(script);\n return ExitCode.Success;\n}\n","import { executionMs, nodeLabel } from \"./metrics.ts\";\nimport type { AnalysisResult, Diagnostic, PlanNode } from \"./model.ts\";\nimport { walk } from \"./parse.ts\";\n\nexport interface SignatureDelta {\n signature: string;\n beforeMs: number;\n afterMs: number;\n deltaMs: number;\n /** Positive = slower in \"after\". */\n deltaPct: number | null;\n}\n\nexport interface DiffResult {\n beforeMs: number | undefined;\n afterMs: number | undefined;\n execDeltaMs: number | undefined;\n execDeltaPct: number | undefined;\n /** Whether both plans had ANALYZE timing (otherwise deltas use cost as a proxy). */\n timed: boolean;\n regressed: SignatureDelta[];\n improved: SignatureDelta[];\n added: SignatureDelta[];\n removed: SignatureDelta[];\n newFindings: Diagnostic[];\n resolvedFindings: Diagnostic[];\n}\n\n/** Self time if available, else self cost (totalCost minus children) as a proxy. */\nfunction weight(node: PlanNode): number {\n if (node.metrics.selfMs !== undefined) return node.metrics.selfMs;\n const own = node.totalCost ?? 0;\n let children = 0;\n for (const c of node.children) children += c.totalCost ?? 0;\n return Math.max(own - children, 0);\n}\n\n/** A stable key for matching nodes across two plans of the same query. */\nfunction signature(node: PlanNode): string {\n return nodeLabel(node);\n}\n\nfunction weightBySignature(result: AnalysisResult): Map<string, number> {\n const map = new Map<string, number>();\n walk(result.tree.root, (node) => {\n const key = signature(node);\n map.set(key, (map.get(key) ?? 0) + weight(node));\n });\n return map;\n}\n\nfunction findingKey(d: Diagnostic): string {\n return `${d.code}|${d.location?.relation ?? \"\"}`;\n}\n\n/** Compare two analyzed plans (before → after). Pure. */\nexport function diffAnalyses(before: AnalysisResult, after: AnalysisResult): DiffResult {\n const beforeMs = executionMs(before.tree);\n const afterMs = executionMs(after.tree);\n const timed = before.tree.hasAnalyze && after.tree.hasAnalyze;\n\n let execDeltaMs: number | undefined;\n let execDeltaPct: number | undefined;\n if (beforeMs !== undefined && afterMs !== undefined) {\n execDeltaMs = afterMs - beforeMs;\n execDeltaPct = beforeMs > 0 ? (100 * execDeltaMs) / beforeMs : undefined;\n }\n\n const beforeMap = weightBySignature(before);\n const afterMap = weightBySignature(after);\n const keys = new Set([...beforeMap.keys(), ...afterMap.keys()]);\n\n const regressed: SignatureDelta[] = [];\n const improved: SignatureDelta[] = [];\n const added: SignatureDelta[] = [];\n const removed: SignatureDelta[] = [];\n\n for (const key of keys) {\n const b = beforeMap.get(key);\n const a = afterMap.get(key);\n const beforeVal = b ?? 0;\n const afterVal = a ?? 0;\n const deltaMs = afterVal - beforeVal;\n const deltaPct = beforeVal > 0 ? (100 * deltaMs) / beforeVal : null;\n const entry: SignatureDelta = {\n signature: key,\n beforeMs: beforeVal,\n afterMs: afterVal,\n deltaMs,\n deltaPct,\n };\n\n if (b === undefined) added.push(entry);\n else if (a === undefined) removed.push(entry);\n else if (deltaMs > 0.0001) regressed.push(entry);\n else if (deltaMs < -0.0001) improved.push(entry);\n }\n\n regressed.sort((x, y) => y.deltaMs - x.deltaMs);\n improved.sort((x, y) => x.deltaMs - y.deltaMs);\n added.sort((x, y) => y.afterMs - x.afterMs);\n removed.sort((x, y) => y.beforeMs - x.beforeMs);\n\n const beforeKeys = new Set(before.diagnostics.map(findingKey));\n const afterKeys = new Set(after.diagnostics.map(findingKey));\n const newFindings = after.diagnostics.filter((d) => !beforeKeys.has(findingKey(d)));\n const resolvedFindings = before.diagnostics.filter((d) => !afterKeys.has(findingKey(d)));\n\n return {\n beforeMs,\n afterMs,\n execDeltaMs,\n execDeltaPct,\n timed,\n regressed,\n improved,\n added,\n removed,\n newFindings,\n resolvedFindings,\n };\n}\n","import type { DiffResult, SignatureDelta } from \"../core/diff.ts\";\nimport { colors } from \"../util/color.ts\";\nimport { fmtMs } from \"../util/format.ts\";\n\nexport type DiffFormat = \"terminal\" | \"markdown\" | \"json\";\n\nexport function renderDiff(diff: DiffResult, format: DiffFormat): string {\n if (format === \"json\") return JSON.stringify(diff, null, 2);\n if (format === \"markdown\") return renderDiffMarkdown(diff);\n return renderDiffTerminal(diff);\n}\n\nfunction headline(diff: DiffResult): string {\n if (diff.execDeltaMs === undefined)\n return \"Compared plans (no timing available — using cost as a proxy).\";\n const dir = diff.execDeltaMs > 0 ? \"slower\" : diff.execDeltaMs < 0 ? \"faster\" : \"unchanged\";\n const pct =\n diff.execDeltaPct !== undefined\n ? ` (${diff.execDeltaPct >= 0 ? \"+\" : \"\"}${diff.execDeltaPct.toFixed(1)}%)`\n : \"\";\n return `${fmtMs(Math.abs(diff.execDeltaMs))} ${dir}${pct}: ${fmtMs(diff.beforeMs ?? 0)} → ${fmtMs(diff.afterMs ?? 0)}`;\n}\n\nfunction renderDiffTerminal(diff: DiffResult): string {\n const c = colors();\n const out: string[] = [];\n out.push(c.bold(\"pg-explain diff (before → after)\"));\n const slower = (diff.execDeltaMs ?? 0) > 0;\n out.push(`${c.bold(\"Verdict:\")} ${slower ? c.red(headline(diff)) : c.green(headline(diff))}`);\n out.push(\"\");\n\n section(out, \"Regressed nodes (slower)\", diff.regressed, (d) => c.red(deltaLine(d)));\n section(out, \"Improved nodes (faster)\", diff.improved, (d) => c.green(deltaLine(d)));\n section(out, \"Added nodes\", diff.added, (d) => `${d.signature} +${fmtMs(d.afterMs)}`);\n section(out, \"Removed nodes\", diff.removed, (d) => `${d.signature} -${fmtMs(d.beforeMs)}`);\n\n if (diff.newFindings.length) {\n out.push(c.bold(c.red(\"New findings\")));\n for (const f of diff.newFindings) out.push(` + [${f.severity}] ${f.title} ${c.dim(f.code)}`);\n out.push(\"\");\n }\n if (diff.resolvedFindings.length) {\n out.push(c.bold(c.green(\"Resolved findings\")));\n for (const f of diff.resolvedFindings) out.push(` - ${f.title} ${c.dim(f.code)}`);\n out.push(\"\");\n }\n return `${out.join(\"\\n\").trimEnd()}\\n`;\n}\n\nfunction section(\n out: string[],\n title: string,\n items: SignatureDelta[],\n line: (d: SignatureDelta) => string,\n): void {\n if (!items.length) return;\n out.push(colors().bold(title));\n for (const d of items.slice(0, 10)) out.push(` ${line(d)}`);\n out.push(\"\");\n}\n\nfunction deltaLine(d: SignatureDelta): string {\n const pct =\n d.deltaPct !== null ? ` (${d.deltaPct >= 0 ? \"+\" : \"\"}${d.deltaPct.toFixed(0)}%)` : \"\";\n const sign = d.deltaMs >= 0 ? \"+\" : \"-\";\n return `${d.signature} ${sign}${fmtMs(Math.abs(d.deltaMs))}${pct} [${fmtMs(d.beforeMs)} → ${fmtMs(d.afterMs)}]`;\n}\n\nfunction renderDiffMarkdown(diff: DiffResult): string {\n const out: string[] = [\"# pg-explain diff\", \"\", `> **${headline(diff)}**`, \"\"];\n\n const table = (title: string, items: SignatureDelta[]) => {\n if (!items.length) return;\n out.push(`## ${title}`, \"\", \"| Node | Before | After | Δ |\", \"| --- | --- | --- | --- |\");\n for (const d of items.slice(0, 20)) {\n const pct =\n d.deltaPct !== null ? ` (${d.deltaPct >= 0 ? \"+\" : \"\"}${d.deltaPct.toFixed(0)}%)` : \"\";\n out.push(\n `| ${d.signature} | ${fmtMs(d.beforeMs)} | ${fmtMs(d.afterMs)} | ${d.deltaMs >= 0 ? \"+\" : \"\"}${fmtMs(d.deltaMs)}${pct} |`,\n );\n }\n out.push(\"\");\n };\n\n table(\"Regressed (slower)\", diff.regressed);\n table(\"Improved (faster)\", diff.improved);\n table(\"Added\", diff.added);\n table(\"Removed\", diff.removed);\n\n if (diff.newFindings.length) {\n out.push(\"## New findings\", \"\");\n for (const f of diff.newFindings) out.push(`- **${f.severity}** ${f.title} \\`${f.code}\\``);\n out.push(\"\");\n }\n if (diff.resolvedFindings.length) {\n out.push(\"## Resolved findings\", \"\");\n for (const f of diff.resolvedFindings) out.push(`- ${f.title} \\`${f.code}\\``);\n out.push(\"\");\n }\n return `${out.join(\"\\n\").trimEnd()}\\n`;\n}\n","import { readFile, writeFile } from \"node:fs/promises\";\nimport type { PgExplainConfig } from \"../config.ts\";\nimport { diffAnalyses } from \"../core/diff.ts\";\nimport { opError } from \"../diagnostics/catalog.ts\";\nimport { analyze } from \"../index.ts\";\nimport { type DiffFormat, renderDiff } from \"../report/diff.ts\";\nimport { configureColor } from \"../util/color.ts\";\nimport { ExitCode } from \"../util/exit.ts\";\n\nexport interface DiffArgs {\n before: string;\n after: string;\n format: DiffFormat;\n output?: string;\n color: \"auto\" | \"always\" | \"never\";\n redact?: boolean;\n config: PgExplainConfig;\n /** Exit 1 if execution time regressed by at least this percent. */\n failOnSlowerPct?: number;\n /** Exit 1 if any new finding appears. */\n failOnNewFindings?: boolean;\n}\n\n/** diff command: compare two plans and report what changed. */\nexport async function runDiff(args: DiffArgs): Promise<ExitCode> {\n const [beforeText, afterText] = await Promise.all([readPlan(args.before), readPlan(args.after)]);\n const before = analyze(beforeText, { config: args.config, redact: args.redact });\n const after = analyze(afterText, { config: args.config, redact: args.redact });\n const diff = diffAnalyses(before, after);\n\n configureColor(args.format === \"terminal\" ? args.color : \"never\");\n const text = renderDiff(diff, args.format);\n if (args.output) await writeFile(args.output, text);\n else process.stdout.write(text.endsWith(\"\\n\") ? text : `${text}\\n`);\n\n // CI gate.\n if (args.failOnNewFindings && diff.newFindings.length > 0) return ExitCode.CiGate;\n if (\n args.failOnSlowerPct !== undefined &&\n diff.execDeltaPct !== undefined &&\n diff.execDeltaPct >= args.failOnSlowerPct\n ) {\n return ExitCode.CiGate;\n }\n return ExitCode.Success;\n}\n\nasync function readPlan(path: string): Promise<string> {\n try {\n return await readFile(path, \"utf8\");\n } catch (err) {\n throw opError(\n \"PGX_EMPTY_INPUT\",\n {\n detail: `Could not read plan file '${path}': ${err instanceof Error ? err.message : String(err)}`,\n },\n err,\n );\n }\n}\n","/**\n * Diagnostics and progress go to stderr; report output goes to stdout. This keeps\n * `pg-explain ... > report.md` and `... | jq` clean. Nothing here ever touches stdout.\n */\nexport type LogLevel = \"quiet\" | \"normal\" | \"verbose\" | \"debug\";\n\nlet level: LogLevel = \"normal\";\n\nexport function setLogLevel(l: LogLevel): void {\n level = l;\n}\n\nexport function isDebug(): boolean {\n return level === \"debug\";\n}\n\nfunction write(msg: string): void {\n process.stderr.write(`${msg}\\n`);\n}\n\n/** Normal informational output (suppressed by --quiet). */\nexport function logInfo(msg: string): void {\n if (level !== \"quiet\") write(msg);\n}\n\n/** Extra detail (only with --verbose/--debug). */\nexport function logVerbose(msg: string): void {\n if (level === \"verbose\" || level === \"debug\") write(msg);\n}\n\n/** Errors are always shown, even under --quiet. */\nexport function logError(msg: string): void {\n write(msg);\n}\n","/** Map a server_version_num (e.g. 160006) to the EXPLAIN options it supports. */\nexport interface ServerCapabilities {\n versionNum: number;\n major: number;\n /** SUMMARY — PG 10+ */\n summary: boolean;\n /** SETTINGS — PG 12+ */\n settings: boolean;\n /** WAL — PG 13+ (requires ANALYZE) */\n wal: boolean;\n /** GENERIC_PLAN — PG 16+ (mutually exclusive with ANALYZE) */\n genericPlan: boolean;\n /** SERIALIZE — PG 17+ (requires ANALYZE) */\n serialize: boolean;\n /** MEMORY — PG 17+ */\n memory: boolean;\n}\n\nexport function capabilities(versionNum: number): ServerCapabilities {\n const major = Math.floor(versionNum / 10000);\n return {\n versionNum,\n major,\n summary: major >= 10,\n settings: major >= 12,\n wal: major >= 13,\n genericPlan: major >= 16,\n serialize: major >= 17,\n memory: major >= 17,\n };\n}\n\n/** \"16.6\" style label from a version number, for messages. */\nexport function versionLabel(versionNum: number): string {\n const major = Math.floor(versionNum / 10000);\n const minor = versionNum % 100;\n return `${major}.${minor}`;\n}\n","import { opError } from \"../diagnostics/catalog.ts\";\nimport type { ServerCapabilities } from \"./version.ts\";\nimport { versionLabel } from \"./version.ts\";\n\nexport interface ExplainFlags {\n analyze: boolean;\n buffers: boolean;\n verbose: boolean;\n settings: boolean;\n wal: boolean;\n /** Default true; set false to add TIMING OFF (reduces ANALYZE overhead). */\n timing: boolean;\n /** Default true; set false to add COSTS OFF. */\n costs: boolean;\n summary: boolean;\n genericPlan: boolean;\n /** Auto-omit options the server can't do instead of erroring. */\n compat: boolean;\n}\n\nexport const DEFAULT_EXPLAIN_FLAGS: ExplainFlags = {\n analyze: true,\n buffers: true,\n verbose: false,\n settings: false,\n wal: false,\n timing: true,\n costs: true,\n summary: true,\n genericPlan: false,\n compat: false,\n};\n\nexport interface BuiltExplain {\n /** The EXPLAIN prefix, e.g. \"EXPLAIN (FORMAT JSON, ANALYZE, BUFFERS)\". */\n prefix: string;\n /** Options dropped under --compat because the server is too old. */\n omitted: string[];\n}\n\n/** Build the EXPLAIN option list, gating each option on the server version. */\nexport function buildExplain(flags: ExplainFlags, caps: ServerCapabilities): BuiltExplain {\n if (flags.genericPlan && flags.analyze) {\n throw opError(\"PGX_INVALID_EXPLAIN_OPTION\", {\n detail:\n \"GENERIC_PLAN cannot be combined with ANALYZE (GENERIC_PLAN does not execute the query).\",\n });\n }\n if (flags.wal && !flags.analyze) {\n throw opError(\"PGX_INVALID_EXPLAIN_OPTION\", { detail: \"WAL requires ANALYZE.\" });\n }\n\n const opts: string[] = [\"FORMAT JSON\"];\n const omitted: string[] = [];\n\n const gate = (label: string, supported: boolean, requiredMajor: number): boolean => {\n if (supported) return true;\n if (flags.compat) {\n omitted.push(label);\n return false;\n }\n throw opError(\"PGX_UNSUPPORTED_PG_VERSION\", {\n detail: `EXPLAIN (${label}) requires PostgreSQL ${requiredMajor}; server is ${versionLabel(caps.versionNum)}.`,\n meta: { option: label, requiredMajor, serverVersion: caps.versionNum },\n });\n };\n\n if (flags.genericPlan && gate(\"GENERIC_PLAN\", caps.genericPlan, 16)) opts.push(\"GENERIC_PLAN\");\n if (flags.analyze) opts.push(\"ANALYZE\");\n if (flags.buffers) opts.push(\"BUFFERS\");\n if (flags.verbose) opts.push(\"VERBOSE\");\n if (flags.settings && gate(\"SETTINGS\", caps.settings, 12)) opts.push(\"SETTINGS\");\n if (flags.wal && gate(\"WAL\", caps.wal, 13)) opts.push(\"WAL\");\n if (!flags.costs) opts.push(\"COSTS OFF\");\n if (flags.analyze && !flags.timing) opts.push(\"TIMING OFF\");\n if (!flags.summary && caps.summary) opts.push(\"SUMMARY OFF\");\n\n return { prefix: `EXPLAIN (${opts.join(\", \")})`, omitted };\n}\n\n// ── statement handling ────────────────────────────────────────────────────────\n\n/** Strip leading comments/whitespace to find the first real keyword. */\nfunction leadingKeyword(sql: string): string {\n const cleaned = sql\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \" \")\n .replace(/--[^\\n]*/g, \" \")\n .trim();\n return (cleaned.split(/\\s+/)[0] ?? \"\").toUpperCase();\n}\n\n/** True for statements EXPLAIN ANALYZE can run without changing data. */\nexport function isReadOnlyStatement(sql: string): boolean {\n const kw = leadingKeyword(sql);\n if ([\"SELECT\", \"TABLE\", \"VALUES\", \"SHOW\", \"EXPLAIN\"].includes(kw)) return true;\n // A WITH may wrap a data-modifying CTE — treat as mutating if so.\n if (kw === \"WITH\") return !/\\b(INSERT|UPDATE|DELETE|MERGE)\\b/i.test(sql);\n return false;\n}\n\n/**\n * Split a SQL string into top-level statements, respecting string literals,\n * quoted identifiers, line/block comments, and dollar-quoted bodies.\n * ponytail: handles real-world SQL; exotic nested cases fall back to one statement.\n */\nexport function splitStatements(sql: string): string[] {\n const out: string[] = [];\n let buf = \"\";\n let i = 0;\n const n = sql.length;\n\n while (i < n) {\n const ch = sql[i];\n const two = sql.slice(i, i + 2);\n\n if (two === \"--\") {\n const nl = sql.indexOf(\"\\n\", i);\n const end = nl === -1 ? n : nl;\n buf += sql.slice(i, end);\n i = end;\n } else if (two === \"/*\") {\n const close = sql.indexOf(\"*/\", i + 2);\n const end = close === -1 ? n : close + 2;\n buf += sql.slice(i, end);\n i = end;\n } else if (ch === \"'\" || ch === '\"') {\n const end = scanQuoted(sql, i, ch);\n buf += sql.slice(i, end);\n i = end;\n } else if (ch === \"$\") {\n const tag = matchDollarTag(sql, i);\n if (tag) {\n const close = sql.indexOf(tag, i + tag.length);\n const end = close === -1 ? n : close + tag.length;\n buf += sql.slice(i, end);\n i = end;\n } else {\n buf += ch;\n i++;\n }\n } else if (ch === \";\") {\n if (buf.trim()) out.push(buf.trim());\n buf = \"\";\n i++;\n } else {\n buf += ch;\n i++;\n }\n }\n if (buf.trim()) out.push(buf.trim());\n return out;\n}\n\nfunction scanQuoted(sql: string, start: number, quote: string): number {\n let i = start + 1;\n while (i < sql.length) {\n if (sql[i] === quote) {\n if (sql[i + 1] === quote)\n i += 2; // doubled escape\n else return i + 1;\n } else {\n i++;\n }\n }\n return sql.length;\n}\n\nfunction matchDollarTag(sql: string, start: number): string | null {\n const m = /^\\$[A-Za-z_]*\\$/.exec(sql.slice(start));\n return m ? m[0] : null;\n}\n\n/** Parse a duration like \"60s\", \"500ms\", \"2min\", or a bare integer (ms) into ms. */\nexport function parseDurationMs(value: string): number {\n const m = /^(\\d+(?:\\.\\d+)?)\\s*(ms|s|min|m|h)?$/.exec(value.trim());\n if (!m?.[1])\n throw opError(\"PGX_INVALID_EXPLAIN_OPTION\", {\n detail: `Invalid duration '${value}'. Use e.g. 60s, 500ms, 2min.`,\n });\n const n = Number(m[1]);\n switch (m[2]) {\n case \"s\":\n return Math.round(n * 1000);\n case \"min\":\n case \"m\":\n return Math.round(n * 60_000);\n case \"h\":\n return Math.round(n * 3_600_000);\n default:\n return Math.round(n); // ms or bare integer\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport type { Client, ClientConfig } from \"pg\";\nimport { opError } from \"../diagnostics/catalog.ts\";\nimport { AppError } from \"../diagnostics/diagnostic.ts\";\nimport { logVerbose } from \"../util/log.ts\";\nimport { buildExplain, type ExplainFlags } from \"./explain.ts\";\nimport { capabilities, type ServerCapabilities } from \"./version.ts\";\n\nexport interface ConnectionOptions {\n dsn?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n /** Prefer PGPASSWORD/.pgpass; this exists for completeness. */\n password?: string;\n /** disable | require | verify-ca | verify-full */\n sslmode?: string;\n sslrootcert?: string;\n connectTimeoutMs: number;\n}\n\nexport interface RunOptions {\n connection: ConnectionOptions;\n statement: string;\n params?: string[];\n flags: ExplainFlags;\n statementTimeoutMs: number;\n lockTimeoutMs: number;\n /** Allow a non-SELECT to actually execute (still rolled back). */\n forceWrite: boolean;\n /** Keep the BEGIN…ROLLBACK wrapper (default true; almost never turn off). */\n rollback: boolean;\n}\n\nexport interface RunResult {\n /** The EXPLAIN (FORMAT JSON) output, serialized to text for the parser. */\n json: string;\n caps: ServerCapabilities;\n /** Options dropped under --compat. */\n omitted: string[];\n}\n\n// ── lazy pg loader ────────────────────────────────────────────────────────────\n\nasync function newClient(config: ClientConfig): Promise<Client> {\n let mod: typeof import(\"pg\");\n try {\n mod = await import(\"pg\");\n } catch (err) {\n throw opError(\"PGX_PG_DRIVER_MISSING\", {}, err);\n }\n // pg is CJS; the Client constructor is on the default export (or the namespace).\n // biome-ignore lint/suspicious/noExplicitAny: CJS/ESM interop for the optional driver.\n const lib: any = (mod as any).default ?? mod;\n return new lib.Client(config) as Client;\n}\n\nfunction buildClientConfig(c: ConnectionOptions, ca?: string): ClientConfig {\n const config: ClientConfig = { connectionTimeoutMillis: c.connectTimeoutMs };\n\n if (c.dsn) {\n config.connectionString = c.dsn;\n } else {\n // Leave fields undefined so pg falls back to PG* env vars and ~/.pgpass.\n if (c.host) config.host = c.host;\n if (c.port) config.port = c.port;\n if (c.database) config.database = c.database;\n if (c.user) config.user = c.user;\n if (c.password) config.password = c.password;\n }\n\n if (c.sslmode && c.sslmode !== \"disable\" && c.sslmode !== \"prefer\") {\n const verify = c.sslmode === \"verify-ca\" || c.sslmode === \"verify-full\";\n config.ssl = ca ? { rejectUnauthorized: verify, ca } : { rejectUnauthorized: verify };\n } else if (c.sslmode === \"disable\") {\n config.ssl = false;\n }\n\n return config;\n}\n\n/**\n * Connect, run EXPLAIN inside a guarded, auto-rolled-back transaction, and return\n * the plan JSON. Safety guarantees:\n * BEGIN → SET LOCAL statement_timeout / lock_timeout → (read-only unless --force)\n * → EXPLAIN … → ROLLBACK (always; an EXPLAIN never needs to commit).\n * The pool is always torn down. All errors become actionable AppErrors.\n */\nexport async function runExplain(opts: RunOptions): Promise<RunResult> {\n const ca = opts.connection.sslrootcert\n ? await readFile(opts.connection.sslrootcert, \"utf8\").catch((err) => {\n throw opError(\"PGX_SSL_VERIFY_FAILED\", {\n detail: `Could not read --sslrootcert '${opts.connection.sslrootcert}': ${err instanceof Error ? err.message : String(err)}`,\n });\n })\n : undefined;\n\n const client = await newClient(buildClientConfig(opts.connection, ca));\n\n try {\n await client.connect();\n } catch (err) {\n throw mapConnectError(err);\n }\n\n try {\n const verNum = await fetchVersionNum(client);\n const caps = capabilities(verNum);\n const built = buildExplain(opts.flags, caps);\n const explainSql = `${built.prefix} ${opts.statement}`;\n logVerbose(`server_version_num=${verNum}; ${built.prefix}`);\n\n const useTxn = opts.rollback;\n if (useTxn) await client.query(\"BEGIN\");\n try {\n if (useTxn) {\n await client.query(`SET LOCAL statement_timeout = ${msInt(opts.statementTimeoutMs)}`);\n await client.query(`SET LOCAL lock_timeout = ${msInt(opts.lockTimeoutMs)}`);\n if (!opts.forceWrite) await client.query(\"SET LOCAL transaction_read_only = on\");\n }\n const res = await client.query<{ \"QUERY PLAN\": unknown }>({\n text: explainSql,\n values: opts.params ?? [],\n });\n return { json: extractPlanJson(res.rows), caps, omitted: built.omitted };\n } catch (err) {\n throw mapQueryError(err);\n } finally {\n if (useTxn) await client.query(\"ROLLBACK\").catch(() => {});\n }\n } finally {\n await client.end().catch(() => {});\n }\n}\n\nfunction msInt(ms: number): number {\n return Math.max(0, Math.floor(ms));\n}\n\nasync function fetchVersionNum(client: Client): Promise<number> {\n try {\n const res = await client.query<{ server_version_num: string }>(\"SHOW server_version_num\");\n return Number(res.rows[0]?.server_version_num ?? 0);\n } catch (err) {\n throw mapQueryError(err);\n }\n}\n\nfunction extractPlanJson(rows: Array<{ \"QUERY PLAN\": unknown }>): string {\n const value = rows[0]?.[\"QUERY PLAN\"];\n if (value === undefined) {\n throw opError(\"PGX_UNEXPECTED_PLAN_SHAPE\", {\n detail: \"The server returned no plan rows for EXPLAIN.\",\n });\n }\n // pg parses the json column into a JS value; re-serialize for the parser.\n return typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\n// ── error mapping (SQLSTATE / network → actionable PGX codes) ─────────────────\n\ninterface PgError {\n code?: string;\n message?: string;\n routine?: string;\n}\n\nfunction asPgError(err: unknown): PgError {\n if (err && typeof err === \"object\") return err as PgError;\n return { message: String(err) };\n}\n\nfunction mapConnectError(err: unknown): AppError {\n if (err instanceof AppError) return err;\n const e = asPgError(err);\n const msg = e.message ?? \"\";\n\n switch (e.code) {\n case \"28P01\":\n case \"28000\":\n return opError(\"PGX_AUTH_FAILED\", { detail: msg }, err);\n case \"3D000\":\n return opError(\"PGX_DB_NOT_FOUND\", { detail: msg }, err);\n case \"ECONNREFUSED\":\n case \"ENOTFOUND\":\n case \"EAI_AGAIN\":\n case \"EHOSTUNREACH\":\n return opError(\"PGX_HOST_UNREACHABLE\", { detail: msg }, err);\n case \"ETIMEDOUT\":\n return opError(\"PGX_CONN_TIMEOUT\", { detail: msg }, err);\n }\n if (/timeout/i.test(msg)) return opError(\"PGX_CONN_TIMEOUT\", { detail: msg }, err);\n if (/self.signed|certificate|verify|CERT_/i.test(msg))\n return opError(\"PGX_SSL_VERIFY_FAILED\", { detail: msg }, err);\n if (/SSL|encryption/i.test(msg)) return opError(\"PGX_SSL_REQUIRED\", { detail: msg }, err);\n return opError(\"PGX_HOST_UNREACHABLE\", { detail: msg }, err);\n}\n\nfunction mapQueryError(err: unknown): AppError {\n if (err instanceof AppError) return err;\n const e = asPgError(err);\n const msg = e.message ?? \"\";\n const meta = e.code ? { sqlState: e.code } : undefined;\n\n switch (e.code) {\n case \"57014\":\n return /statement timeout/i.test(msg)\n ? opError(\"PGX_STATEMENT_TIMEOUT\", { detail: msg, meta }, err)\n : opError(\"PGX_QUERY_CANCELED\", { detail: msg, meta }, err);\n case \"55P03\":\n return opError(\"PGX_LOCK_TIMEOUT\", { detail: msg, meta }, err);\n case \"42501\":\n return opError(\"PGX_PERMISSION_DENIED\", { detail: msg, meta }, err);\n case \"42P01\":\n return opError(\"PGX_RELATION_NOT_FOUND\", { detail: msg, meta }, err);\n case \"28P01\":\n case \"28000\":\n return opError(\"PGX_AUTH_FAILED\", { detail: msg, meta }, err);\n case \"3D000\":\n return opError(\"PGX_DB_NOT_FOUND\", { detail: msg, meta }, err);\n default:\n return opError(\"PGX_QUERY_FAILED\", { detail: msg, meta }, err);\n }\n}\n","import { readFile } from \"node:fs/promises\";\nimport type { PgExplainConfig } from \"../config.ts\";\nimport { type ConnectionOptions, runExplain } from \"../db/client.ts\";\nimport { type ExplainFlags, isReadOnlyStatement, splitStatements } from \"../db/explain.ts\";\nimport { opError } from \"../diagnostics/catalog.ts\";\nimport { analyze } from \"../index.ts\";\nimport type { ExitCode } from \"../util/exit.ts\";\nimport { logInfo } from \"../util/log.ts\";\nimport { type EmitOptions, emit } from \"./emit.ts\";\n\nexport interface RunArgs extends EmitOptions {\n connection: ConnectionOptions;\n query?: string;\n file?: string;\n statementIndex?: number;\n /** Values for $1, $2, … in the statement. */\n params?: string[];\n flags: ExplainFlags;\n statementTimeoutMs: number;\n lockTimeoutMs: number;\n forceWrite: boolean;\n rollback: boolean;\n redact?: boolean;\n config: PgExplainConfig;\n}\n\n/** run command: connect, EXPLAIN (safely), parse, analyze, render. */\nexport async function runRun(args: RunArgs): Promise<ExitCode> {\n const sql = await resolveSql(args);\n const statements = splitStatements(sql);\n const statement = selectStatement(statements, args.statementIndex);\n\n // Safety: EXPLAIN ANALYZE executes the statement. Refuse data-modifying ones\n // unless the user explicitly opts in with --force (still auto-rolled-back).\n if (\n args.flags.analyze &&\n !args.flags.genericPlan &&\n !isReadOnlyStatement(statement) &&\n !args.forceWrite\n ) {\n const verb = statement.trim().split(/\\s+/)[0]?.toUpperCase() ?? \"statement\";\n throw opError(\"PGX_NON_SELECT_REFUSED\", {\n detail: `Refusing to ANALYZE a non-SELECT (${verb}) — it would modify data.`,\n });\n }\n\n const result = await runExplain({\n connection: args.connection,\n statement,\n params: args.params,\n flags: args.flags,\n statementTimeoutMs: args.statementTimeoutMs,\n lockTimeoutMs: args.lockTimeoutMs,\n forceWrite: args.forceWrite,\n rollback: args.rollback,\n });\n\n if (result.omitted.length) {\n logInfo(\n `Note: server is PostgreSQL ${result.caps.major}; skipped unsupported option(s): ${result.omitted.join(\", \")}.`,\n );\n }\n\n const analysis = analyze(result.json, { config: args.config, redact: args.redact });\n return emit(analysis, args);\n}\n\nasync function resolveSql(args: RunArgs): Promise<string> {\n if (args.query) return args.query;\n if (args.file) {\n try {\n return await readFile(args.file, \"utf8\");\n } catch (err) {\n throw opError(\n \"PGX_EMPTY_INPUT\",\n {\n detail: `Could not read SQL file '${args.file}': ${err instanceof Error ? err.message : String(err)}`,\n },\n err,\n );\n }\n }\n throw opError(\"PGX_EMPTY_INPUT\", {\n detail: \"The run command needs SQL: pass --query '<sql>' or --file <path.sql>.\",\n });\n}\n\nfunction selectStatement(statements: string[], index?: number): string {\n if (statements.length === 0) {\n throw opError(\"PGX_EMPTY_INPUT\", { detail: \"No SQL statement found after parsing.\" });\n }\n if (index !== undefined) {\n const stmt = statements[index - 1];\n if (!stmt) {\n throw opError(\"PGX_MULTIPLE_STATEMENTS\", {\n detail: `--statement ${index} is out of range; found ${statements.length} statement(s).`,\n });\n }\n return stmt;\n }\n if (statements.length > 1) {\n throw opError(\"PGX_MULTIPLE_STATEMENTS\", {\n detail: `Found ${statements.length} statements. Pick one with --statement <n> (1-based).`,\n });\n }\n // Length is exactly 1 here.\n return statements[0] as string;\n}\n","import type { Diagnostic } from \"../core/model.ts\";\nimport { colors } from \"../util/color.ts\";\nimport { scrubCredentials } from \"./diagnostic.ts\";\n\n/**\n * Format a single diagnostic for stderr (fatal operational errors). Always tells the\n * user what/why/how, with copy-pasteable commands. Credentials are scrubbed last.\n */\nexport function formatDiagnostic(d: Diagnostic): string {\n const c = colors();\n const tag =\n d.severity === \"error\"\n ? c.red(c.bold(\"error\"))\n : d.severity === \"warn\"\n ? c.yellow(\"warning\")\n : c.cyan(\"info\");\n\n const lines: string[] = [];\n lines.push(`${tag} ${c.bold(d.title)} ${c.dim(`[${d.code}]`)}`);\n lines.push(` ${c.dim(\"what:\")} ${d.detail}`);\n lines.push(` ${c.dim(\"why: \")} ${d.cause}`);\n lines.push(` ${c.dim(\"fix: \")} ${d.remediation.summary}`);\n for (const step of d.remediation.steps ?? []) lines.push(` • ${step}`);\n for (const cmd of d.remediation.commands ?? []) {\n const body = cmd.sql ?? cmd.shell ?? \"\";\n const label = cmd.label ? `${c.dim(`${cmd.label}:`)} ` : \"\";\n lines.push(` ${label}${c.green(body)}`);\n }\n if (d.docsUrl) lines.push(` ${c.dim(`docs: ${d.docsUrl}`)}`);\n\n return scrubCredentials(lines.join(\"\\n\"));\n}\n","import { defineCommand, runMain } from \"citty\";\nimport pkg from \"../package.json\" with { type: \"json\" };\nimport { runAnalyze } from \"./commands/analyze.ts\";\nimport { runCompletion } from \"./commands/completion.ts\";\nimport { runDiff } from \"./commands/diff.ts\";\nimport type { EmitOptions } from \"./commands/emit.ts\";\nimport { runRun } from \"./commands/run.ts\";\nimport { loadConfig } from \"./config.ts\";\nimport type { Diagnostic, Severity } from \"./core/model.ts\";\nimport type { ConnectionOptions } from \"./db/client.ts\";\nimport { type ExplainFlags, parseDurationMs } from \"./db/explain.ts\";\nimport { opDiagnostic } from \"./diagnostics/catalog.ts\";\nimport { AppError, scrubCredentials } from \"./diagnostics/diagnostic.ts\";\nimport { formatDiagnostic } from \"./diagnostics/print.ts\";\nimport { type Format, isFormat } from \"./report/render.ts\";\nimport { configureColor } from \"./util/color.ts\";\nimport { ExitCode } from \"./util/exit.ts\";\nimport { isDebug, logError, setLogLevel } from \"./util/log.ts\";\n\nconst SEVERITIES: Severity[] = [\"error\", \"warn\", \"info\"];\n\n// biome-ignore lint/suspicious/noExplicitAny: citty's parsed args are loosely typed.\ntype Args = Record<string, any>;\n\nconst outputArgs = {\n format: {\n type: \"string\",\n default: \"terminal\",\n alias: \"f\",\n description: \"terminal | markdown | json | html | text\",\n },\n output: {\n type: \"string\",\n alias: \"o\",\n description: \"Write the report to a file instead of stdout\",\n },\n tldr: { type: \"boolean\", description: \"Summary + findings only (no plan tree)\" },\n redact: { type: \"boolean\", description: \"Strip literal values from expressions (safe to share)\" },\n ascii: { type: \"boolean\", description: \"Use ASCII tree glyphs instead of Unicode\" },\n color: { type: \"string\", default: \"auto\", description: \"auto | always | never\" },\n \"no-color\": { type: \"boolean\", description: \"Disable color (same as --color never)\" },\n \"fail-on\": {\n type: \"string\",\n description: \"CI gate: exit 1 if a finding at/above info|warn|error exists\",\n },\n strict: { type: \"boolean\", description: \"Shorthand for --fail-on warn\" },\n config: {\n type: \"string\",\n description: \"Path to a config file (default: .pgexplainrc[.json] / package.json#pgExplain)\",\n },\n compact: { type: \"boolean\", description: \"Compact JSON output\" },\n quiet: { type: \"boolean\", alias: \"q\", description: \"Suppress non-error logs\" },\n verbose: { type: \"boolean\", description: \"Extra diagnostic logging\" },\n debug: { type: \"boolean\", description: \"Print stack traces on internal errors\" },\n} as const;\n\nfunction applyGlobalFlags(args: Args): void {\n setLogLevel(args.quiet ? \"quiet\" : args.debug ? \"debug\" : args.verbose ? \"verbose\" : \"normal\");\n const mode = args[\"no-color\"] ? \"never\" : (args.color as string);\n configureColor(mode === \"always\" || mode === \"never\" ? mode : \"auto\");\n}\n\nfunction emitOptionsFrom(args: Args): EmitOptions {\n const opts: EmitOptions = {\n format: resolveFormat(args.format),\n color: (args[\"no-color\"] ? \"never\" : args.color) as \"auto\" | \"always\" | \"never\",\n ascii: args.ascii,\n tldr: args.tldr,\n pretty: !args.compact,\n };\n if (args.output) opts.output = args.output;\n const failOn = resolveFailOn(args);\n if (failOn) opts.failOn = failOn;\n return opts;\n}\n\nfunction resolveFormat(value: string): Format {\n if (isFormat(value)) return value;\n throw usageError(\n `Unknown --format '${value}'`,\n \"Pick one of: terminal, markdown, json, html, text.\",\n );\n}\n\nfunction resolveFailOn(args: Args): Severity | undefined {\n if (args.strict) return \"warn\";\n const value = args[\"fail-on\"] as string | undefined;\n if (value === undefined) return undefined;\n if ((SEVERITIES as string[]).includes(value)) return value as Severity;\n throw usageError(`Unknown --fail-on '${value}'`, \"Use one of: info, warn, error.\");\n}\n\nfunction resolveStatement(args: Args): number | undefined {\n const raw = (args.statement ?? args.stmt) as string | undefined;\n if (raw === undefined) return undefined;\n const n = Number(raw);\n if (!Number.isInteger(n) || n < 1)\n throw usageError(`Invalid --statement '${raw}'`, \"Use a 1-based integer.\");\n return n;\n}\n\nfunction usageError(title: string, fix: string): AppError {\n const diagnostic: Diagnostic = {\n code: \"PGX_USAGE\",\n domain: \"operational\",\n severity: \"error\",\n title,\n detail: \"The command could not be run as given.\",\n cause: \"Invalid command-line usage.\",\n remediation: {\n summary: fix,\n commands: [{ label: \"See all options\", shell: \"pg-explain --help\" }],\n },\n };\n return new AppError(diagnostic, ExitCode.Usage);\n}\n\nfunction handleFatal(err: unknown): ExitCode {\n if (err instanceof AppError) {\n logError(formatDiagnostic(err.diagnostic));\n return err.exitCode;\n }\n logError(formatDiagnostic(opDiagnostic(\"PGX_INTERNAL\")));\n if (isDebug() && err instanceof Error && err.stack) logError(scrubCredentials(err.stack));\n return ExitCode.Internal;\n}\n\n// ── run subcommand ────────────────────────────────────────────────────────────\n\nconst runCmd = defineCommand({\n meta: {\n name: \"run\",\n description: \"Connect to PostgreSQL, run EXPLAIN safely, and analyze the result.\",\n },\n args: {\n dsn: {\n type: \"string\",\n description: \"Connection string (or use --host/--port/… or PG* env vars)\",\n },\n host: { type: \"string\", description: \"Server host\" },\n port: { type: \"string\", description: \"Server port\" },\n dbname: { type: \"string\", alias: \"d\", description: \"Database name\" },\n user: { type: \"string\", alias: \"U\", description: \"Role name\" },\n sslmode: { type: \"string\", description: \"disable | require | verify-ca | verify-full\" },\n sslrootcert: { type: \"string\", description: \"Path to a CA certificate (PEM)\" },\n \"connect-timeout\": {\n type: \"string\",\n default: \"10s\",\n description: \"Connection timeout (e.g. 30s)\",\n },\n query: { type: \"string\", description: \"SQL to explain\" },\n file: { type: \"string\", description: \"Path to a .sql file to explain\" },\n statement: { type: \"string\", description: \"1-based statement index when the file has several\" },\n param: { type: \"string\", description: \"Value for $1, $2, … (repeatable)\" },\n \"statement-timeout\": {\n type: \"string\",\n default: \"30s\",\n description: \"statement_timeout for the run\",\n },\n \"lock-timeout\": { type: \"string\", default: \"5s\", description: \"lock_timeout for the run\" },\n force: {\n type: \"boolean\",\n description: \"Allow a non-SELECT to execute (still auto-rolled-back)\",\n },\n \"no-rollback\": {\n type: \"boolean\",\n description: \"Do not wrap the run in a rolled-back transaction (dangerous)\",\n },\n \"no-analyze\": { type: \"boolean\", description: \"Do not execute the query; plan estimates only\" },\n \"no-buffers\": { type: \"boolean\", description: \"Omit BUFFERS\" },\n \"explain-verbose\": {\n type: \"boolean\",\n description: \"Add EXPLAIN VERBOSE (output columns, schemas)\",\n },\n settings: { type: \"boolean\", description: \"Add EXPLAIN SETTINGS (PG12+)\" },\n wal: { type: \"boolean\", description: \"Add EXPLAIN WAL (PG13+, needs ANALYZE)\" },\n \"generic-plan\": {\n type: \"boolean\",\n description: \"EXPLAIN GENERIC_PLAN (PG16+, does not execute)\",\n },\n \"no-timing\": { type: \"boolean\", description: \"Add TIMING OFF (reduces ANALYZE overhead)\" },\n \"no-costs\": { type: \"boolean\", description: \"Add COSTS OFF\" },\n compat: { type: \"boolean\", description: \"Auto-omit EXPLAIN options the server is too old for\" },\n ...outputArgs,\n },\n async run({ args }) {\n try {\n applyGlobalFlags(args);\n const connection: ConnectionOptions = {\n connectTimeoutMs: parseDurationMs(args[\"connect-timeout\"]),\n };\n if (args.dsn) connection.dsn = args.dsn;\n if (args.host) connection.host = args.host;\n if (args.port) connection.port = Number(args.port);\n if (args.dbname) connection.database = args.dbname;\n if (args.user) connection.user = args.user;\n if (args.sslmode) connection.sslmode = args.sslmode;\n if (args.sslrootcert) connection.sslrootcert = args.sslrootcert;\n\n const flags: ExplainFlags = {\n analyze: !args[\"no-analyze\"],\n buffers: !args[\"no-buffers\"],\n verbose: !!args[\"explain-verbose\"],\n settings: !!args.settings,\n wal: !!args.wal,\n timing: !args[\"no-timing\"],\n costs: !args[\"no-costs\"],\n summary: true,\n genericPlan: !!args[\"generic-plan\"],\n compat: !!args.compat,\n };\n\n const params = Array.isArray(args.param) ? args.param : args.param ? [args.param] : undefined;\n\n process.exitCode = await runRun({\n ...emitOptionsFrom(args),\n config: await loadConfig(args.config),\n connection,\n query: args.query,\n file: args.file,\n statementIndex: resolveStatement(args),\n params,\n flags,\n statementTimeoutMs: parseDurationMs(args[\"statement-timeout\"]),\n lockTimeoutMs: parseDurationMs(args[\"lock-timeout\"]),\n forceWrite: !!args.force,\n rollback: !args[\"no-rollback\"],\n redact: args.redact,\n });\n } catch (err) {\n process.exitCode = handleFatal(err);\n }\n },\n});\n\n// ── diff subcommand ───────────────────────────────────────────────────────────\n\nconst diffCmd = defineCommand({\n meta: {\n name: \"diff\",\n description: \"Compare two EXPLAIN plans (before → after) and report regressions.\",\n },\n args: {\n before: { type: \"positional\", required: true, description: \"Baseline plan JSON file\" },\n after: { type: \"positional\", required: true, description: \"New plan JSON file\" },\n format: {\n type: \"string\",\n default: \"terminal\",\n alias: \"f\",\n description: \"terminal | markdown | json\",\n },\n output: { type: \"string\", alias: \"o\", description: \"Write to a file instead of stdout\" },\n color: { type: \"string\", default: \"auto\", description: \"auto | always | never\" },\n \"no-color\": { type: \"boolean\", description: \"Disable color\" },\n redact: { type: \"boolean\", description: \"Strip literal values before comparing\" },\n config: { type: \"string\", description: \"Path to a config file\" },\n \"fail-on-slower\": {\n type: \"string\",\n description: \"Exit 1 if execution time regresses by ≥ this percent\",\n },\n \"fail-on-new-findings\": { type: \"boolean\", description: \"Exit 1 if any new finding appears\" },\n quiet: { type: \"boolean\", alias: \"q\", description: \"Suppress non-error logs\" },\n debug: { type: \"boolean\", description: \"Print stack traces on internal errors\" },\n },\n async run({ args }) {\n try {\n applyGlobalFlags(args);\n const format = args.format as string;\n if (![\"terminal\", \"markdown\", \"json\"].includes(format)) {\n throw usageError(`Unknown diff --format '${format}'`, \"Use terminal, markdown, or json.\");\n }\n const diffArgs: import(\"./commands/diff.ts\").DiffArgs = {\n before: args.before,\n after: args.after,\n format: format as \"terminal\" | \"markdown\" | \"json\",\n color: (args[\"no-color\"] ? \"never\" : args.color) as \"auto\" | \"always\" | \"never\",\n redact: args.redact,\n config: await loadConfig(args.config),\n failOnNewFindings: !!args[\"fail-on-new-findings\"],\n };\n if (args.output) diffArgs.output = args.output;\n if (args[\"fail-on-slower\"] !== undefined) {\n const pct = Number(args[\"fail-on-slower\"]);\n if (!Number.isFinite(pct))\n throw usageError(\n `Invalid --fail-on-slower '${args[\"fail-on-slower\"]}'`,\n \"Use a number, e.g. 20.\",\n );\n diffArgs.failOnSlowerPct = pct;\n }\n process.exitCode = await runDiff(diffArgs);\n } catch (err) {\n process.exitCode = handleFatal(err);\n }\n },\n});\n\n// ── main (analyze) command ────────────────────────────────────────────────────\n\nconst main = defineCommand({\n meta: {\n name: \"pg-explain\",\n version: pkg.version,\n description:\n \"Analyze a PostgreSQL EXPLAIN plan and report fixable findings. Pipe a plan or pass a file; use `pg-explain run --help` to execute a query and explain it.\",\n },\n args: {\n file: {\n type: \"positional\",\n required: false,\n description: \"Plan JSON file (default: read stdin)\",\n },\n statement: {\n type: \"string\",\n description: \"1-based statement index when the input holds several\",\n },\n ...outputArgs,\n },\n async run({ args }) {\n try {\n applyGlobalFlags(args);\n process.exitCode = await runAnalyze({\n ...emitOptionsFrom(args),\n config: await loadConfig(args.config),\n file: args.file,\n statement: resolveStatement(args),\n redact: args.redact,\n });\n } catch (err) {\n process.exitCode = handleFatal(err);\n }\n },\n});\n\nprocess.on(\"SIGINT\", () => process.exit(ExitCode.Sigint));\nprocess.on(\"SIGTERM\", () => process.exit(ExitCode.Sigint));\n\n// Manual dispatch: citty's subCommands treat any first positional as a subcommand\n// name (throwing on unknown), which conflicts with our positional plan-file argument.\n// Routing by argv[0] keeps `pg-explain plan.json` and `pg-explain run …` both working.\nconst argv = process.argv.slice(2);\n\nif (argv[0] === \"completion\") {\n process.exitCode = runCompletion(argv[1]);\n} else {\n const started =\n argv[0] === \"run\"\n ? runMain(runCmd, { rawArgs: argv.slice(1) })\n : argv[0] === \"diff\"\n ? runMain(diffCmd, { rawArgs: argv.slice(1) })\n : runMain(main, { rawArgs: argv });\n\n started.catch((err) => {\n process.exitCode = handleFatal(err);\n });\n}\n"]}
|