[Go to site: main page, start]

Database RuboCop docs

Database/AvoidInheritanceColumn

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Checks for self.inheritance_column usage, which is discouraged https://docs.gitlab.com/ee/development/database/single_table_inheritance.html

Database/AvoidIntRangePartitioning

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Prevents new usages of the :int_range partitioning strategy.

int_range partition boundaries are derived from the ID sequence of the partitioning key, and sequence ranges are allocated per cell. A destination cell therefore cannot reproduce the partition topology of the source cell, which blocks moving an organization between cells.

Use a date-range strategy (:daily, :weekly, :monthly) instead, or reach out to @gitlab-org/database-team/triage if that does not fit the access pattern.

Examples

# bad
partitioned_by :project_id, strategy: :int_range, partition_size: 2_000_000

# bad
partition_table_by_int_range(
  'merge_request_diff_commits',
  'merge_request_diff_id',
  partition_size: 10_000_000,
  primary_key: %w[merge_request_diff_id relative_order]
)

# good
partitioned_by :created_at, strategy: :monthly, retain_for: 3.months

Database/AvoidScopeTo

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Disallows the use of scope_to to avoid problematic batched background migration queries.

Examples

# bad
class CustomBatchedMigrationClass < BatchedMigrationJob
  scope_to ->(relation) { relation.where( user_type: "ADMIN") }
end

# good
class CustomBatchedMigrationClass < BatchedMigrationJob
  def perform
    each_sub_batch do |relation|
      relation.where( user_type: "ADMIN").update_all("column = 'foo'")
    end
  end
end

Database/AvoidUnpartitionedCiRelations

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Prevents calling partitioned CI relation methods on Project without partition scoping.

Partitioned CI tables require .in_partition(partition_id) to avoid expensive cross-partition scans that can cause database lock contention.

Examples

# bad
project.all_pipelines
project.builds.where(status: :failed)
@project.job_artifacts.recent

# good
project.all_pipelines.in_partition(106)
project.builds.in_partition(106).where(status: :failed)
@project.job_artifacts.in_partition(106).recent

Database/AvoidUsingConnectionExecute

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Avoid using connection.execute for read-only queries.

Examples

# bad
class MyClass < ApplicationRecord
  def all
    connection.execute('SELECT * FROM my_table') # This goes to the primary db node
  end
end

# good
class MyClass < ApplicationRecord
  def all
    connection.select_all('SELECT * FROM my_table') # This goes to a read replica
  end
end

Database/AvoidUsingPluckWithoutLimit

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Checks the use of .pluck(:attribute) without setting a limit.

Examples

# bad
def all
  Project.where(user_id: User.pluck(:id))
end

# good
def all(limit)
  Project.where(user_id: User.limit(limit).pluck(:id))
end

Database/DisableReferentialIntegrity

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Cop that checks if ‘disable_referential_integrity’ method is called.

Database/EstablishConnection

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

No documentation

Database/JsonbSizeLimit

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Enforces size limits on new JSONB column validations

This cop ensures that new json_schema validations include explicit size limits to prevent unbounded JSONB growth that can impact database performance at scale.

Examples

# bad - no size limit specified
validates :metadata, json_schema: { filename: "project_metadata" }

# good - explicit size limit
validates :metadata, json_schema: { filename: "project_metadata", size_limit: 64.kilobytes }

Database/MultipleDatabases

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Examples

# bad
ActiveRecord::Base.connection

# good
ApplicationRecord.connection

Database/NoOnDemandCellLocalBackgroundOperation

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Prevents on-demand enqueuing of Gitlab::Database::BackgroundOperation::WorkerCellLocal.

Cell-local background operations are stored under the gitlab_shared_cell_local schema and are not migrated when an organization moves to a new cell. On-demand enqueues would therefore be silently lost. Only recurring cron jobs may enqueue cell-local workers, via Database::BackgroundOperation::CronEnqueueWorker.

See doc/development/database/background_operations.md for the full rationale.

Examples

# bad
Gitlab::Database::BackgroundOperation::WorkerCellLocal.enqueue(
  'MyOperationClass', 'target_table', 'id'
)

# good (recurring cron)
# Register the operation in config/schedule.yml under
# Database::BackgroundOperation::CronEnqueueWorker.

Database/PreventWildcardInjection

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Checks for potential wildcard injection vulnerabilities in LIKE queries

This cop detects dangerous patterns where user input could be used directly in LIKE queries without proper sanitization, potentially leading to wildcard injection attacks.

Examples

# bad
where("name LIKE '%#{term}%'")
where("title LIKE ?", "#{pattern}%")

# good
where("name LIKE ?", "%#{sanitize_sql_like(term)}%")
where("title LIKE ?", sanitize_sql_like(pattern))

Database/RescueQueryCanceled

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Checks for rescue blocks targeting the ActiveRecord::QueryCanceled class.

Examples

# bad

begin
  run_an_expensive_long_query
rescue ActiveRecord::QueryCanceled
  try_something_else
end
# good

run_cheap_queries_with_each_batch

Database/RescueStatementTimeout

Enabled by defaultSafeSupports autocorrectionVersion AddedVersion Changed
EnabledYesNo--

Checks for rescue blocks targeting the ActiveRecord::StatementTimeout class.

Examples

# bad

begin
  run_an_expensive_long_query
rescue ActiveRecord::StatementTimeout
  try_something_else
end
# good

run_cheap_queries_with_each_batch