Quote the internal "char" type's CreateFormat in DataTypes by alaricd · Pull Request #6684 · npgsql/npgsql · GitHub
Skip to content

Quote the internal "char" type's CreateFormat in DataTypes - #6684

Open
alaricd wants to merge 1 commit into
npgsql:mainfrom
pengdows:fix/datatypes-internal-char
Open

alaricd wants to merge 1 commit into
npgsql:mainfrom
pengdows:fix/datatypes-internal-char

Conversation

@alaricd

@alaricd alaricd commented Oct 20, 2026

Copy link
Copy Markdown

The DataTypes row for PostgreSQL's internal one-byte "char" type (OID 18) advertises CreateFormat CHAR({0}) with CreateParameters size. Unquoted, CHAR(n) is character(n) (bpchar), a different type, so a column created from the row isn't a "char" column: it reads as System.String, while the row's DataType is System.Char.

DataTypes row: char | CHAR({0}) | size | System.Char | OID 18
CREATE TABLE t (c CHAR(10))   -- creates character(10), read as System.String

The cause is in PopulateHardcodedDataTypeInfo: case "char" compares the display name, so it matches OID 18 rather than bpchar (character), and falls through to case "text", which adds the size. This gives "char" its own case: CreateFormat is "char" (and "char"[] for the array), with no size. The other values it had through the fall-through (literal prefix and suffix, searchable with LIKE, not the best match for System.Char) are unchanged.

DataTypes_CreateFormat_of_internal_char_creates_that_type creates a column from the row, checks in pg_attribute that it is type 18, and checks that the reader returns the row's DataType. It fails on main; all SchemaTests pass against PostgreSQL 17 (204).

This touches the same switch as #6683, which takes CreateFormat modifiers from pg_type.typmodin; the two are independent, and I'll rebase whichever merges second.

Found with the pengdows ADO.NET conformance suite, whose type-fidelity tests create a column from each DataTypes row and check that the type read back is the one advertised.

🤖 Generated with Claude Code

The DataTypes row for PostgreSQL's one-byte "char" type (OID 18)
advertised CHAR({0}), but unquoted, CHAR(n) is character(n), a different
type: a column made from it read as string, not the char its DataType
says. Advertise "char", which takes no size.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alaricd
alaricd requested review from roji and vonzshik as code owners October 20, 2026 14:29

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant