Skip to content

Commit b39050e

Browse files
pirjbyroot
authored andcommitted
Fix incorrect caching of case-insensitivity
`false` values would not cache with `||=`, and `begin` would run each time.
1 parent 324880c commit b39050e

File tree

3 files changed

+40
-16
lines changed

3 files changed

+40
-16
lines changed

activerecord/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
* Fix redundant updates to the column insensitivity cache
2+
3+
Fixed redundant queries checking column capability for insensitive
4+
comparison.
5+
6+
*Phil Pirozhkov*
7+
18
* Allow disabling methods generated by `ActiveRecord.enum`.
29

310
*Alfred Dominic*

activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,22 +1032,24 @@ def build_statement_pool
10321032

10331033
def can_perform_case_insensitive_comparison_for?(column)
10341034
@case_insensitive_cache ||= {}
1035-
@case_insensitive_cache[column.sql_type] ||= begin
1036-
sql = <<~SQL
1037-
SELECT exists(
1038-
SELECT * FROM pg_proc
1039-
WHERE proname = 'lower'
1040-
AND proargtypes = ARRAY[#{quote column.sql_type}::regtype]::oidvector
1041-
) OR exists(
1042-
SELECT * FROM pg_proc
1043-
INNER JOIN pg_cast
1044-
ON ARRAY[casttarget]::oidvector = proargtypes
1045-
WHERE proname = 'lower'
1046-
AND castsource = #{quote column.sql_type}::regtype
1047-
)
1048-
SQL
1049-
execute_and_clear(sql, "SCHEMA", [], allow_retry: true, uses_transaction: false) do |result|
1050-
result.getvalue(0, 0)
1035+
@case_insensitive_cache.fetch(column.sql_type) do
1036+
@case_insensitive_cache[column.sql_type] = begin
1037+
sql = <<~SQL
1038+
SELECT exists(
1039+
SELECT * FROM pg_proc
1040+
WHERE proname = 'lower'
1041+
AND proargtypes = ARRAY[#{quote column.sql_type}::regtype]::oidvector
1042+
) OR exists(
1043+
SELECT * FROM pg_proc
1044+
INNER JOIN pg_cast
1045+
ON ARRAY[casttarget]::oidvector = proargtypes
1046+
WHERE proname = 'lower'
1047+
AND castsource = #{quote column.sql_type}::regtype
1048+
)
1049+
SQL
1050+
execute_and_clear(sql, "SCHEMA", [], allow_retry: true, uses_transaction: false) do |result|
1051+
result.getvalue(0, 0)
1052+
end
10511053
end
10521054
end
10531055
end

activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,21 @@ def test_unparsed_defaults_are_at_least_set_when_saving
455455
end
456456
end
457457

458+
def test_only_check_for_insensitive_comparison_capability_once
459+
with_example_table "id SERIAL PRIMARY KEY, number INTEGER" do
460+
number_klass = Class.new(ActiveRecord::Base) do
461+
self.table_name = "ex"
462+
end
463+
attribute = number_klass.arel_table[:number]
464+
assert_queries :any, ignore_none: true do
465+
@connection.case_insensitive_comparison(attribute, "foo")
466+
end
467+
assert_no_queries do
468+
@connection.case_insensitive_comparison(attribute, "foo")
469+
end
470+
end
471+
end
472+
458473
private
459474
def with_example_table(definition = "id serial primary key, number integer, data character varying(255)", &block)
460475
super(@connection, "ex", definition, &block)

0 commit comments

Comments
 (0)