diff --git a/app/models/packages/protection/rule.rb b/app/models/packages/protection/rule.rb
index 4de4ca37e55d8e8b1f09865f2e28463fd0b98671..6a06d1a21459aa6e16e92bf204dbc66759a5f29b 100644
--- a/app/models/packages/protection/rule.rb
+++ b/app/models/packages/protection/rule.rb
@@ -3,6 +3,9 @@
 module Packages
   module Protection
     class Rule < ApplicationRecord
+      include IgnorableColumns
+      ignore_column :package_name_pattern_ilike_query, remove_with: '16.11', remove_after: '2024-03-22'
+
       enum package_type: Packages::Package.package_types.slice(:npm)
       enum push_protected_up_to_access_level:
              Gitlab::Access.sym_options_with_owner.slice(:developer, :maintainer, :owner),
@@ -21,8 +24,6 @@ class Rule < ApplicationRecord
       validates :package_type, presence: true
       validates :push_protected_up_to_access_level, presence: true
 
-      before_save :set_package_name_pattern_ilike_query, if: :package_name_pattern_changed?
-
       scope :for_package_name, ->(package_name) do
         return none if package_name.blank?
 
@@ -39,17 +40,6 @@ def self.for_push_exists?(access_level:, package_name:, package_type:)
           .for_package_name(package_name)
           .exists?
       end
-
-      private
-
-      # We want to allow wildcard pattern (`*`) for the field `package_name_pattern`
-      # , e.g. `@my-scope/my-package-*`, etc.
-      # Therefore, we need to preprocess the field value before we can use the field in the ILIKE clause.
-      # E.g. convert wildcard character (`*`) to LIKE match character (`%`), escape certain characters, etc.
-      def set_package_name_pattern_ilike_query
-        self.package_name_pattern_ilike_query = self.class.sanitize_sql_like(package_name_pattern)
-                                                          .tr('*', '%')
-      end
     end
   end
 end
diff --git a/db/migrate/20240118172525_remove_not_null_constraint_from_package_name_pattern_ilike_query_column.rb b/db/migrate/20240118172525_remove_not_null_constraint_from_package_name_pattern_ilike_query_column.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c83e99775277b2e68144b7e6cf6968ed3e7b0096
--- /dev/null
+++ b/db/migrate/20240118172525_remove_not_null_constraint_from_package_name_pattern_ilike_query_column.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveNotNullConstraintFromPackageNamePatternIlikeQueryColumn < Gitlab::Database::Migration[2.2]
+  disable_ddl_transaction!
+
+  milestone '16.9'
+
+  def up
+    change_column_null :packages_protection_rules, :package_name_pattern_ilike_query, true
+  end
+
+  def down
+    change_column_null :packages_protection_rules, :package_name_pattern_ilike_query, false
+  end
+end
diff --git a/db/schema_migrations/20240118172525 b/db/schema_migrations/20240118172525
new file mode 100644
index 0000000000000000000000000000000000000000..d62e55e086f62a8a5d845891238c4625036391f6
--- /dev/null
+++ b/db/schema_migrations/20240118172525
@@ -0,0 +1 @@
+5856d91dec985d1de03ae428be8504404f1e38e18bad933c5d311d2019ac725c
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index a92849860428fb3a09ac18484446ca40c2924cc1..8d1e8651638094df52cf8218e7e28bebf1bfbb3f 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -21152,7 +21152,7 @@ CREATE TABLE packages_protection_rules (
     push_protected_up_to_access_level smallint NOT NULL,
     package_type smallint NOT NULL,
     package_name_pattern text NOT NULL,
-    package_name_pattern_ilike_query text NOT NULL,
+    package_name_pattern_ilike_query text,
     CONSTRAINT check_d2d75d206d CHECK ((char_length(package_name_pattern) <= 255)),
     CONSTRAINT check_ff47b09794 CHECK ((char_length(package_name_pattern_ilike_query) <= 255))
 );
diff --git a/spec/models/packages/protection/rule_spec.rb b/spec/models/packages/protection/rule_spec.rb
index 995f0035879b126cc724e372febf0d3b5323f5f7..3db97af4deeaa9fce12ba722d884461eb4235253 100644
--- a/spec/models/packages/protection/rule_spec.rb
+++ b/spec/models/packages/protection/rule_spec.rb
@@ -73,28 +73,6 @@
     end
   end
 
-  describe 'before_save' do
-    describe '#set_package_name_pattern_ilike_query' do
-      subject { create(:package_protection_rule, package_name_pattern: package_name_pattern) }
-
-      context 'with different package name patterns' do
-        where(:package_name_pattern, :expected_pattern_query) do
-          '@my-scope/my-package'                               | '@my-scope/my-package'
-          '@my-scope/*my-package-with-wildcard-start'          | '@my-scope/%my-package-with-wildcard-start'
-          '@my-scope/my-package-with-wildcard-end*'            | '@my-scope/my-package-with-wildcard-end%'
-          '@my-scope/my-package*with-wildcard-inbetween'       | '@my-scope/my-package%with-wildcard-inbetween'
-          '@my-scope/**my-package-**-with-wildcard-multiple**' | '@my-scope/%%my-package-%%-with-wildcard-multiple%%'
-          '@my-scope/my-package-with_____underscore'           | '@my-scope/my-package-with\_\_\_\_\_underscore'
-          '@my-scope/my-package-with-regex-characters.+'       | '@my-scope/my-package-with-regex-characters.+'
-        end
-
-        with_them do
-          it { is_expected.to have_attributes(package_name_pattern_ilike_query: expected_pattern_query) }
-        end
-      end
-    end
-  end
-
   describe '.for_package_name' do
     let_it_be(:package_protection_rule) do
       create(:package_protection_rule, package_name_pattern: '@my-scope/my_package')