From 70b249728e3c4026c0fdddc427fc864476b2ccd0 Mon Sep 17 00:00:00 2001 From: Tom Wolfe Date: Fri, 19 Jun 2026 02:17:49 +0100 Subject: [PATCH 1/3] fix: column duplication across schemas. --- .../Sql/PostgresSchemaProvider.cs | 4 +- .../Sql/PostgresSchemaProviderTests.cs | 41 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/NSchema.Postgres/Sql/PostgresSchemaProvider.cs b/src/NSchema.Postgres/Sql/PostgresSchemaProvider.cs index 3d0b3f4..37625d0 100644 --- a/src/NSchema.Postgres/Sql/PostgresSchemaProvider.cs +++ b/src/NSchema.Postgres/Sql/PostgresSchemaProvider.cs @@ -132,10 +132,10 @@ private static async Task> QueryColumns(NpgsqlConnection conn, s seq.seqincrement AS identity_increment, CASE WHEN c.is_generated = 'ALWAYS' THEN c.generation_expression END AS generation_expression FROM information_schema.columns c + LEFT JOIN pg_namespace n ON n.nspname = c.table_schema LEFT JOIN pg_class t ON t.relname = c.table_name + AND t.relnamespace = n.oid AND t.relkind = 'r' - LEFT JOIN pg_namespace n ON n.oid = t.relnamespace - AND n.nspname = c.table_schema LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attname = c.column_name LEFT JOIN pg_depend d ON d.refobjid = t.oid diff --git a/tests/NSchema.Postgres.Tests/Sql/PostgresSchemaProviderTests.cs b/tests/NSchema.Postgres.Tests/Sql/PostgresSchemaProviderTests.cs index 7d4c5aa..dec3769 100644 --- a/tests/NSchema.Postgres.Tests/Sql/PostgresSchemaProviderTests.cs +++ b/tests/NSchema.Postgres.Tests/Sql/PostgresSchemaProviderTests.cs @@ -1042,4 +1042,45 @@ public async Task GetSchema_Extensions_AreReportedAtRootWithVersion() citext.Version.ShouldNotBeNull(); schema.Extensions.ShouldNotContain(e => e.Name == "plpgsql"); } + + // ── Same table name across schemas ──────────────────────────────────────── + + // Regression: the columns query joined pg_class on relname alone (not namespace), so a table name shared by + // two schemas matched both pg_class rows and fanned every column row out once per schema — columns appeared + // duplicated in each table. Each table must report only its own columns. + [Fact] + public async Task GetSchema_SameTableNameInDifferentSchemas_DoesNotDuplicateColumns() + { + // Arrange + var other = $"test_{Guid.NewGuid():N}"; + await Exec($"CREATE SCHEMA \"{other}\""); + try + { + await Exec($""" + CREATE TABLE "{_schema}".users ( + id INTEGER NOT NULL, + name TEXT NOT NULL + ) + """); + await Exec($""" + CREATE TABLE "{other}".users ( + code INTEGER NOT NULL, + region TEXT NOT NULL + ) + """); + + // Act + var model = await _sut.GetSchema([_schema, other], TestContext.Current.CancellationToken); + + // Assert + var primary = model.Schemas.Single(s => s.Name == _schema).Tables.Single(t => t.Name == "users"); + var secondary = model.Schemas.Single(s => s.Name == other).Tables.Single(t => t.Name == "users"); + primary.Columns.Select(c => c.Name).ShouldBe(["id", "name"]); + secondary.Columns.Select(c => c.Name).ShouldBe(["code", "region"]); + } + finally + { + await Exec($"DROP SCHEMA IF EXISTS \"{other}\" CASCADE"); + } + } } From b237d0a6bfbaa9fc2d0f187f3bb00ee99f28b16c Mon Sep 17 00:00:00 2001 From: Tom Wolfe Date: Fri, 19 Jun 2026 02:18:11 +0100 Subject: [PATCH 2/3] build: bump version. --- src/NSchema.Postgres/NSchema.Postgres.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NSchema.Postgres/NSchema.Postgres.csproj b/src/NSchema.Postgres/NSchema.Postgres.csproj index b019ac7..4bff55c 100644 --- a/src/NSchema.Postgres/NSchema.Postgres.csproj +++ b/src/NSchema.Postgres/NSchema.Postgres.csproj @@ -20,7 +20,7 @@ true true snupkg - 3.0.0-alpha.12 + 3.0.0-beta.1 $(Version.Split('-')[0]) $(Version.Split('-')[0]) true From 5d824dfcdb2fb6c760b0ba8b33a1453c78aa39b9 Mon Sep 17 00:00:00 2001 From: Tom Wolfe Date: Fri, 19 Jun 2026 02:19:44 +0100 Subject: [PATCH 3/3] build: bump core package --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index c2742e6..cc94025 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,7 +7,7 @@ - +