@@ -75,22 +75,8 @@ private RelationalCommandParameterObject CreateRelationalCommandParameters()
7575 /// doing so can result in application failures when updating to a new Entity Framework Core release.
7676 /// </summary>
7777 protected override string ExistsSql
78- {
79- get
80- {
81- var stringTypeMapping = Dependencies . TypeMappingSource . GetMapping ( typeof ( string ) ) ;
82-
83- return
84- $ """
85- SELECT EXISTS (
86- SELECT 1 FROM pg_catalog.pg_class c
87- JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace
88- WHERE n.nspname={ stringTypeMapping . GenerateSqlLiteral ( TableSchema ?? "public" ) } AND
89- c.relname={ stringTypeMapping . GenerateSqlLiteral ( TableName ) }
90- )
91- """ ;
92- }
93- }
78+ => throw new UnreachableException (
79+ "We should not be checking for the existence of the history table, but rather creating it and catching exceptions (see below)" ) ;
9480
9581 /// <summary>
9682 /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
@@ -194,6 +180,58 @@ public override string GetEndIfScript()
194180END $EF$;
195181""" ;
196182
183+ /// <summary>
184+ /// Calls the base implementation, but catches "table not found" exceptions; we do this rather than try to detect whether the
185+ /// migration table already exists (see <see cref="ExistsAsync" /> override below), since it's difficult to reliably check if the
186+ /// migration history table exists or not (because user may set PG <c>search_path</c>, which determines unqualified tables
187+ /// references when creating, selecting).
188+ /// </summary>
189+ public override IReadOnlyList < HistoryRow > GetAppliedMigrations ( )
190+ {
191+ try
192+ {
193+ return base . GetAppliedMigrations ( ) ;
194+ }
195+ catch ( PostgresException e ) when ( e . SqlState is "3D000" or "42P01" )
196+ {
197+ return [ ] ;
198+ }
199+ }
200+
201+ /// <summary>
202+ /// Calls the base implementation, but catches "table not found" exceptions; we do this rather than try to detect whether the
203+ /// migration table already exists (see <see cref="ExistsAsync" /> override below), since it's difficult to reliably check if the
204+ /// migration history table exists or not (because user may set PG <c>search_path</c>, which determines unqualified tables
205+ /// references when creating, selecting).
206+ /// </summary>
207+ public override async Task < IReadOnlyList < HistoryRow > > GetAppliedMigrationsAsync ( CancellationToken cancellationToken = default )
208+ {
209+ try
210+ {
211+ return await base . GetAppliedMigrationsAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
212+ }
213+ catch ( PostgresException e ) when ( e . SqlState is "3D000" or "42P01" )
214+ {
215+ return [ ] ;
216+ }
217+ }
218+
219+ /// <summary>
220+ /// Always returns <see langword="true" /> for PostgreSQL - it's difficult to reliably check if the migration history table
221+ /// exists or not (because user may set PG <c>search_path</c>, which determines unqualified tables references when creating,
222+ /// selecting). So we instead catch the "table doesn't exist" exceptions instead.
223+ /// </summary>
224+ public override bool Exists ( )
225+ => true ;
226+
227+ /// <summary>
228+ /// Always returns <see langword="true" /> for PostgreSQL - it's difficult to reliably check if the migration history table
229+ /// exists or not (because user may set PG <c>search_path</c>, which determines unqualified tables references when creating,
230+ /// selecting). So we instead catch the "table doesn't exist" exceptions instead.
231+ /// </summary>
232+ public override Task < bool > ExistsAsync ( CancellationToken cancellationToken = default )
233+ => Task . FromResult ( true ) ;
234+
197235 private sealed class NpgsqlMigrationDatabaseLock ( IHistoryRepository historyRepository ) : IMigrationsDatabaseLock
198236 {
199237 /// <summary>
0 commit comments