Selecto.Performance.ComplexityAnalyzer (Selecto v0.3.12)

Analyzes query complexity to prevent database overload.

Provides pre-execution query analysis to block or warn about queries that may be too expensive to execute safely. Complexity is scored based on:

  • Number of JOINs (each JOIN: +10 points)
  • Subqueries and subselects (each: +15 points)
  • Cartesian products (detected cross joins: +100 points - blocks execution)
  • Large IN clauses (>100 items: +20 points)
  • LIKE patterns with leading wildcard (+5 points)
  • Missing WHERE clauses on non-aggregated queries (+30 points)
  • Post-pivot filters (additional complexity: +10 points)

usage

Usage

# Analyze before execution
case Selecto.Performance.ComplexityAnalyzer.analyze(selecto) do
  {:ok, analysis} ->
    # Safe to execute, but may have warnings
    Logger.warning(analysis.warnings)
    execute(selecto)

  {:error, :too_complex, analysis} ->
    # Query blocked due to high complexity
    {:error, "Query too complex: #{Enum.join(analysis.blocking_issues, ", ")}"}
end

configuration

Configuration

# Application config
config :selecto, :complexity_analyzer,
  max_complexity: 100,
  max_joins: 10,
  max_in_clause_size: 100,
  warn_on_full_table_scan: true

Link to this section Summary

Functions

Analyze query complexity before execution.

Get a human-readable summary of the complexity analysis.

Check if a query is safe to execute based on complexity. Returns true if safe, false if blocked.

Link to this section Types

Link to this type

analysis_result()

@type analysis_result() :: {:ok, t()} | {:error, :too_complex, t()}
@type t() :: %Selecto.Performance.ComplexityAnalyzer{
  blocking_issues: [String.t()],
  details: map(),
  recommendations: [String.t()],
  score: non_neg_integer(),
  warnings: [String.t()]
}

Link to this section Functions

Link to this function

analyze(selecto, opts \\ [])

@spec analyze(
  Selecto.t(),
  keyword()
) :: analysis_result()

Analyze query complexity before execution.

options

Options

  • :max_complexity - Maximum allowed complexity score (default: 100)
  • :max_joins - Maximum allowed joins (default: 10)
  • :max_in_clause_size - Maximum items in IN clause (default: 100)
  • :block_on_warnings - Treat warnings as blocking (default: false)

returns

Returns

  • {:ok, analysis} - Query is safe to execute (may have warnings)
  • {:error, :too_complex, analysis} - Query exceeds complexity limits
Link to this function

format_summary(analysis)

@spec format_summary(t()) :: String.t()

Get a human-readable summary of the complexity analysis.

Link to this function

safe_to_execute?(selecto, opts \\ [])

@spec safe_to_execute?(
  Selecto.t(),
  keyword()
) :: boolean()

Check if a query is safe to execute based on complexity. Returns true if safe, false if blocked.