analyze_sql
Analyze SQL queries for validation, parsing, metadata extraction, security vulnerabilities, linting issues, and formatting compliance in a single operation.
Instructions
Run all 6 analysis tools concurrently and return a composite report (validate, parse, metadata, security, lint, format).
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | The SQL string to analyze |
Implementation Reference
- Handler function 'analyzeCommand' executes the 'analyze' command by spawning a process with the GoSQLX binary, capturing its stdout as analysis output.
async function analyzeCommand(): Promise<void> { const timer = new PerformanceTimer(); timer.start(); const editor = vscode.window.activeTextEditor; if (!editor || !isSqlLanguageId(editor.document.languageId)) { vscode.window.showWarningMessage( 'No SQL file is open. Open a .sql file to analyze.', 'Open File' ).then(action => { if (action === 'Open File') { vscode.commands.executeCommand('workbench.action.files.openFile'); } }); return; } const text = editor.document.getText(); const config = vscode.workspace.getConfiguration('gosqlx'); const executablePath = await getBinaryPath(); const analysisTimeout = config.get<number>('timeouts.analysis', 30000); // Show progress indicator await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: 'Analyzing SQL...', cancellable: true }, async (progress, cancellationToken) => { try { const result = await new Promise<{ stdout: string; stderr: string }>((resolve, reject) => { const child = spawn(executablePath, ['analyze'], { stdio: ['pipe', 'pipe', 'pipe'] }); let stdout = ''; let stderr = ''; let outputSize = 0; const maxSize = 5 * 1024 * 1024; // 5MB limit // Set a timeout using configured value const timeout = setTimeout(() => { child.kill(); reject(new Error(`Analysis timed out after ${analysisTimeout / 1000} seconds. Try increasing gosqlx.timeouts.analysis in settings.`)); }, analysisTimeout); // Handle cancellation cancellationToken.onCancellationRequested(() => { child.kill(); clearTimeout(timeout); reject(new Error('Analysis cancelled by user')); }); if (child.stdout) { child.stdout.on('data', (data: Buffer) => { outputSize += data.length; if (outputSize < maxSize) { stdout += data.toString(); } }); } if (child.stderr) { child.stderr.on('data', (data: Buffer) => { stderr += data.toString(); }); } child.on('close', (code: number | null) => { clearTimeout(timeout); if (code === 0 || code === null) { resolve({ stdout, stderr }); } else { reject(new Error(`Process exited with code ${code}: ${stderr || 'Unknown error'}`)); } }); child.on('error', (err: Error) => { clearTimeout(timeout); reject(err); }); // Send SQL content via stdin if (child.stdin) { child.stdin.write(text); child.stdin.end(); } }); const duration = timer.stop(); metrics.record('command.analyze', duration, true, { outputSize: result.stdout.length }); telemetry.recordCommand('analyze', duration, true); if (result.stderr) { outputChannel.appendLine(`Analysis stderr: ${result.stderr}`); } // Show analysis results in a new document const doc = await vscode.workspace.openTextDocument({ content: result.stdout || 'No analysis output', language: 'markdown' }); await vscode.window.showTextDocument(doc, { preview: true }); outputChannel.appendLine(`Analyzed: ${editor.document.uri.fsPath} (${duration}ms)`); if (performanceStatusBarItem) { updatePerformanceStatusBar(performanceStatusBarItem, metrics); } } catch (error) { const duration = timer.stop(); const errorMessage = formatError(error); const errorCode = extractErrorCode(error); metrics.record('command.analyze', duration, false, { error: errorCode || 'unknown' }); telemetry.recordCommand('analyze', duration, false, errorCode); const detailedMessage = getAnalysisErrorMessage(errorMessage); outputChannel.appendLine(detailedMessage); vscode.window.showErrorMessage( `Analysis failed: ${errorMessage}`, 'Show Details' ).then(action => { if (action === 'Show Details') { outputChannel.show(); } }); } }); } - vscode-extension/src/extension.ts:111-119 (registration)Registration of the 'gosqlx.analyze' command in the VS Code extension activate method.
context.subscriptions.push( vscode.commands.registerCommand('gosqlx.validate', validateCommand), vscode.commands.registerCommand('gosqlx.format', formatCommand), vscode.commands.registerCommand('gosqlx.analyze', analyzeCommand), vscode.commands.registerCommand('gosqlx.restartServer', restartServerCommand), vscode.commands.registerCommand('gosqlx.showOutput', () => outputChannel.show()), vscode.commands.registerCommand('gosqlx.showMetrics', showMetricsCommand), vscode.commands.registerCommand('gosqlx.validateConfiguration', validateConfigurationCommand) );