Skip to content

Commit 16b5627

Browse files
authored
[release] fix: resolve NotSupportedException for schema-qualified PostgreSQL enum types (#421)
* fix: resolve NotSupportedException for schema-qualified PostgreSQL enum types When a PostgreSQL column references an enum type with schema qualification (e.g., `block_type public.post_block_type`), sqlc sets `column.Type.Schema` to `public`. However, `ConstructEnumsLookup` normalizes default schema enums under key `` (empty string), causing `GetEnumType` to fail the lookup and throw `NotSupportedException`. Fixed by normalizing the schema name in `GetEnumSchemaAndName` to empty string when it matches the driver's DefaultSchema. Changes: - Drivers/NpgsqlDriver.cs: normalize default schema in GetEnumSchemaAndName - unit-tests/CodegenTests/CodegenSchemaTests.cs: add failing-then-passing test - examples/config/postgresql/types/: add schema-qualified enum table + queries - examples/Npgsql*Example/: regenerated code with new model/queries - end2end/: add truncation for new table in e2e TearDown * fixup: use Any() instead of First() + null assertion in test * fix: bump MySQL version from 8.4.6 to 8.4.9 in legacy CI workflow 8.4.6 was removed from the MySQL CDN (404), causing Chocolatey install to fail. 8.4.9 is the latest 8.4.x patch available. * fix: remove MySQL version pin in legacy CI workflow The pinned versions 8.4.6 and 8.4.9 both fail — 8.4.6 downloads from a dead CDN URL, and 8.4.9 doesn't exist on Chocolatey. Removing the pin lets Chocolatey resolve the latest approved version with a valid URL. * refactor: merge qualified enum column into existing postgres_special_types table Move c_qualified_enum (public.c_enum) into the existing postgres_special_types table instead of a separate postgres_qualified_enum_types table, per PR feedback. The schema-qualified enum type is tested alongside the existing unqualified c_enum column in the same table and its queries. This avoids adding a new table to the schema.
1 parent 5f6252a commit 16b5627

21 files changed

Lines changed: 333 additions & 80 deletions

File tree

.github/workflows/legacy-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ jobs:
7171
shell: pwsh
7272
command: |
7373
$mysqlJob = Start-Job -ScriptBlock {
74-
choco install mysql --no-progress --version=8.4.6 -y --params "/serviceName:MySQL"
74+
choco install mysql --no-progress -y --params "/serviceName:MySQL"
7575
return $LASTEXITCODE
7676
}
7777

Drivers/NpgsqlDriver.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ public override string AddParametersToCommand(Query query)
730730
}).JoinByNewLine();
731731
}
732732

733-
private static (string, string) GetEnumSchemaAndName(Column column)
733+
private (string, string) GetEnumSchemaAndName(Column column)
734734
{
735735
var schemaName = column.Type.Schema;
736736
var enumName = column.Type.Name;
@@ -740,6 +740,8 @@ private static (string, string) GetEnumSchemaAndName(Column column)
740740
schemaName = schemaAndEnum[0];
741741
enumName = schemaAndEnum[1];
742742
}
743+
if (schemaName == DefaultSchema)
744+
schemaName = string.Empty;
743745
return (schemaName, enumName);
744746
}
745747

examples/NpgsqlDapperExample/Models.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public class PostgresSpecialType
8585
{
8686
public Guid? CUuid { get; init; }
8787
public CEnum? CEnum { get; init; }
88+
public CEnum? CQualifiedEnum { get; init; }
8889
public JsonElement? CJson { get; init; }
8990
public JsonElement? CJsonStringOverride { get; init; }
9091
public JsonElement? CJsonb { get; init; }

examples/NpgsqlDapperExample/QuerySql.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,8 @@ INSERT INTO postgres_special_types
13581358
c_xml,
13591359
c_xml_string_override,
13601360
c_uuid,
1361-
c_enum
1361+
c_enum,
1362+
c_qualified_enum
13621363
)
13631364
VALUES (
13641365
@c_json,
@@ -1368,7 +1369,8 @@ INSERT INTO postgres_special_types
13681369
@c_xml::xml,
13691370
@c_xml_string_override::xml,
13701371
@c_uuid,
1371-
@c_enum::c_enum
1372+
@c_enum::c_enum,
1373+
@c_qualified_enum::c_enum
13721374
)";
13731375
public class InsertPostgresSpecialTypesArgs
13741376
{
@@ -1380,6 +1382,7 @@ public class InsertPostgresSpecialTypesArgs
13801382
public string? CXmlStringOverride { get; init; }
13811383
public Guid? CUuid { get; init; }
13821384
public CEnum? CEnum { get; init; }
1385+
public CEnum? CQualifiedEnum { get; init; }
13831386
};
13841387
public async Task InsertPostgresSpecialTypesAsync(InsertPostgresSpecialTypesArgs args)
13851388
{
@@ -1392,6 +1395,7 @@ public async Task InsertPostgresSpecialTypesAsync(InsertPostgresSpecialTypesArgs
13921395
queryParams.Add("c_xml_string_override", args.CXmlStringOverride);
13931396
queryParams.Add("c_uuid", args.CUuid);
13941397
queryParams.Add("c_enum", args.CEnum != null ? args.CEnum.Value.Stringify() : null);
1398+
queryParams.Add("c_qualified_enum", args.CQualifiedEnum != null ? args.CQualifiedEnum.Value.Stringify() : null);
13951399
if (this.Transaction == null)
13961400
{
13971401
using (var connection = await GetDataSource().OpenConnectionAsync())
@@ -1484,7 +1488,8 @@ public async Task TruncatePostgresNotNullTypesAsync()
14841488
c_xml,
14851489
c_xml_string_override,
14861490
c_uuid,
1487-
c_enum
1491+
c_enum,
1492+
c_qualified_enum
14881493
FROM postgres_special_types
14891494
LIMIT 1";
14901495
public class GetPostgresSpecialTypesRow
@@ -1497,6 +1502,7 @@ public class GetPostgresSpecialTypesRow
14971502
public string? CXmlStringOverride { get; init; }
14981503
public Guid? CUuid { get; init; }
14991504
public CEnum? CEnum { get; init; }
1505+
public CEnum? CQualifiedEnum { get; init; }
15001506
};
15011507
public async Task<GetPostgresSpecialTypesRow?> GetPostgresSpecialTypesAsync()
15021508
{

examples/NpgsqlDapperExample/request.json

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,17 @@
605605
"name": "c_enum"
606606
}
607607
},
608+
{
609+
"name": "c_qualified_enum",
610+
"length": -1,
611+
"table": {
612+
"name": "postgres_special_types"
613+
},
614+
"type": {
615+
"schema": "public",
616+
"name": "c_enum"
617+
}
618+
},
608619
{
609620
"name": "c_json",
610621
"length": -1,
@@ -35090,7 +35101,7 @@
3509035101
}
3509135102
},
3509235103
{
35093-
"text": "\nINSERT INTO postgres_special_types\n(\n c_json,\n c_json_string_override,\n c_jsonb,\n c_jsonpath,\n c_xml,\n c_xml_string_override,\n c_uuid,\n c_enum\n)\nVALUES (\n $1, \n $2::json, \n $3,\n $4::jsonpath,\n $5::xml,\n $6::xml,\n $7,\n $8::c_enum\n)",
35104+
"text": "\nINSERT INTO postgres_special_types\n(\n c_json,\n c_json_string_override,\n c_jsonb,\n c_jsonpath,\n c_xml,\n c_xml_string_override,\n c_uuid,\n c_enum,\n c_qualified_enum\n)\nVALUES (\n $1, \n $2::json, \n $3,\n $4::jsonpath,\n $5::xml,\n $6::xml,\n $7,\n $8::c_enum,\n $9::c_enum\n)",
3509435105
"name": "InsertPostgresSpecialTypes",
3509535106
"cmd": ":exec",
3509635107
"parameters": [
@@ -35192,6 +35203,16 @@
3519235203
"name": "c_enum"
3519335204
}
3519435205
}
35206+
},
35207+
{
35208+
"number": 9,
35209+
"column": {
35210+
"name": "c_qualified_enum",
35211+
"length": -1,
35212+
"type": {
35213+
"name": "c_enum"
35214+
}
35215+
}
3519535216
}
3519635217
],
3519735218
"comments": [
@@ -35251,7 +35272,7 @@
3525135272
"filename": "query.sql"
3525235273
},
3525335274
{
35254-
"text": "SELECT\n c_json,\n c_json_string_override,\n c_jsonb,\n c_jsonpath,\n c_xml,\n c_xml_string_override,\n c_uuid,\n c_enum\nFROM postgres_special_types \nLIMIT 1",
35275+
"text": "SELECT\n c_json,\n c_json_string_override,\n c_jsonb,\n c_jsonpath,\n c_xml,\n c_xml_string_override,\n c_uuid,\n c_enum,\n c_qualified_enum\nFROM postgres_special_types \nLIMIT 1",
3525535276
"name": "GetPostgresSpecialTypes",
3525635277
"cmd": ":one",
3525735278
"columns": [
@@ -35344,6 +35365,18 @@
3534435365
"name": "c_enum"
3534535366
},
3534635367
"originalName": "c_enum"
35368+
},
35369+
{
35370+
"name": "c_qualified_enum",
35371+
"length": -1,
35372+
"table": {
35373+
"name": "postgres_special_types"
35374+
},
35375+
"type": {
35376+
"schema": "public",
35377+
"name": "c_enum"
35378+
},
35379+
"originalName": "c_qualified_enum"
3534735380
}
3534835381
],
3534935382
"filename": "query.sql"

examples/NpgsqlDapperExample/request.message

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
2
44
postgresql-examples/config/postgresql/authors/schema.sql+examples/config/postgresql/types/schema.sql",examples/config/postgresql/authors/query.sql"*examples/config/postgresql/types/query.sqlb�
55
examples/NpgsqlDapperExamplecsharp�{"debugRequest":true,"generateCsproj":true,"namespaceName":"NpgsqlDapperExampleGen","overrides":[{"column":"GetPostgresFunctions:max_integer","csharp_type":{"notNull":false,"type":"int"}},{"column":"GetPostgresFunctions:max_varchar","csharp_type":{"notNull":false,"type":"string"}},{"column":"GetPostgresFunctions:max_timestamp","csharp_type":{"notNull":true,"type":"DateTime"}},{"column":"GetPostgresSpecialTypesCnt:c_json","csharp_type":{"notNull":false,"type":"JsonElement"}},{"column":"GetPostgresSpecialTypesCnt:c_jsonb","csharp_type":{"notNull":false,"type":"JsonElement"}},{"column":"*:c_json_string_override","csharp_type":{"notNull":false,"type":"string"}},{"column":"*:c_xml_string_override","csharp_type":{"notNull":false,"type":"string"}},{"column":"*:c_macaddr8","csharp_type":{"notNull":false,"type":"string"}},{"column":"*:c_timestamp_noda_instant_override","csharp_type":{"notNull":false,"type":"Instant"}}],"targetFramework":"net8.0","useDapper":true}*
6-
./dist/LocalRunner�� public"�public�
6+
./dist/LocalRunner�� public"�public�
77
authors)
88
id0���������R authorsb  bigserial&
99
name0���������R authorsbtext#
@@ -83,10 +83,11 @@ pg_catalog timestamp
8383
c_box0���������Rpostgres_geometric_typesbbox7
8484
c_path0���������Rpostgres_geometric_typesbpath=
8585
c_polygon0���������Rpostgres_geometric_typesb polygon;
86-
c_circle0���������Rpostgres_geometric_typesbcircle�
86+
c_circle0���������Rpostgres_geometric_typesbcircle�
8787
postgres_special_types5
8888
c_uuid0���������Rpostgres_special_typesbuuid7
89-
c_enum0���������Rpostgres_special_typesbc_enumA
89+
c_enum0���������Rpostgres_special_typesbc_enumI
90+
c_qualified_enum0���������Rpostgres_special_typesbpublicc_enumA
9091
c_json0���������Rpostgres_special_typesb
9192
pg_catalogjsonQ
9293
c_json_string_override0���������Rpostgres_special_typesb
@@ -10680,8 +10681,8 @@ LIMIT 1GetPostgresNetworkTypesCnt:one"=
1068010681
) VALUES ($1, $2, $3)InsertPostgresNetworkTypesBatch :copyfrom*IE
1068110682
c_cidr0���������R publicpostgres_network_typesbcidrzc_cidr*IE
1068210683
c_inet0���������R publicpostgres_network_typesbinetzc_inet*RN
10683-
c_macaddr0���������R publicpostgres_network_typesb macaddrz c_macaddr: query.sqlBpostgres_network_types�
10684-
�
10684+
c_macaddr0���������R publicpostgres_network_typesb macaddrz c_macaddr: query.sqlBpostgres_network_types�
10685+
�
1068510686
INSERT INTO postgres_special_types
1068610687
(
1068710688
c_json,
@@ -10691,7 +10692,8 @@ INSERT INTO postgres_special_types
1069110692
c_xml,
1069210693
c_xml_string_override,
1069310694
c_uuid,
10694-
c_enum
10695+
c_enum,
10696+
c_qualified_enum
1069510697
)
1069610698
VALUES (
1069710699
$1,
@@ -10701,7 +10703,8 @@ VALUES (
1070110703
$5::xml,
1070210704
$6::xml,
1070310705
$7,
10704-
$8::c_enum
10706+
$8::c_enum,
10707+
$9::c_enum
1070510708
)InsertPostgresSpecialTypes:exec*VR
1070610709
c_json0���������8R publicpostgres_special_typesbpg_catalog.jsonzc_json*;7
1070710710
c_json_string_override0���������b
@@ -10713,7 +10716,8 @@ c_jsonpath0
1071310716
c_xml0���������bxml*-)
1071410717
c_xml_string_override0���������bxml*KG
1071510718
c_uuid0���������8R publicpostgres_special_typesbuuidzc_uuid*!
10716-
c_enum0���������bc_enum2 Special types : query.sqlBpostgres_special_types�
10719+
c_enum0���������bc_enum*+ '
10720+
c_qualified_enum0���������bc_enum2 Special types : query.sqlBpostgres_special_types�
1071710721
UINSERT INTO postgres_not_null_types
1071810722
(
1071910723
c_enum_not_null
@@ -10727,16 +10731,17 @@ VALUES (
1072710731
FROM postgres_not_null_types
1072810732
LIMIT 1GetPostgresNotNullTypes:one"T
1072910733
c_enum_not_null0���������Rpostgres_not_null_typesbc_enumzc_enum_not_null: query.sqlX
10730-
&TRUNCATE TABLE postgres_not_null_typesTruncatePostgresNotNullTypes:exec: query.sql�
10731-
�SELECT
10734+
&TRUNCATE TABLE postgres_not_null_typesTruncatePostgresNotNullTypes:exec: query.sql�
10735+
�SELECT
1073210736
c_json,
1073310737
c_json_string_override,
1073410738
c_jsonb,
1073510739
c_jsonpath,
1073610740
c_xml,
1073710741
c_xml_string_override,
1073810742
c_uuid,
10739-
c_enum
10743+
c_enum,
10744+
c_qualified_enum
1074010745
FROM postgres_special_types
1074110746
LIMIT 1GetPostgresSpecialTypes:one"I
1074210747
c_json0���������Rpostgres_special_typesb
@@ -10751,7 +10756,8 @@ c_jsonpath":
1075110756
c_xml0���������Rpostgres_special_typesbxmlzc_xml"Z
1075210757
c_xml_string_override0���������Rpostgres_special_typesbxmlzc_xml_string_override"=
1075310758
c_uuid0���������Rpostgres_special_typesbuuidzc_uuid"?
10754-
c_enum0���������Rpostgres_special_typesbc_enumzc_enum: query.sqlW
10759+
c_enum0���������Rpostgres_special_typesbc_enumzc_enum"[
10760+
c_qualified_enum0���������Rpostgres_special_typesbpublicc_enumzc_qualified_enum: query.sqlW
1075510761
%TRUNCATE TABLE postgres_special_typesTruncatePostgresSpecialTypes:exec: query.sql�
1075610762
lINSERT INTO postgres_special_types
1075710763
(

examples/NpgsqlDapperLegacyExample/Models.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public class PostgresSpecialType
8686
{
8787
public Guid? CUuid { get; set; }
8888
public CEnum? CEnum { get; set; }
89+
public CEnum? CQualifiedEnum { get; set; }
8990
public JsonElement? CJson { get; set; }
9091
public JsonElement? CJsonStringOverride { get; set; }
9192
public JsonElement? CJsonb { get; set; }

examples/NpgsqlDapperLegacyExample/QuerySql.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,8 @@ INSERT INTO postgres_special_types
13591359
c_xml,
13601360
c_xml_string_override,
13611361
c_uuid,
1362-
c_enum
1362+
c_enum,
1363+
c_qualified_enum
13631364
)
13641365
VALUES (
13651366
@c_json,
@@ -1369,7 +1370,8 @@ INSERT INTO postgres_special_types
13691370
@c_xml::xml,
13701371
@c_xml_string_override::xml,
13711372
@c_uuid,
1372-
@c_enum::c_enum
1373+
@c_enum::c_enum,
1374+
@c_qualified_enum::c_enum
13731375
)";
13741376
public class InsertPostgresSpecialTypesArgs
13751377
{
@@ -1381,6 +1383,7 @@ public class InsertPostgresSpecialTypesArgs
13811383
public string CXmlStringOverride { get; set; }
13821384
public Guid? CUuid { get; set; }
13831385
public CEnum? CEnum { get; set; }
1386+
public CEnum? CQualifiedEnum { get; set; }
13841387
};
13851388
public async Task InsertPostgresSpecialTypesAsync(InsertPostgresSpecialTypesArgs args)
13861389
{
@@ -1393,6 +1396,7 @@ public async Task InsertPostgresSpecialTypesAsync(InsertPostgresSpecialTypesArgs
13931396
queryParams.Add("c_xml_string_override", args.CXmlStringOverride);
13941397
queryParams.Add("c_uuid", args.CUuid);
13951398
queryParams.Add("c_enum", args.CEnum != null ? args.CEnum.Value.Stringify() : null);
1399+
queryParams.Add("c_qualified_enum", args.CQualifiedEnum != null ? args.CQualifiedEnum.Value.Stringify() : null);
13961400
if (this.Transaction == null)
13971401
{
13981402
using (var connection = await GetDataSource().OpenConnectionAsync())
@@ -1485,7 +1489,8 @@ public async Task TruncatePostgresNotNullTypesAsync()
14851489
c_xml,
14861490
c_xml_string_override,
14871491
c_uuid,
1488-
c_enum
1492+
c_enum,
1493+
c_qualified_enum
14891494
FROM postgres_special_types
14901495
LIMIT 1";
14911496
public class GetPostgresSpecialTypesRow
@@ -1498,6 +1503,7 @@ public class GetPostgresSpecialTypesRow
14981503
public string CXmlStringOverride { get; set; }
14991504
public Guid? CUuid { get; set; }
15001505
public CEnum? CEnum { get; set; }
1506+
public CEnum? CQualifiedEnum { get; set; }
15011507
};
15021508
public async Task<GetPostgresSpecialTypesRow> GetPostgresSpecialTypesAsync()
15031509
{

examples/NpgsqlDapperLegacyExample/request.json

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,17 @@
605605
"name": "c_enum"
606606
}
607607
},
608+
{
609+
"name": "c_qualified_enum",
610+
"length": -1,
611+
"table": {
612+
"name": "postgres_special_types"
613+
},
614+
"type": {
615+
"schema": "public",
616+
"name": "c_enum"
617+
}
618+
},
608619
{
609620
"name": "c_json",
610621
"length": -1,
@@ -35090,7 +35101,7 @@
3509035101
}
3509135102
},
3509235103
{
35093-
"text": "\nINSERT INTO postgres_special_types\n(\n c_json,\n c_json_string_override,\n c_jsonb,\n c_jsonpath,\n c_xml,\n c_xml_string_override,\n c_uuid,\n c_enum\n)\nVALUES (\n $1, \n $2::json, \n $3,\n $4::jsonpath,\n $5::xml,\n $6::xml,\n $7,\n $8::c_enum\n)",
35104+
"text": "\nINSERT INTO postgres_special_types\n(\n c_json,\n c_json_string_override,\n c_jsonb,\n c_jsonpath,\n c_xml,\n c_xml_string_override,\n c_uuid,\n c_enum,\n c_qualified_enum\n)\nVALUES (\n $1, \n $2::json, \n $3,\n $4::jsonpath,\n $5::xml,\n $6::xml,\n $7,\n $8::c_enum,\n $9::c_enum\n)",
3509435105
"name": "InsertPostgresSpecialTypes",
3509535106
"cmd": ":exec",
3509635107
"parameters": [
@@ -35192,6 +35203,16 @@
3519235203
"name": "c_enum"
3519335204
}
3519435205
}
35206+
},
35207+
{
35208+
"number": 9,
35209+
"column": {
35210+
"name": "c_qualified_enum",
35211+
"length": -1,
35212+
"type": {
35213+
"name": "c_enum"
35214+
}
35215+
}
3519535216
}
3519635217
],
3519735218
"comments": [
@@ -35251,7 +35272,7 @@
3525135272
"filename": "query.sql"
3525235273
},
3525335274
{
35254-
"text": "SELECT\n c_json,\n c_json_string_override,\n c_jsonb,\n c_jsonpath,\n c_xml,\n c_xml_string_override,\n c_uuid,\n c_enum\nFROM postgres_special_types \nLIMIT 1",
35275+
"text": "SELECT\n c_json,\n c_json_string_override,\n c_jsonb,\n c_jsonpath,\n c_xml,\n c_xml_string_override,\n c_uuid,\n c_enum,\n c_qualified_enum\nFROM postgres_special_types \nLIMIT 1",
3525535276
"name": "GetPostgresSpecialTypes",
3525635277
"cmd": ":one",
3525735278
"columns": [
@@ -35344,6 +35365,18 @@
3534435365
"name": "c_enum"
3534535366
},
3534635367
"originalName": "c_enum"
35368+
},
35369+
{
35370+
"name": "c_qualified_enum",
35371+
"length": -1,
35372+
"table": {
35373+
"name": "postgres_special_types"
35374+
},
35375+
"type": {
35376+
"schema": "public",
35377+
"name": "c_enum"
35378+
},
35379+
"originalName": "c_qualified_enum"
3534735380
}
3534835381
],
3534935382
"filename": "query.sql"

0 commit comments

Comments
 (0)