Skip to content

Idempotency Analysis & Migration Safety Validation

Overview

Implement advanced validation tools that analyze SQL migrations for idempotency issues and safety concerns. This is a critical capability that helps Claude agents ensure migrations are safe and can be run multiple times without side effects.

Claude Agent Success Criteria

A Claude agent should be able to:

  • Test any migration for idempotency by running it multiple times
  • Analyze SQL code and detect non-idempotent patterns
  • Suggest specific fixes for common idempotency issues
  • Validate all migrations in a project for safety

Detailed Acceptance Criteria

1. Idempotency Testing Tool

Implement test_migration_idempotency MCP tool:

{
  name: "test_migration_idempotency",
  description: "Test migration idempotency by running it multiple times",
  inputSchema: {
    type: "object",
    properties: {
      projectPath: {
        type: "string",
        description: "Path to the Graphile Migrate project"
      },
      migrationFile: {
        type: "string",
        description: "Specific migration to test (defaults to current.sql)"
      },
      iterations: {
        type: "number",
        description: "Number of times to run migration (default: 3)",
        minimum: 2,
        maximum: 10
      }
    },
    required: ["projectPath"]
  }
}

Return Structure:

interface IdempotencyTestResult {
  success: boolean;
  data: {
    migration: {
      file: string;
      content: string;
      size: number;
    };
    test: {
      iterations: number;
      passed: boolean;
      duration: number;
      details: IterationResult[];
    };
    issues: IdempotencyIssue[];
    recommendations: string[];
  };
}

interface IterationResult {
  iteration: number;
  success: boolean;
  duration: number;
  changes?: string[];
  errors?: string[];
}
  • Create isolated test database for each run
  • Execute migration multiple times sequentially
  • Compare database state after each iteration
  • Detect changes between iterations
  • Report specific failure points

2. Static SQL Analysis Tool

Implement analyze_migration_safety MCP tool:

{
  name: "analyze_migration_safety",
  description: "Analyze migration SQL for safety and idempotency issues",
  inputSchema: {
    type: "object",
    properties: {
      projectPath: {
        type: "string",
        description: "Path to the Graphile Migrate project"
      },
      migrationFile: {
        type: "string", 
        description: "Migration file to analyze (defaults to current.sql)"
      },
      includeRecommendations: {
        type: "boolean",
        description: "Include fix recommendations (default: true)"
      }
    },
    required: ["projectPath"]
  }
}

Analysis Categories:

interface SafetyAnalysis {
  idempotency: {
    score: number; // 0-100
    issues: IdempotencyIssue[];
    patterns: SafetyPattern[];
  };
  performance: {
    potentialImpact: 'low' | 'medium' | 'high';
    concerns: PerformanceConcern[];
  };
  safety: {
    destructive: boolean;
    risks: SafetyRisk[];
  };
  bestPractices: {
    score: number;
    recommendations: string[];
  };
}
  • Parse SQL using regex-based analysis
  • Detect non-idempotent patterns
  • Identify performance risks
  • Check for destructive operations
  • Validate best practices adherence

3. Idempotency Issue Detection

Implement comprehensive pattern detection:

Anti-Patterns to Detect:

const ANTI_PATTERNS = [
  {
    pattern: /CREATE TABLE (?!.*IF NOT EXISTS)/gi,
    issue: 'non_idempotent_table_creation',
    message: 'CREATE TABLE without IF NOT EXISTS',
    fix: 'Add IF NOT EXISTS clause'
  },
  {
    pattern: /CREATE INDEX (?!.*IF NOT EXISTS)/gi,
    issue: 'non_idempotent_index_creation', 
    message: 'CREATE INDEX without IF NOT EXISTS',
    fix: 'Add IF NOT EXISTS clause'
  },
  {
    pattern: /ALTER TABLE.*ADD COLUMN (?!.*IF NOT EXISTS)/gi,
    issue: 'non_idempotent_column_addition',
    message: 'ADD COLUMN without IF NOT EXISTS',
    fix: 'Add IF NOT EXISTS clause'
  },
  {
    pattern: /DROP TABLE (?!.*IF EXISTS)/gi,
    issue: 'non_idempotent_table_drop',
    message: 'DROP TABLE without IF EXISTS',
    fix: 'Add IF EXISTS clause'
  }
];

Safe Patterns to Recognize:

  • CREATE OR REPLACE FUNCTION

  • DO $$ BEGIN ... EXCEPTION WHEN duplicate_object ... blocks

  • IF NOT EXISTS and IF EXISTS clauses

  • Conditional constraint additions

  • Implement regex-based pattern detection

  • Support comprehensive SQL pattern analysis

  • Recognize safe idempotent patterns

  • Provide context-aware suggestions

4. Fix Suggestion Engine

Implement suggest_idempotency_fixes MCP tool:

{
  name: "suggest_idempotency_fixes",
  description: "Analyze SQL and suggest specific idempotency improvements",
  inputSchema: {
    type: "object",
    properties: {
      projectPath: {
        type: "string",
        description: "Path to the Graphile Migrate project"
      },
      migrationContent: {
        type: "string",
        description: "SQL content to analyze and fix"
      },
      analysisType: {
        type: "string",
        enum: ["basic", "comprehensive"],
        description: "Level of analysis to perform"
      }
    },
    required: ["projectPath", "migrationContent"]
  }
}

Fix Suggestions:

interface FixSuggestion {
  issue: string;
  line: number;
  column?: number;
  originalCode: string;
  suggestedCode: string;
  explanation: string;
  confidence: 'high' | 'medium' | 'low';
}

interface FixResult {
  originalSql: string;
  fixedSql: string;
  suggestions: FixSuggestion[];
  warnings: string[];
}

Example Transformations:

-- BEFORE (non-idempotent)
CREATE TABLE users (id SERIAL PRIMARY KEY);

-- AFTER (idempotent)
CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY);

-- BEFORE (complex case)
CREATE TYPE user_role AS ENUM ('admin', 'user');

-- AFTER (idempotent with error handling)  
DO $$ BEGIN
    CREATE TYPE user_role AS ENUM ('admin', 'user');
EXCEPTION
    WHEN duplicate_object THEN null;
END $$;
  • Generate specific line-by-line suggestions
  • Provide confidence scores for suggestions
  • Handle complex SQL constructs
  • Preserve original formatting and comments

5. Comprehensive Project Validation

Implement validate_all_migrations MCP tool:

{
  name: "validate_all_migrations",
  description: "Validate all migrations in project for safety and idempotency",
  inputSchema: {
    type: "object",
    properties: {
      projectPath: {
        type: "string",
        description: "Path to the Graphile Migrate project"
      },
      includeIdempotencyTest: {
        type: "boolean",
        description: "Run actual idempotency tests (default: false - static analysis only)"
      },
      includeSafetyAnalysis: {
        type: "boolean", 
        description: "Include safety analysis (default: true)"
      },
      parallelExecution: {
        type: "boolean",
        description: "Run validations in parallel (default: true)"
      }
    },
    required: ["projectPath"]
  }
}
  • Analyze all committed migrations
  • Include current.sql if present
  • Generate comprehensive validation report
  • Support parallel validation for performance
  • Provide project-wide recommendations

Testing Requirements

Unit Tests

  • Test SQL pattern recognition and parsing
  • Test fix suggestion generation
  • Test idempotency analysis algorithms
  • Test edge cases and complex SQL constructs

Integration Tests

  • Test with real PostgreSQL databases
  • Test idempotency with actual migration runs
  • Test with various SQL constructs and patterns
  • Test performance with large migrations

Test Fixtures

Create comprehensive test SQL files:

  • Idempotent migration examples
  • Non-idempotent migration examples
  • Complex SQL with functions, types, triggers
  • Edge cases and corner cases
  • Performance-impacting migrations

Claude Agent Guidance

Typical Usage Workflow

// 1. Analyze current migration
const analysis = await tools.analyze_migration_safety({
  projectPath: "/path/to/project"
});

// 2. Get specific fix suggestions  
const fixes = await tools.suggest_idempotency_fixes({
  projectPath: "/path/to/project",
  migrationContent: currentMigrationContent
});

// 3. Test actual idempotency
const test = await tools.test_migration_idempotency({
  projectPath: "/path/to/project",
  iterations: 3
});

// 4. Validate entire project
const validation = await tools.validate_all_migrations({
  projectPath: "/path/to/project",
  includeIdempotencyTest: true
});

How to Verify Success

# Test static analysis
node -e "
const analysis = require('./dist/tools/analyze-migration-safety');
console.log(analysis.analyzeSQL('CREATE TABLE test();'));
"

# Test fix suggestions  
node -e "
const fixes = require('./dist/tools/suggest-fixes');
console.log(fixes.suggestFixes('CREATE INDEX test_idx ON test(id);'));
"

Expected Behavior

  • Static analysis should catch common anti-patterns
  • Fix suggestions should be actionable and safe
  • Idempotency testing should detect actual issues
  • Validation reports should be comprehensive and clear

Error Handling Examples

  • Database Connection Failed: "Cannot test idempotency: database connection failed. Check connection string."
  • Invalid SQL: "SQL syntax error at line 15: unexpected token 'CREAT'"
  • Test Database Error: "Failed to create test database. Ensure user has CREATE permissions."

Definition of Done

  • All validation tools implemented with comprehensive pattern detection
  • Idempotency testing works with real databases
  • Fix suggestion engine provides actionable recommendations
  • Static analysis covers all major anti-patterns
  • Integration tests validate real-world scenarios
  • >80% test coverage maintained
  • Performance optimized for large migrations
  • CLAUDE.md updated with validation examples

Estimated Effort

3-4 days

Dependencies

Technical Notes for Claude Agents

Key Files to Create

  • src/tools/test-idempotency.ts - Idempotency testing tool
  • src/tools/analyze-safety.ts - Static analysis tool
  • src/tools/suggest-fixes.ts - Fix suggestion engine
  • src/tools/validate-all.ts - Comprehensive validation
  • src/analysis/patterns.ts - Pattern detection rules
  • src/analysis/parser.ts - SQL parsing utilities

SQL Analysis Approach

  • Use regex patterns for simple detection
  • Implement SQL AST parsing for complex analysis
  • Support PostgreSQL-specific syntax
  • Handle comments and string literals correctly
  • Preserve original formatting in suggestions

Database Testing Strategy

  • Use temporary test databases
  • Implement proper cleanup procedures
  • Support multiple PostgreSQL versions
  • Handle connection pooling and timeouts
  • Provide detailed failure diagnostics
Edited by John Haley