Skip to content

Missing "public" schema fallback for migration table exists query #2787

Description

@Turnerj

There is a subtle bug with how the migration table exists query works when dealing with a combination of defined and non-defined schemas in a database (I know that is unusual but it is what it is).

The problem is this block of code:

protected override string ExistsSql
{
get
{
var builder = new StringBuilder();
builder.Append("SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace WHERE ");
var stringTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(string));
if (TableSchema is not null)
{
builder
.Append("n.nspname=")
.Append(stringTypeMapping.GenerateSqlLiteral(TableSchema))
.Append(" AND ");
}
builder
.Append("c.relname=")
.Append(stringTypeMapping.GenerateSqlLiteral(TableName))
.Append(");");
return builder.ToString();
}
}

If you don't specify a schema, that query will actually match against all schemas rather than filter to the default public schema. This means if you have a migration in another schema, that will be picked up even though it isn't valid for the current migration.

As far as I can tell, you can probably just do this without the outer null-check to resolve it:

         builder 
             .Append("n.nspname=") 
             .Append(stringTypeMapping.GenerateSqlLiteral(TableSchema ?? "public")) 
             .Append(" AND "); 

This was against Npgsql.EntityFrameworkCore.PostgreSQL v6.0.8


Steps to recreate issue:

  • Have two contexts, one with a schema, one without
  • Run a migration for the context with the schema
  • Attempt to run a migration for the context without the schema

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions