Commit ee0c3cc7 authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch 'centralized-whitelisted-and-blacklisted-tables' into 'master'

Concentrates whitelisted and blacklisted tables

See merge request gitlab-org/gitlab!25624
parents 70c30de2 e16b3e3e
...@@ -14,14 +14,18 @@ class AddStatusToDeployments < ActiveRecord::Migration[4.2] ...@@ -14,14 +14,18 @@ class AddStatusToDeployments < ActiveRecord::Migration[4.2]
# Ideally, `status` column should not have default value because it should be leveraged by state machine (i.e. application level). # Ideally, `status` column should not have default value because it should be leveraged by state machine (i.e. application level).
# However, we have to use the default value for avoiding `NOT NULL` violation during the transition period. # However, we have to use the default value for avoiding `NOT NULL` violation during the transition period.
# The default value should be removed in the future release. # The default value should be removed in the future release.
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default(:deployments, # rubocop:disable Migration/AddColumnWithDefault add_column_with_default(:deployments,
:status, :status,
:integer, :integer,
limit: 2, limit: 2,
default: DEPLOYMENT_STATUS_SUCCESS, default: DEPLOYMENT_STATUS_SUCCESS,
allow_null: false) allow_null: false)
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down def down
remove_column(:deployments, :status) remove_column(:deployments, :status)
......
...@@ -7,10 +7,12 @@ class AddMergeTrainEnabledToCiCdSettings < ActiveRecord::Migration[5.1] ...@@ -7,10 +7,12 @@ class AddMergeTrainEnabledToCiCdSettings < ActiveRecord::Migration[5.1]
disable_ddl_transaction! disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable # rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default :project_ci_cd_settings, :merge_trains_enabled, :boolean, default: false, allow_null: false add_column_with_default :project_ci_cd_settings, :merge_trains_enabled, :boolean, default: false, allow_null: false
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable # rubocop:enable Migration/UpdateLargeTable
def down def down
......
...@@ -7,9 +7,13 @@ class AddVariableTypeToCiPipelineVariables < ActiveRecord::Migration[5.0] ...@@ -7,9 +7,13 @@ class AddVariableTypeToCiPipelineVariables < ActiveRecord::Migration[5.0]
DOWNTIME = false DOWNTIME = false
ENV_VAR_VARIABLE_TYPE = 1 ENV_VAR_VARIABLE_TYPE = 1
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default(:ci_pipeline_variables, :variable_type, :smallint, default: ENV_VAR_VARIABLE_TYPE) # rubocop:disable Migration/AddColumnWithDefault add_column_with_default(:ci_pipeline_variables, :variable_type, :smallint, default: ENV_VAR_VARIABLE_TYPE)
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down def down
remove_column(:ci_pipeline_variables, :variable_type) remove_column(:ci_pipeline_variables, :variable_type)
......
...@@ -7,9 +7,13 @@ class AddDeploymentEventsToServices < ActiveRecord::Migration[5.0] ...@@ -7,9 +7,13 @@ class AddDeploymentEventsToServices < ActiveRecord::Migration[5.0]
disable_ddl_transaction! disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default(:services, :deployment_events, :boolean, default: false, allow_null: false) add_column_with_default(:services, :deployment_events, :boolean, default: false, allow_null: false)
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down def down
remove_column(:services, :deployment_events) remove_column(:services, :deployment_events)
......
...@@ -7,9 +7,13 @@ class AddCommentActionsToServices < ActiveRecord::Migration[5.2] ...@@ -7,9 +7,13 @@ class AddCommentActionsToServices < ActiveRecord::Migration[5.2]
disable_ddl_transaction! disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default(:services, :comment_on_event_enabled, :boolean, default: true) add_column_with_default(:services, :comment_on_event_enabled, :boolean, default: true)
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down def down
remove_column(:services, :comment_on_event_enabled) remove_column(:services, :comment_on_event_enabled)
......
...@@ -7,9 +7,13 @@ class AddInstanceToServices < ActiveRecord::Migration[6.0] ...@@ -7,9 +7,13 @@ class AddInstanceToServices < ActiveRecord::Migration[6.0]
disable_ddl_transaction! disable_ddl_transaction!
# rubocop:disable Migration/AddColumnWithDefault
# rubocop:disable Migration/UpdateLargeTable
def up def up
add_column_with_default(:services, :instance, :boolean, default: false) add_column_with_default(:services, :instance, :boolean, default: false)
end end
# rubocop:enable Migration/AddColumnWithDefault
# rubocop:enable Migration/UpdateLargeTable
def down def down
remove_column(:services, :instance) remove_column(:services, :instance)
......
...@@ -7,6 +7,7 @@ class ReaddTemplateColumnToServices < ActiveRecord::Migration[6.0] ...@@ -7,6 +7,7 @@ class ReaddTemplateColumnToServices < ActiveRecord::Migration[6.0]
disable_ddl_transaction! disable_ddl_transaction!
# rubocop:disable Migration/UpdateLargeTable
def up def up
return if column_exists? :services, :template return if column_exists? :services, :template
...@@ -16,6 +17,7 @@ class ReaddTemplateColumnToServices < ActiveRecord::Migration[6.0] ...@@ -16,6 +17,7 @@ class ReaddTemplateColumnToServices < ActiveRecord::Migration[6.0]
# of `template`, we would look for entries with `project_id IS NULL`. # of `template`, we would look for entries with `project_id IS NULL`.
add_column_with_default :services, :template, :boolean, default: false, allow_null: true add_column_with_default :services, :template, :boolean, default: false, allow_null: true
end end
# rubocop:enable Migration/UpdateLargeTable
def down def down
# NOP since the column is expected to exist # NOP since the column is expected to exist
......
...@@ -8,11 +8,6 @@ module RuboCop ...@@ -8,11 +8,6 @@ module RuboCop
class AddColumn < RuboCop::Cop::Cop class AddColumn < RuboCop::Cop::Cop
include MigrationHelpers include MigrationHelpers
WHITELISTED_TABLES = %i[
application_settings
plan_limits
].freeze
MSG = '`add_column` with a default value requires downtime, ' \ MSG = '`add_column` with a default value requires downtime, ' \
'use `add_column_with_default` instead'.freeze 'use `add_column_with_default` instead'.freeze
......
...@@ -10,38 +10,6 @@ module RuboCop ...@@ -10,38 +10,6 @@ module RuboCop
class AddColumnWithDefault < RuboCop::Cop::Cop class AddColumnWithDefault < RuboCop::Cop::Cop
include MigrationHelpers include MigrationHelpers
# Tables >= 10 GB on GitLab.com as of 02/2020
BLACKLISTED_TABLES = %i[
audit_events
ci_build_trace_sections
ci_builds
ci_builds_metadata
ci_job_artifacts
ci_pipeline_variables
ci_pipelines
ci_stages
deployments
events
issues
merge_request_diff_commits
merge_request_diff_files
merge_request_diffs
merge_request_metrics
merge_requests
note_diff_files
notes
project_authorizations
projects
push_event_payloads
resource_label_events
sent_notifications
system_note_metadata
taggings
todos
users
web_hook_logs
].freeze
MSG = '`add_column_with_default` without `allow_null: true` may cause prolonged lock situations and downtime, ' \ MSG = '`add_column_with_default` without `allow_null: true` may cause prolonged lock situations and downtime, ' \
'see https://gitlab.com/gitlab-org/gitlab/issues/38060'.freeze 'see https://gitlab.com/gitlab-org/gitlab/issues/38060'.freeze
......
...@@ -23,10 +23,6 @@ module RuboCop ...@@ -23,10 +23,6 @@ module RuboCop
NULL_OFFENSE = 'Boolean columns on the `%s` table should disallow nulls.'.freeze NULL_OFFENSE = 'Boolean columns on the `%s` table should disallow nulls.'.freeze
DEFAULT_AND_NULL_OFFENSE = 'Boolean columns on the `%s` table should have a default and should disallow nulls. You may wish to use `add_column_with_default`.'.freeze DEFAULT_AND_NULL_OFFENSE = 'Boolean columns on the `%s` table should have a default and should disallow nulls. You may wish to use `add_column_with_default`.'.freeze
SMALL_TABLES = %i[
application_settings
].freeze
def_node_matcher :add_column?, <<~PATTERN def_node_matcher :add_column?, <<~PATTERN
(send nil? :add_column $...) (send nil? :add_column $...)
PATTERN PATTERN
...@@ -41,7 +37,7 @@ module RuboCop ...@@ -41,7 +37,7 @@ module RuboCop
table, _, type = matched.to_a.take(3).map(&:children).map(&:first) table, _, type = matched.to_a.take(3).map(&:children).map(&:first)
opts = matched[3] opts = matched[3]
return unless SMALL_TABLES.include?(table) && type == :boolean return unless WHITELISTED_TABLES.include?(table) && type == :boolean
no_default = no_default?(opts) no_default = no_default?(opts)
nulls_allowed = nulls_allowed?(opts) nulls_allowed = nulls_allowed?(opts)
......
...@@ -19,26 +19,6 @@ module RuboCop ...@@ -19,26 +19,6 @@ module RuboCop
'complete, and should be avoided unless absolutely ' \ 'complete, and should be avoided unless absolutely ' \
'necessary'.freeze 'necessary'.freeze
LARGE_TABLES = %i[
ci_build_trace_sections
ci_builds
ci_job_artifacts
ci_pipelines
ci_stages
events
issues
merge_request_diff_commits
merge_request_diff_files
merge_request_diffs
merge_requests
namespaces
notes
projects
project_ci_cd_settings
routes
users
].freeze
BATCH_UPDATE_METHODS = %w[ BATCH_UPDATE_METHODS = %w[
:add_column_with_default :add_column_with_default
:change_column_type_concurrently :change_column_type_concurrently
...@@ -59,7 +39,7 @@ module RuboCop ...@@ -59,7 +39,7 @@ module RuboCop
update_method = matches.first update_method = matches.first
table = matches.last.to_a.first table = matches.last.to_a.first
return unless LARGE_TABLES.include?(table) return unless BLACKLISTED_TABLES.include?(table)
add_offense(node, location: :expression, message: format(MSG, update_method, table)) add_offense(node, location: :expression, message: format(MSG, update_method, table))
end end
......
module RuboCop module RuboCop
# Module containing helper methods for writing migration cops. # Module containing helper methods for writing migration cops.
module MigrationHelpers module MigrationHelpers
WHITELISTED_TABLES = %i[
application_settings
plan_limits
].freeze
# Blacklisted table due to:
# - size in GB (>= 10 GB on GitLab.com as of 02/2020)
# - number of records
BLACKLISTED_TABLES = %i[
audit_events
ci_build_trace_sections
ci_builds
ci_builds_metadata
ci_job_artifacts
ci_pipeline_variables
ci_pipelines
ci_stages
deployments
events
issues
merge_request_diff_commits
merge_request_diff_files
merge_request_diffs
merge_request_metrics
merge_requests
namespaces
note_diff_files
notes
project_authorizations
projects
project_ci_cd_settings
push_event_payloads
resource_label_events
routes
sent_notifications
services
system_note_metadata
taggings
todos
users
web_hook_logs
].freeze
# Returns true if the given node originated from the db/migrate directory. # Returns true if the given node originated from the db/migrate directory.
def in_migration?(node) def in_migration?(node)
dirname(node).end_with?('db/migrate', 'db/geo/migrate') || in_post_deployment_migration?(node) dirname(node).end_with?('db/migrate', 'db/geo/migrate') || in_post_deployment_migration?(node)
......
...@@ -17,7 +17,7 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do ...@@ -17,7 +17,7 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do
allow(cop).to receive(:in_migration?).and_return(true) allow(cop).to receive(:in_migration?).and_return(true)
end end
described_class::SMALL_TABLES.each do |table| described_class::WHITELISTED_TABLES.each do |table|
context "for the #{table} table" do context "for the #{table} table" do
sources_and_offense = [ sources_and_offense = [
["add_column :#{table}, :column, :boolean, default: true", 'should disallow nulls'], ["add_column :#{table}, :column, :boolean, default: true", 'should disallow nulls'],
...@@ -62,14 +62,14 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do ...@@ -62,14 +62,14 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do
end end
end end
it 'registers no offense for tables not listed in SMALL_TABLES' do it 'registers no offense for tables not listed in WHITELISTED_TABLES' do
inspect_source("add_column :large_table, :column, :boolean") inspect_source("add_column :large_table, :column, :boolean")
expect(cop.offenses).to be_empty expect(cop.offenses).to be_empty
end end
it 'registers no offense for non-boolean columns' do it 'registers no offense for non-boolean columns' do
table = described_class::SMALL_TABLES.sample table = described_class::WHITELISTED_TABLES.sample
inspect_source("add_column :#{table}, :column, :string") inspect_source("add_column :#{table}, :column, :string")
expect(cop.offenses).to be_empty expect(cop.offenses).to be_empty
...@@ -78,7 +78,7 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do ...@@ -78,7 +78,7 @@ describe RuboCop::Cop::Migration::SaferBooleanColumn do
context 'outside of migration' do context 'outside of migration' do
it 'registers no offense' do it 'registers no offense' do
table = described_class::SMALL_TABLES.sample table = described_class::WHITELISTED_TABLES.sample
inspect_source("add_column :#{table}, :column, :boolean") inspect_source("add_column :#{table}, :column, :boolean")
expect(cop.offenses).to be_empty expect(cop.offenses).to be_empty
......
...@@ -18,7 +18,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do ...@@ -18,7 +18,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do
end end
shared_examples 'large tables' do |update_method| shared_examples 'large tables' do |update_method|
described_class::LARGE_TABLES.each do |table| described_class::BLACKLISTED_TABLES.each do |table|
it "registers an offense for the #{table} table" do it "registers an offense for the #{table} table" do
inspect_source("#{update_method} :#{table}, :column, default: true") inspect_source("#{update_method} :#{table}, :column, default: true")
...@@ -53,7 +53,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do ...@@ -53,7 +53,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do
end end
it 'registers no offense for non-blacklisted methods' do it 'registers no offense for non-blacklisted methods' do
table = described_class::LARGE_TABLES.sample table = described_class::BLACKLISTED_TABLES.sample
inspect_source("some_other_method :#{table}, :column, default: true") inspect_source("some_other_method :#{table}, :column, default: true")
...@@ -62,7 +62,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do ...@@ -62,7 +62,7 @@ describe RuboCop::Cop::Migration::UpdateLargeTable do
end end
context 'outside of migration' do context 'outside of migration' do
let(:table) { described_class::LARGE_TABLES.sample } let(:table) { described_class::BLACKLISTED_TABLES.sample }
it 'registers no offense for add_column_with_default' do it 'registers no offense for add_column_with_default' do
inspect_source("add_column_with_default :#{table}, :column, default: true") inspect_source("add_column_with_default :#{table}, :column, default: true")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment