Skip to main content
Glama

get-execution-plan

Analyze SQL query execution plans to understand how Firebird databases will process queries, helping optimize performance and identify bottlenecks.

Instructions

Gets the execution plan for a SQL query to understand how the database will execute it

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sqlYesSQL query to analyze
paramsNoParameters for parameterized queries

Implementation Reference

  • Zod input schema for the get-execution-plan tool defining sql and optional params
    export const GetExecutionPlanArgsSchema = z.object({ sql: z.string().min(1).describe("SQL query to analyze"), params: z.array(z.string().or(z.number()).or(z.boolean()).or(z.null())).optional().describe("Parameters for parameterized queries") });
  • Registration of the get-execution-plan tool in setupDatabaseTools, including inline handler that delegates to getExecutionPlan
    tools.set("get-execution-plan", { name: "get-execution-plan", description: "Gets the execution plan for a SQL query to understand how the database will execute it", inputSchema: GetExecutionPlanArgsSchema, handler: async (request) => { const { sql, params } = request; logger.info(`Executing get-execution-plan tool for query: ${sql.substring(0, 50)}...`); try { const result = await getExecutionPlan(sql, params || []); return { content: [{ type: "text", text: formatForClaude(result) }] }; } catch (error) { const errorResponse = wrapError(error); logger.error(`Error getting execution plan: ${errorResponse.error} [${errorResponse.errorType || 'UNKNOWN'}]`); return { content: [{ type: "text", text: stringifyCompact(errorResponse) }] }; } } });
  • Core getExecutionPlan function implementation that handles validation and returns detailed explanation why execution plans are not retrievable via Node.js drivers, with tool recommendations
    export const getExecutionPlan = async ( sql: string, params: any[] = [], config = getGlobalConfig() || DEFAULT_CONFIG ): Promise<ExecutionPlanResult> => { try { // Validate the SQL query to prevent injection if (!validateSql(sql)) { throw new FirebirdError( `Invalid SQL query: ${sql}`, 'VALIDATION_ERROR' ); } logger.info(`Getting execution plan for query: ${sql.substring(0, 100)}${sql.length > 100 ? '...' : ''}`); // Only SELECT queries are supported for execution plan analysis if (!sql.trim().toUpperCase().startsWith('SELECT')) { throw new FirebirdError( `Only SELECT queries are supported for execution plan analysis`, 'UNSUPPORTED_OPERATION' ); } // Check if we're using the native driver by checking DriverFactory const { DriverFactory } = await import('./driver-factory.js'); const driverInfo = await DriverFactory.getDriverInfo(); logger.debug('Driver info for execution plan', { driverType: driverInfo.current, nativeAvailable: driverInfo.nativeAvailable }); // Note: node-firebird-driver-native and node-firebird do not expose a direct method to get execution plans // The Firebird API has isc_dsql_sql_info with isc_info_sql_get_plan (constant value: 22), but this is not // exposed in the high-level driver interfaces. The low-level node-firebird-native-api would be needed, // but it's complex to use directly and would require significant refactoring. // // Research findings: // - FDB (Python driver) uses: isc_dsql_sql_info(statement_handle, [isc_info_sql_get_plan]) // - node-firebird-driver-native Statement object does not have getPlan() or getInfo() methods // - node-firebird (pure JS) does not support SET PLANONLY or SET PLAN commands (isql-specific) // // Recommendation: Use Firebird tools for execution plan analysis: // - isql: SET PLANONLY ON; <query>; SET PLANONLY OFF; // - FlameRobin: GUI tool with built-in plan visualization // - IBExpert: Commercial tool with advanced plan analysis logger.info('Execution plan retrieval is not available through Node.js Firebird drivers'); logger.info('The drivers do not expose the isc_dsql_sql_info API needed to get execution plans'); logger.info('Recommendation: Use Firebird tools like isql, FlameRobin, or IBExpert for execution plans'); // Return informative message return { query: sql, plan: "Execution plan not available", planDetails: [], success: true, analysis: "Node.js Firebird drivers do not expose the execution plan API.\n\n" + "The Firebird API provides isc_dsql_sql_info with isc_info_sql_get_plan (constant: 22) " + "to retrieve execution plans, but neither node-firebird-driver-native nor node-firebird " + "expose this functionality in their high-level interfaces.\n\n" + "To view execution plans, please use one of these Firebird tools:\n\n" + "1. isql (Firebird command-line tool):\n" + " SET PLANONLY ON;\n" + " <your query>;\n" + " SET PLANONLY OFF;\n\n" + "2. FlameRobin (Free GUI tool):\n" + " - Open SQL Editor\n" + " - Enter your query\n" + " - Click 'Show Plan' button\n\n" + "3. IBExpert (Commercial GUI tool):\n" + " - SQL Editor with built-in plan visualization\n" + " - Advanced plan analysis features\n\n" + "Alternatively, you can use the 'analyze-query-performance' tool to measure " + "query execution time and identify performance issues." }; } catch (error: any) { const errorMessage = `Error getting execution plan: ${error.message || error}`; logger.error(errorMessage); return { query: sql, plan: "", planDetails: [], success: false, error: errorMessage, analysis: "Failed to get execution plan." }; } };
  • TypeScript interface defining the structure of execution plan results
    export interface ExecutionPlanResult { query: string; plan: string; planDetails: any[]; success: boolean; error?: string; analysis: string; }
  • Helper function to analyze execution plans (currently unused as plans can't be retrieved)
    function analyzePlan(plan: string): string { const analysis: string[] = []; const upperPlan = plan.toUpperCase(); // Check for NATURAL scans (table scans without index) if (upperPlan.includes('NATURAL')) { analysis.push('⚠️ NATURAL scan detected - table is being scanned without using an index. Consider adding an index for better performance.'); } // Check for INDEX usage const indexMatches = plan.match(/INDEX\s+\(([^)]+)\)/gi); if (indexMatches && indexMatches.length > 0) { analysis.push(`✅ Using ${indexMatches.length} index(es): ${indexMatches.join(', ')}`); } // Check for JOIN operations if (upperPlan.includes('JOIN')) { analysis.push('🔗 Query contains JOIN operations'); } // Check for SORT operations if (upperPlan.includes('SORT')) { analysis.push('📊 SORT operation detected - may impact performance on large datasets'); } // Check for FILTER operations if (upperPlan.includes('FILTER')) { analysis.push('🔍 FILTER operation detected - rows are being filtered after retrieval'); } if (analysis.length === 0) { return 'Plan retrieved successfully. The query appears to be optimized.'; } return analysis.join('\n'); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PuroDelphi/mcpFirebird'

If you have feedback or need assistance with the MCP directory API, please join our Discord server