fix(catalog): store reg* oid-alias columns as their display name, not the oid#385
Merged
Conversation
… the oid PostgreSQL `reg*` columns (regproc, regtype, regclass, ...) display as the object NAME, not the integer oid -- e.g. `pg_type.typinput` for the `text` type shows `textin`. Commit 0300310 had exported these as `::oid` integers so the oid-coercion analyzer rule could resolve name/numeric string comparisons. That benefit is now mostly gone (the coercion analyzer was replaced by SQL rewrites in #380, and the implicit comparison it served is blacklisted), while the display regression it introduced remains: clients saw `42` where real Postgres returns `textin` (issue #384). Revert the `reg*` storage to the display name (string), keeping the `pg.oid_alias=<kind>` field metadata so the wire layer (arrow-pg, fixed separately) still reports the correct alias type in RowDescription. Genuine `oid` columns stay int32 (Postgres displays oid as the integer). export_pg_catalog_arrow.sh (generates the committed feathers): - reg* family -> pa.string(); drop the `::oid` SELECT cast (select_expr). - oid stays pa.int32(); metadata stamping unchanged. - POSTGRES_PORT is now env-overridable (host-side publish is only for ad-hoc inspection; the export runs in-container). pg_to_arrow.py (generic exporter): it already stored reg* as string (the OIDs fall through to the pa.string() default); only the now-stale docstrings claimed int32. Updated the docstrings. Regenerated the 10 affected feathers against postgres:17.6 (unchanged version): pg_type, pg_proc, pg_aggregate, pg_operator, pg_am, pg_amproc, pg_conversion, pg_range, pg_ts_parser, pg_ts_template. Verified pg_type.typinput/typoutput/ typreceive/typsend are now `string` + `pg.oid_alias=regproc` holding the name (`textin`, `textout`, ...); oid/typnamespace remain int32. Added end-to-end test pg_type_regproc_columns_display_as_names: selecting typinput/typoutput for oid=25 returns `textin`/`textout`. Trade-off (documented in the issue/option choice): numeric oid equality on reg* columns (`WHERE typinput = 42`) and an explicit `col::regproc` cast on a (now string) reg* column no longer work the int path. The common display and name-comparison forms -- `SELECT typinput`, `typinput::text`, `WHERE typinput = 'textin'` -- are restored. Refs: #384
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.
Summary
PostgreSQL
reg*columns (regproc,regtype,regclass, ...) display as the object name, not the integer oid — e.g.pg_type.typinputfor thetexttype showstextin. Commit0300310had exported these as::oidintegers so the oid-coercion analyzer rule could resolve name/numeric string comparisons. That benefit is now mostly gone (the coercion analyzer was replaced by SQL rewrites in #380, and the implicit comparison it served is blacklisted), while the display regression it introduced remains: clients saw the raw oid where real Postgres returns the name (part of #384).This reverts the
reg*storage to the display name (string), keeping thepg.oid_alias=<kind>field metadata so the wire layer can still report the correct alias type. Genuineoidcolumns stayint32(Postgres displaysoidas the integer).Changes
export_pg_catalog_arrow.sh(generates the committed feathers):reg*family →pa.string(); dropped the::oidSELECT cast inselect_expr.oidstayspa.int32();pg.oid_aliasmetadata stamping unchanged.POSTGRES_PORTis now env-overridable (the host-side publish is only for ad-hoc inspection; the export runs in-container).pg_to_arrow.py(generic exporter): it already storedreg*as string (the OIDs fall through to thepa.string()default); only the now-stale docstrings claimed int32 — corrected.postgres:17.6(no version drift):pg_type,pg_proc,pg_aggregate,pg_operator,pg_am,pg_amproc,pg_conversion,pg_range,pg_ts_parser,pg_ts_template. Verified e.g.pg_type.typinput/typoutput/typreceive/typsendare nowstring+pg.oid_alias=regprocholding the name (textin,textout, ...);oid/typnamespaceremainint32.pg_type_regproc_columns_display_as_names: selectingtypinput/typoutputforoid = 25returnstextin/textout.Verification
cargo test -p datafusion-pg-catalog→ 46 passed (incl. the new test).Trade-off
Numeric oid equality on
reg*columns (WHERE typinput = 42) and an explicitcol::regproccast on a (now string)reg*column no longer take the int path. The common display/name-comparison forms —SELECT typinput,typinput::text,WHERE typinput = 'textin'— are restored.Refs: #384