Skip to main content
Glama

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
NameRequiredDescriptionDefault
sqlYesThe 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();
                    }
                });
            }
        });
    }
  • 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)
    );

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/ajitpratap0/GoSQLX'

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