From 77baa1f20ae585a730d06fe49944da2565bebb3f Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov <7889985+andreybavt@users.noreply.github.com> Date: Mon, 11 May 2026 19:27:57 +0200 Subject: [PATCH] fix: make pgss max advisory informational --- packages/cli/src/doctor.test.ts | 10 ++--- packages/cli/src/historic-sql-doctor.test.ts | 39 +++++++++++++++++++- packages/cli/src/historic-sql-doctor.ts | 14 +++++-- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/packages/cli/src/doctor.test.ts b/packages/cli/src/doctor.test.ts index b40af1bd..d0ebdb95 100644 --- a/packages/cli/src/doctor.test.ts +++ b/packages/cli/src/doctor.test.ts @@ -292,10 +292,9 @@ describe('runKtxDoctor', () => { { id: 'historic-sql-postgres-warehouse', label: 'Postgres Historic SQL (warehouse)', - status: 'warn' as const, + status: 'pass' as const, detail: - 'pg_stat_statements ready (PostgreSQL 16.4) with warnings: pg_stat_statements.max is 1000; set it to at least 5000 to reduce query-template eviction churn', - fix: `Update the Postgres parameter group or config, then rerun \`ktx dev doctor --project-dir ${tempDir}\``, + 'pg_stat_statements ready (PostgreSQL 16.4); info: pg_stat_statements.max is 1000; set it to at least 5000 to reduce query-template eviction churn', }, ]); @@ -313,8 +312,9 @@ describe('runKtxDoctor', () => { ).resolves.toBe(0); expect(runHistoricSqlDoctorChecks).toHaveBeenCalledTimes(1); - expect(testIo.stdout()).toContain('WARN Postgres Historic SQL (warehouse): pg_stat_statements ready'); - expect(testIo.stdout()).toContain('Fix: Update the Postgres parameter group or config'); + expect(testIo.stdout()).toContain('PASS Postgres Historic SQL (warehouse): pg_stat_statements ready'); + expect(testIo.stdout()).toContain('info: pg_stat_statements.max is 1000'); + expect(testIo.stdout()).not.toContain('Fix: Update the Postgres parameter group or config'); }); it('warns when semantic-search embeddings are not configured', async () => { diff --git a/packages/cli/src/historic-sql-doctor.test.ts b/packages/cli/src/historic-sql-doctor.test.ts index f4e0ee7f..1c08b6e3 100644 --- a/packages/cli/src/historic-sql-doctor.test.ts +++ b/packages/cli/src/historic-sql-doctor.test.ts @@ -81,7 +81,39 @@ describe('runPostgresHistoricSqlDoctorChecks', () => { ]); }); - it('warns when the PGSS probe succeeds with operational warnings', async () => { + it('passes with an informational note when only pg_stat_statements.max is below the recommended floor', async () => { + const checks = await runPostgresHistoricSqlDoctorChecks( + projectWithConnections({ + warehouse: { + driver: 'postgres', + url: 'env:WAREHOUSE_DATABASE_URL', + readonly: true, + historicSql: { enabled: true, dialect: 'postgres' }, + }, + }), + { + postgresHistoricSqlProbe: async () => ({ + pgServerVersion: 'PostgreSQL 16.4', + warnings: [], + info: [ + 'pg_stat_statements.max is 1000; set it to at least 5000 to reduce query-template eviction churn', + ], + }), + }, + ); + + expect(checks).toEqual([ + { + id: 'historic-sql-postgres-warehouse', + label: 'Postgres Historic SQL (warehouse)', + status: 'pass', + detail: + 'pg_stat_statements ready (PostgreSQL 16.4); info: pg_stat_statements.max is 1000; set it to at least 5000 to reduce query-template eviction churn', + }, + ]); + }); + + it('warns when pg_stat_statements tracking is disabled', async () => { const checks = await runPostgresHistoricSqlDoctorChecks( projectWithConnections({ warehouse: { @@ -95,6 +127,9 @@ describe('runPostgresHistoricSqlDoctorChecks', () => { postgresHistoricSqlProbe: async () => ({ pgServerVersion: 'PostgreSQL 16.4', warnings: [ + 'pg_stat_statements.track is none; set it to top or all in the Postgres parameter group or config', + ], + info: [ 'pg_stat_statements.max is 1000; set it to at least 5000 to reduce query-template eviction churn', ], }), @@ -107,7 +142,7 @@ describe('runPostgresHistoricSqlDoctorChecks', () => { label: 'Postgres Historic SQL (warehouse)', status: 'warn', detail: - 'pg_stat_statements ready (PostgreSQL 16.4) with warnings: pg_stat_statements.max is 1000; set it to at least 5000 to reduce query-template eviction churn', + 'pg_stat_statements ready (PostgreSQL 16.4) with warnings: pg_stat_statements.track is none; set it to top or all in the Postgres parameter group or config; info: pg_stat_statements.max is 1000; set it to at least 5000 to reduce query-template eviction churn', fix: 'Update the Postgres parameter group or config, then rerun `ktx dev doctor --project-dir /tmp/ktx-project`', }, ]); diff --git a/packages/cli/src/historic-sql-doctor.ts b/packages/cli/src/historic-sql-doctor.ts index dc8bd317..62db386b 100644 --- a/packages/cli/src/historic-sql-doctor.ts +++ b/packages/cli/src/historic-sql-doctor.ts @@ -16,6 +16,7 @@ export interface PostgresHistoricSqlDoctorProbeInput { export interface PostgresHistoricSqlDoctorProbeResult { pgServerVersion: string; warnings: string[]; + info?: string[]; } export type PostgresHistoricSqlDoctorProbe = ( @@ -72,6 +73,13 @@ function failureDetail(error: unknown): string { return String(error); } +function readinessDetail(result: PostgresHistoricSqlDoctorProbeResult): string { + const warningText = result.warnings.length > 0 ? ` with warnings: ${result.warnings.join('; ')}` : ''; + const info = result.info ?? []; + const infoText = info.length > 0 ? `; info: ${info.join('; ')}` : ''; + return `pg_stat_statements ready (${result.pgServerVersion})${warningText}${infoText}`; +} + async function defaultPostgresHistoricSqlProbe( input: PostgresHistoricSqlDoctorProbeInput, ): Promise { @@ -134,14 +142,12 @@ export async function runPostgresHistoricSqlDoctorChecks( 'warn', checkId(connectionId), label, - `pg_stat_statements ready (${result.pgServerVersion}) with warnings: ${result.warnings.join('; ')}`, + readinessDetail(result), `Update the Postgres parameter group or config, then rerun \`ktx dev doctor --project-dir ${project.projectDir}\``, ), ); } else { - checks.push( - check('pass', checkId(connectionId), label, `pg_stat_statements ready (${result.pgServerVersion})`), - ); + checks.push(check('pass', checkId(connectionId), label, readinessDetail(result))); } } catch (error) { checks.push(