/**
* PostgreSQL Performance Tools - EXPLAIN Operations
*/
import type { PostgresAdapter } from '../../PostgresAdapter.js';
import type { ToolDefinition, RequestContext } from '../../../../types/index.js';
import { readOnly } from '../../../../utils/annotations.js';
import { getToolIcons } from '../../../../utils/icons.js';
import { ExplainSchema } from '../../schemas/index.js';
export function createExplainTool(adapter: PostgresAdapter): ToolDefinition {
return {
name: 'pg_explain',
description: 'Show query execution plan without running the query.',
group: 'performance',
inputSchema: ExplainSchema,
annotations: readOnly('Explain Query'),
icons: getToolIcons('performance', readOnly('Explain Query')),
handler: async (params: unknown, _context: RequestContext) => {
const { sql, format, params: queryParams } = ExplainSchema.parse(params);
const fmt = format ?? 'text';
const explainSql = `EXPLAIN (FORMAT ${fmt.toUpperCase()}) ${sql}`;
const result = await adapter.executeQuery(explainSql, queryParams ?? []);
if (fmt === 'json') {
return { plan: result.rows?.[0]?.['QUERY PLAN'] };
}
return { plan: result.rows?.map(r => Object.values(r)[0]).join('\n') };
}
};
}
export function createExplainAnalyzeTool(adapter: PostgresAdapter): ToolDefinition {
return {
name: 'pg_explain_analyze',
description: 'Run query and show actual execution plan with timing.',
group: 'performance',
inputSchema: ExplainSchema,
annotations: readOnly('Explain Analyze'),
icons: getToolIcons('performance', readOnly('Explain Analyze')),
handler: async (params: unknown, _context: RequestContext) => {
const { sql, format, params: queryParams } = ExplainSchema.parse(params);
const fmt = format ?? 'text';
const explainSql = `EXPLAIN (ANALYZE, FORMAT ${fmt.toUpperCase()}) ${sql}`;
const result = await adapter.executeQuery(explainSql, queryParams ?? []);
if (fmt === 'json') {
return { plan: result.rows?.[0]?.['QUERY PLAN'] };
}
return { plan: result.rows?.map(r => Object.values(r)[0]).join('\n') };
}
};
}
export function createExplainBuffersTool(adapter: PostgresAdapter): ToolDefinition {
return {
name: 'pg_explain_buffers',
description: 'Show query plan with buffer usage statistics.',
group: 'performance',
inputSchema: ExplainSchema,
annotations: readOnly('Explain Buffers'),
icons: getToolIcons('performance', readOnly('Explain Buffers')),
handler: async (params: unknown, _context: RequestContext) => {
const { sql, format, params: queryParams } = ExplainSchema.parse(params);
const fmt = format ?? 'json';
const explainSql = `EXPLAIN (ANALYZE, BUFFERS, FORMAT ${fmt.toUpperCase()}) ${sql}`;
const result = await adapter.executeQuery(explainSql, queryParams ?? []);
if (fmt === 'json') {
return { plan: result.rows?.[0]?.['QUERY PLAN'] };
}
return { plan: result.rows?.map(r => Object.values(r)[0]).join('\n') };
}
};
}