summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2019-03-29 08:38:42 -0700
committerStan Hu <stanhu@gmail.com>2019-03-29 08:38:42 -0700
commitde644e00c98c0e1a6d8d6697ab799f360791b7ad (patch)
tree6ccff420fc15d0ca23729a58793e51f484672c77
parent549f1732e09ee551dab8850fe2722dd9d5d7cd87 (diff)
downloadgitlab-ce-sh-add-index-extern-uid.tar.gz
Remove PostgreSQL monkey patchsh-add-index-extern-uid
Rails 5 added support for indexes with expressions, and this is necessary to update db/schema.rb.
-rw-r--r--config/initializers/postgresql_opclasses_support.rb211
-rw-r--r--db/migrate/20190328105753_add_index_on_identities_lower_extern_uid_and_lower_provider.rb4
-rw-r--r--db/schema.rb1
3 files changed, 4 insertions, 212 deletions
diff --git a/config/initializers/postgresql_opclasses_support.rb b/config/initializers/postgresql_opclasses_support.rb
deleted file mode 100644
index b066f3788ec..00000000000
--- a/config/initializers/postgresql_opclasses_support.rb
+++ /dev/null
@@ -1,211 +0,0 @@
-# rubocop:disable all
-
-# These changes add support for PostgreSQL operator classes when creating
-# indexes and dumping/loading schemas. Taken from Rails pull request
-# https://github.com/rails/rails/pull/19090.
-#
-# License:
-#
-# Copyright (c) 2004-2016 David Heinemeier Hansson
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-require 'date'
-require 'set'
-require 'bigdecimal'
-require 'bigdecimal/util'
-
-# As the Struct definition is changed in this PR/patch we have to first remove
-# the existing one.
-ActiveRecord::ConnectionAdapters.send(:remove_const, :IndexDefinition)
-
-module ActiveRecord
- module ConnectionAdapters #:nodoc:
- # Abstract representation of an index definition on a table. Instances of
- # this type are typically created and returned by methods in database
- # adapters. e.g. ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#indexes
- attrs = [:table, :name, :unique, :columns, :lengths, :orders, :where, :type, :using, :comment, :opclasses]
-
- class IndexDefinition < Struct.new(*attrs) #:nodoc:
- end
- end
-end
-
-
-module ActiveRecord
- module ConnectionAdapters # :nodoc:
- module SchemaStatements
- def add_index_options(table_name, column_name, options = {}) #:nodoc:
- column_names = Array(column_name)
- index_name = index_name(table_name, column: column_names)
-
- options.assert_valid_keys(:unique, :order, :name, :where, :length, :internal, :using, :algorithm, :type, :opclasses)
-
- index_type = options[:unique] ? "UNIQUE" : ""
- index_type = options[:type].to_s if options.key?(:type)
- index_name = options[:name].to_s if options.key?(:name)
- max_index_length = options.fetch(:internal, false) ? index_name_length : allowed_index_name_length
-
- if options.key?(:algorithm)
- algorithm = index_algorithms.fetch(options[:algorithm]) {
- raise ArgumentError.new("Algorithm must be one of the following: #{index_algorithms.keys.map(&:inspect).join(', ')}")
- }
- end
-
- using = "USING #{options[:using]}" if options[:using].present?
-
- if supports_partial_index?
- index_options = options[:where] ? " WHERE #{options[:where]}" : ""
- end
-
- if index_name.length > max_index_length
- raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{max_index_length} characters"
- end
- if data_source_exists?(table_name) && index_name_exists?(table_name, index_name, false)
- raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
- end
- index_columns = quoted_columns_for_index(column_names, options).join(", ")
-
- [index_name, index_type, index_columns, index_options, algorithm, using]
- end
- end
- end
-end
-
-module ActiveRecord
- module ConnectionAdapters
- module PostgreSQL
- module SchemaStatements
- # Returns an array of indexes for the given table.
- def indexes(table_name, name = nil)
- result = query(<<-SQL, 'SCHEMA')
- SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid
- FROM pg_class t
- INNER JOIN pg_index d ON t.oid = d.indrelid
- INNER JOIN pg_class i ON d.indexrelid = i.oid
- WHERE i.relkind = 'i'
- AND d.indisprimary = 'f'
- AND t.relname = '#{table_name}'
- AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) )
- ORDER BY i.relname
- SQL
-
- result.map do |row|
- index_name = row[0]
- unique = row[1]
- indkey = row[2].split(" ").map(&:to_i)
- inddef = row[3]
- oid = row[4]
-
- columns = Hash[query(<<-SQL, "SCHEMA")]
- SELECT a.attnum, a.attname
- FROM pg_attribute a
- WHERE a.attrelid = #{oid}
- AND a.attnum IN (#{indkey.join(",")})
- SQL
-
- column_names = columns.values_at(*indkey).compact
-
- unless column_names.empty?
- # add info on sort order for columns (only desc order is explicitly specified, asc is the default)
- desc_order_columns = inddef.scan(/(\w+) DESC/).flatten
- orders = desc_order_columns.any? ? Hash[desc_order_columns.map {|order_column| [order_column, :desc]}] : {}
- where = inddef.scan(/WHERE (.+)$/).flatten[0]
- using = inddef.scan(/USING (.+?) /).flatten[0].to_sym
- opclasses = Hash[inddef.scan(/\((.+?)\)(?:$| WHERE )/).flatten[0].split(',').map do |column_and_opclass|
- column, opclass = column_and_opclass.split(' ').map(&:strip)
- end.reject do |column, opclass|
- ['desc', 'asc'].include?(opclass&.downcase)
- end.map do |column, opclass|
- [column, opclass] if opclass
- end.compact]
-
- index_attrs = [table_name, index_name, unique, column_names, [], orders, where, nil, using, nil, opclasses]
-
- IndexDefinition.new(*index_attrs)
- end
- end.compact
- end
-
- def add_index(table_name, column_name, options = {}) #:nodoc:
- index_name, index_type, index_columns_and_opclasses, index_options, index_algorithm, index_using = add_index_options(table_name, column_name, options)
- execute "CREATE #{index_type} INDEX #{index_algorithm} #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} #{index_using} (#{index_columns_and_opclasses})#{index_options}"
- end
-
- protected
-
- def quoted_columns_for_index(column_names, options = {})
- column_opclasses = options[:opclasses] || {}
- column_names.map {|name| "#{quote_column_name(name)} #{column_opclasses[name]}"}
-
- quoted_columns = Hash[column_names.map { |name| [name.to_sym, "#{quote_column_name(name)} #{column_opclasses[name]}"] }]
- add_options_for_index_columns(quoted_columns, options).values
- end
- end
- end
- end
-end
-
-module ActiveRecord
- class SchemaDumper
- private
-
- def indexes(table, stream)
- if (indexes = @connection.indexes(table)).any?
- add_index_statements = indexes.map do |index|
- table_name = remove_prefix_and_suffix(index.table).inspect
- " add_index #{([table_name]+index_parts(index)).join(', ')}"
- end
-
- stream.puts add_index_statements.sort.join("\n")
- stream.puts
- end
- end
-
- def indexes_in_create(table, stream)
- if (indexes = @connection.indexes(table)).any?
- index_statements = indexes.map do |index|
- " t.index #{index_parts(index).join(', ')}"
- end
- stream.puts index_statements.sort.join("\n")
- end
- end
-
- def index_parts(index)
- index_parts = [
- index.columns.inspect,
- "name: #{index.name.inspect}",
- ]
- index_parts << "unique: true" if index.unique
- index_parts << "length: { #{format_options(index.lengths)} }" if index.lengths.present?
- index_parts << "order: { #{format_options(index.orders)} }" if index.orders.present?
- index_parts << "where: #{index.where.inspect}" if index.where
- index_parts << "using: #{index.using.inspect}" if index.using
- index_parts << "type: #{index.type.inspect}" if index.type
- index_parts << "opclasses: #{index.opclasses.inspect}" if index.opclasses.present?
- index_parts << "comment: #{index.comment.inspect}" if index.comment
- index_parts
- end
-
- def format_options(options)
- options.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")
- end
- end
-end
diff --git a/db/migrate/20190328105753_add_index_on_identities_lower_extern_uid_and_lower_provider.rb b/db/migrate/20190328105753_add_index_on_identities_lower_extern_uid_and_lower_provider.rb
index 1a0dd4a85de..4a76bcf89c4 100644
--- a/db/migrate/20190328105753_add_index_on_identities_lower_extern_uid_and_lower_provider.rb
+++ b/db/migrate/20190328105753_add_index_on_identities_lower_extern_uid_and_lower_provider.rb
@@ -12,7 +12,9 @@ class AddIndexOnIdentitiesLowerExternUidAndLowerProvider < ActiveRecord::Migrati
def up
return unless Gitlab::Database.postgresql?
- execute "CREATE INDEX CONCURRENTLY #{INDEX_NAME} ON identities (LOWER(extern_uid), LOWER(provider));"
+ unless index_exists?(:identities, 'lower(extern_uid), lower(provider)', name: INDEX_NAME)
+ add_concurrent_index(:identities, 'lower(extern_uid), lower(provider)', name: INDEX_NAME)
+ end
end
def down
diff --git a/db/schema.rb b/db/schema.rb
index db085a4aa83..2d8fbdc3405 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -1003,6 +1003,7 @@ ActiveRecord::Schema.define(version: 20190328105753) do
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
+ t.index "lower((extern_uid)::text), lower((provider)::text)", name: "index_on_identities_lower_extern_uid_and_lower_provider", using: :btree
t.index ["user_id"], name: "index_identities_on_user_id", using: :btree
end