Decode internal "char" type (OID 18) natively#168
Open
Dev-iL wants to merge 1 commit into
Open
Conversation
Member
|
@Dev-iL Could you please check lint stages? |
Author
|
Yeah, forgot to enable hooks locally after cloning. Will fix shortly... |
Fixes psqlpy-python#165. Any query touching PostgreSQL system catalogs (pg_type, pg_class, pg_attribute, pg_proc, ...) raised RustToPyValueMappingError because the internal "char" type — distinct from character(n)/BPCHAR — had no native decoder and fell through to other_postgres_bytes_to_py. Add an InternalChar(u8) wrapper next to the existing InternalUuid / InnerDecimal / InnerInterval helpers and wire it into postgres_bytes_to_py via two new match arms (Type::CHAR, Type::CHAR_ARRAY). The byte is read through tokio-postgres' i8 FromSql impl, cast back to u8, and mapped to a one-character Python str through char::from(u8) — i.e. Unicode code points 0..=255 (Latin-1 round-trip), matching psycopg2/psycopg3. The custom_decoders dispatch is intentionally unchanged: it stays keyed by column name per the existing documented contract. Tests: - python/tests/test_value_converter.py: * test_char_internal_type_pg_type_reproduction — exact snippet from psqlpy-python#165 * test_char_internal_type_byte_spectrum — reachable ASCII bytes 0x20, 0x41, 0x61, 0x7E plus NULL (SQL chr() rejects NUL and re-encodes >=0x80 as multi-byte UTF-8) * test_char_internal_type_array — "char"[] decoded to list[str] - src/value_converter/models/internal_char.rs: * from_sql_round_trips_full_byte_range — full 0..=255 byte mapping the SQL test cannot reach * accepts_only_char_type — type guard rejects TEXT/VARCHAR/BPCHAR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds a native decoder for PostgreSQL's internal
"char"type (OID 18) and its array variant. A newInternalChar(u8)wrapper sits alongside the existingInternalUuid/InnerDecimal/InnerIntervalhelpers; two new arms inpostgres_bytes_to_py(Type::CHAR,Type::CHAR_ARRAY) decode the single wire byte to a one-character Pythonstrviachar::from(u8)— Unicode code points 0..=255, Latin-1 round-trip, matching psycopg2/psycopg3.custom_decoderskeying is intentionally unchanged (still column-name-keyed, lowercase, per the existing documented contract).Motivation and Context
Fixes #165.
Querying any column of the internal
"char"type — distinct fromcharacter(n)/BPCHAR — raisedRustToPyValueMappingError: Cannot convert _char into Python type, please look at the custom_decoders functionality.The type had no native decoder and fell through toother_postgres_bytes_to_py. The error message pointed atcustom_decoders, but that path is keyed by column name, not type, so for users hitting this throughpg_type/pg_class/pg_attribute/pg_proc(where"char"columns are pervasive —pg_typealone has five) it offered no workable escape.How has this been tested?
cargo build --releasecargo clippy --all-targets -- -D warnings— cleancargo test --release internal_char— 2 passed (full 0..=255 byte round-trip +accepts()type guard rejects TEXT / VARCHAR / BPCHAR)pytest python/tests/test_value_converter.py— 163 passed, including three new tests:test_char_internal_type_pg_type_reproduction— the exact failing snippet from the issuetest_char_internal_type_byte_spectrum— round-trips bytes0x20 / 0x41 / 0x61 / 0x7Eplus NULL through a temp"char"column (SQLchr()rejects NUL and re-encodes>= 0x80as multi-byte UTF-8 of which only the first byte is stored, so the full 0..=255 range is exercised by the Rust unit test instead)test_char_internal_type_array— decodesARRAY['a'::"char", 'b'::"char", 'c'::"char"]to["a", "b", "c"]RustToPyValueMappingError: Cannot convert _char into Python typeerror; with the fix in place, they pass.Tested against PostgreSQL 14 (psqlpy's lowest supported major version) on Linux / Python 3.12.
Screenshots (if appropriate):
N/A.
Types of changes
Checklist: