From 5c77a511b78f7291e07c411ec21b0e030ad887a0 Mon Sep 17 00:00:00 2001 From: Nino Floris Date: Sun, 26 Oct 2025 18:33:39 +0100 Subject: [PATCH 1/2] Respect configured schemas in enum field loading Closes #6246 --- src/Npgsql/PostgresDatabaseInfo.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Npgsql/PostgresDatabaseInfo.cs b/src/Npgsql/PostgresDatabaseInfo.cs index 6cd4f2a5fe..2e46dd66e7 100644 --- a/src/Npgsql/PostgresDatabaseInfo.cs +++ b/src/Npgsql/PostgresDatabaseInfo.cs @@ -183,12 +183,14 @@ JOIN pg_attribute AS att ON (att.attrelid = typ.typrelid) NOT attisdropped ORDER BY typ.oid, att.attnum;"; - static string GenerateLoadEnumFieldsQuery(bool withEnumSortOrder) + static string GenerateLoadEnumFieldsQuery(bool withEnumSortOrder, string? schemaListSqlFragment) => $@" -- Load enum fields -SELECT pg_type.oid, enumlabel +SELECT typ.oid, enumlabel FROM pg_enum -JOIN pg_type ON pg_type.oid=enumtypid +JOIN pg_type AS typ ON typ.oid = enumtypid +JOIN pg_namespace AS ns ON ns.oid = typ.typnamespace +{(schemaListSqlFragment is not null ? $"WHERE (ns.nspname IN ({BuiltinSchemaListSqlFragment}{(schemaListSqlFragment.Length > 0 ? $", {schemaListSqlFragment}" : "")}))" : "")} ORDER BY oid{(withEnumSortOrder ? ", enumsortorder" : "")};"; /// @@ -230,7 +232,7 @@ internal async Task> LoadBackendTypes(NpgsqlConnector conn, N var loadTypesQuery = GenerateLoadTypesQuery(SupportsRangeTypes, SupportsMultirangeTypes, loadTableComposites, schemaListSqlFragment, HasTypeCategory); var loadCompositeTypesQuery = GenerateLoadCompositeTypesQuery(loadTableComposites, schemaListSqlFragment); var loadEnumFieldsQuery = SupportsEnumTypes - ? GenerateLoadEnumFieldsQuery(HasEnumSortOrder) + ? GenerateLoadEnumFieldsQuery(HasEnumSortOrder, schemaListSqlFragment) : string.Empty; timeout.CheckAndApply(conn); From b1a55abaf1ee8415eecd0caa2724aa9eb8d8532f Mon Sep 17 00:00:00 2001 From: Nino Floris Date: Mon, 27 Oct 2025 15:21:54 +0100 Subject: [PATCH 2/2] Small cleanup --- src/Npgsql/PostgresDatabaseInfo.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Npgsql/PostgresDatabaseInfo.cs b/src/Npgsql/PostgresDatabaseInfo.cs index 2e46dd66e7..1c1b518a3f 100644 --- a/src/Npgsql/PostgresDatabaseInfo.cs +++ b/src/Npgsql/PostgresDatabaseInfo.cs @@ -149,8 +149,8 @@ LEFT JOIN pg_class AS elemcls ON (elemcls.oid = elemtyp.typrelid) ) AS t JOIN pg_namespace AS ns ON (ns.oid = typnamespace) WHERE - {(schemaListSqlFragment is not null ? $"(ns.nspname IN ({BuiltinSchemaListSqlFragment}{(schemaListSqlFragment.Length > 0 ? $", {schemaListSqlFragment}" : "")}){(hasTypeCategory ? " OR typcategory = 'U'" : "" )}) AND (" : "(")} - typtype IN ('b', 'r', 'm', 'e', 'd') OR -- Base, range, multirange, enum, domain + {(schemaListSqlFragment is not null ? $"(ns.nspname IN ({schemaListSqlFragment}){(hasTypeCategory ? " OR typcategory = 'U'" : "" )}) AND " : "")} + (typtype IN ('b', 'r', 'm', 'e', 'd') OR -- Base, range, multirange, enum, domain (typtype = 'c' AND {(loadTableComposites ? $"ns.nspname NOT IN ({BuiltinSchemaListSqlFragment})" : "relkind='c'")}) OR -- User-defined free-standing composites (not table composites) by default (typtype = 'p' AND typname IN ('record', 'void', 'unknown')) OR -- Some special supported pseudo-types (typtype = 'a' AND ( -- Array of... @@ -178,7 +178,7 @@ JOIN pg_class AS cls ON (cls.oid = typ.typrelid) JOIN pg_attribute AS att ON (att.attrelid = typ.typrelid) WHERE (typ.typtype = 'c' AND {(loadTableComposites ? $"ns.nspname NOT IN ({BuiltinSchemaListSqlFragment})" : "cls.relkind='c'")}) AND - {(schemaListSqlFragment is not null ? $"(ns.nspname IN ({BuiltinSchemaListSqlFragment}{(schemaListSqlFragment.Length > 0 ? $", {schemaListSqlFragment}" : "")})) AND " : "")} + {(schemaListSqlFragment is not null ? $"(ns.nspname IN ({schemaListSqlFragment})) AND " : "")} attnum > 0 AND -- Don't load system attributes NOT attisdropped ORDER BY typ.oid, att.attnum;"; @@ -190,7 +190,7 @@ static string GenerateLoadEnumFieldsQuery(bool withEnumSortOrder, string? schema FROM pg_enum JOIN pg_type AS typ ON typ.oid = enumtypid JOIN pg_namespace AS ns ON ns.oid = typ.typnamespace -{(schemaListSqlFragment is not null ? $"WHERE (ns.nspname IN ({BuiltinSchemaListSqlFragment}{(schemaListSqlFragment.Length > 0 ? $", {schemaListSqlFragment}" : "")}))" : "")} +{(schemaListSqlFragment is not null ? $"WHERE (ns.nspname IN ({schemaListSqlFragment}))" : "")} ORDER BY oid{(withEnumSortOrder ? ", enumsortorder" : "")};"; /// @@ -215,11 +215,10 @@ internal async Task> LoadBackendTypes(NpgsqlConnector conn, N string? schemaListSqlFragment = null; if (typeLoading.TypeLoadingSchemas is not null) { - var builder = new StringBuilder(); + var builder = new StringBuilder(BuiltinSchemaListSqlFragment); for (var i = 0; i < typeLoading.TypeLoadingSchemas.Length; i++) { - if (i > 0) - builder.Append(", "); + builder.Append(", "); var schema = typeLoading.TypeLoadingSchemas[i]; builder.Append('\''); builder.Append(EscapeLiteral(schema));