Update database helpers to set the current_schema
What does this MR do?
With !41907 (merged), we have removed all assumptions about using the public
schema as the schema that GitLab uses.
That means that a GitLab instance can run using any arbitrary schema or even using multiple different schemas for different setups.
We have not observed the latter use case, but it is an option that an instance could follow and that would mean that the same tables exist in multiple schemas. Or an instance may use a specific schema for GitLab and have test tables in public
with the same names as ones defined in GitLab, like for example the very commonly used users
, projects
or issues
.
All our Migration Helpers that directly query pg_class
, pg_index
, pg_constraint
, etc currently do not set the schema when fetching information about database objects, which means that those helpers can match an object with the same relname in the wrong schema.
This MR adds the current schema to all queries that access the catalog and adds specs that test that our Migration helpers do not match the wrong object in the presence of multiple schemas.
Related issue: #256121 (closed)
Problem showcase
Using a simple test migration as an example:
def up
puts current_schema
table_name = 'audit_events_part_5fc467ac26_202009'
index_name = 'audit_events_part_5fc467ac26_202009_pkey'
if postgres_exists_by_name?(table_name, index_name)
puts "#{table_name}.#{index_name} exists!"
else
puts "#{table_name}.#{index_name} does NOT exist!"
end
table_name = 'audit_events_part_5fc467ac26_202009'
constraint_name = 'check_492aaa021d'
if check_constraint_exists?(table_name, constraint_name)
puts "#{table_name} --> #{constraint_name} exists!"
else
puts "#{table_name} --> #{constraint_name} does NOT exist!"
end
end
In the example above, we are searching for two objects that exist in the gitlab_partitions_dynamicschema (which is not included in the
search_path`)
Before, this update, it was matching both objects:
$ bundle exec rake db:migrate
== 20200928104232 TestCurrentSchema: migrating ================================
-- current_schema()
-> 0.0008s
public
audit_events_part_5fc467ac26_202009.audit_events_part_5fc467ac26_202009_pkey exists!
audit_events_part_5fc467ac26_202009 --> check_492aaa021d exists!
== 20200928104232 TestCurrentSchema: migrated (0.0026s) =======================
After this update, our migration helpers correctly report that the index and the constraint can not be found:
$ bundle exec rake db:migrate
== 20200928104232 TestCurrentSchema: migrating ================================
-- current_schema()
-> 0.0006s
public
-- current_schema()
-> 0.0003s
audit_events_part_5fc467ac26_202009.audit_events_part_5fc467ac26_202009_pkey does NOT exist!
-- current_schema()
-> 0.0002s
audit_events_part_5fc467ac26_202009 --> check_492aaa021d does NOT exist!
== 20200928104232 TestCurrentSchema: migrated (0.0037s) =======================
Similarly, with the updated specs, the existing version of the code would:
1) Gitlab::Database::MigrationHelpers#index_exists_by_name? when an index exists for a table with the the same name in another schema returns true if an index exists
Failure/Error:
expect(model.index_exists_by_name?(:projects, 'test_index_on_name'))
.to be_falsy
expected: falsey value
got: true
2) Gitlab::Database::MigrationHelpers#check_constraint_exists? returns false if a constraint with the same name exists for the same table in another schema
Failure/Error:
expect(model.check_constraint_exists?(:projects, 'check_2'))
.to be_falsy
expected: falsey value
got: true
... .... ...
With the updates, all specs pass.
Does this MR meet the acceptance criteria?
Conformity
-
Changelog entry - [-] Documentation (if required)
-
Code review guidelines -
Merge request performance guidelines -
Style guides -
Database guides - [-] Separation of EE specific content
Availability and Testing
-
Review and add/update tests for this feature/bug. Consider all test levels. See the Test Planning Process. - [-] Tested in all supported browsers
- [-] Informed Infrastructure department of a default or new setting change, if applicable per definition of done
Security
If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:
- [-] Label as security and @ mention
@gitlab-com/gl-security/appsec
- [-] The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
- [-] Security reports checked/validated by a reviewer from the AppSec team