Skip to content

fix: preserve typmod for extension types in column type resolution (#295)#297

Merged
tianzhou merged 2 commits intomainfrom
fix/issue-295-pgvector-typmod
Feb 19, 2026
Merged

fix: preserve typmod for extension types in column type resolution (#295)#297
tianzhou merged 2 commits intomainfrom
fix/issue-295-pgvector-typmod

Conversation

@tianzhou
Copy link
Contributor

Summary

  • pgvector types with dimensions (e.g., vector(384), halfvec(384)) were losing their typmod during schema inspection because the resolved_type query only returned dt.typname for non-pg_catalog base types
  • Now extracts the typmod portion from format_type(atttypid, atttypmod) using a POSIX regex and appends it to the type name, preserving dimensions like vector(384) while maintaining existing schema qualification logic

Fixes #295

Test plan

  • Full test suite passes (go test ./...) — all packages green
  • Cross-schema extension type test (add_column_cross_schema_custom_type) passes — validates fix doesn't break existing citext/hstore handling
  • Manual validation with pgvector: create table with halfvec(384) column and HNSW index, verify pgschema plan preserves dimensions

🤖 Generated with Claude Code

)

pgvector types with dimensions (e.g., vector(384), halfvec(384)) were
losing their typmod during schema inspection. The resolved_type query
only returned dt.typname for non-pg_catalog base types, dropping the
typmod. Now extracts the typmod from format_type() and appends it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 19, 2026 04:25
@greptile-apps
Copy link

greptile-apps bot commented Feb 19, 2026

Greptile Summary

Fixed pgvector dimension loss by extracting typmod from format_type() for non-pg_catalog base types.

  • Modified column type resolution query to preserve type modifiers (e.g., vector(384)) for extension types
  • Uses POSIX regex '\([^)]*\)' to extract typmod portion from format_type(atttypid, atttypmod)
  • Applied to both same-schema and cross-schema extension type cases
  • Maintains existing behavior for pg_catalog types (varchar, numeric, etc.) which use separate character_maximum_length and numeric_precision fields
  • Generated Go code correctly reflects the SQL changes

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The change is surgical and well-targeted: it only modifies the type resolution logic for non-pg_catalog base types to preserve typmod. The regex pattern is simple and correct. Standard PostgreSQL types remain unchanged. The fix has been validated by existing test suite passing, and the generated Go code correctly reflects the SQL changes.
  • No files require special attention

Important Files Changed

Filename Overview
ir/queries/queries.sql Added typmod preservation for extension types using format_type() and regex extraction
ir/queries/queries.sql.go Generated Go code correctly reflects SQL query changes for typmod preservation

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Column Type Resolution] --> B{Type Category?}
    B -->|Domain/Enum/Composite| C[Use dt.typname with schema qualification]
    B -->|Array Base Type| D["Use et.typname + [] with schema qualification"]
    B -->|Non-Array Base Type| E{Schema Location?}
    E -->|pg_catalog| F["Use c.udt_name (Standard types handled separately)"]
    E -->|Same as table schema| G["dt.typname + extract typmod (Preserves vector(384))"]
    E -->|Different schema| H["schema.dt.typname + extract typmod (Preserves dimensions)"]
    G --> I["Typmod Extraction: substring(format_type FROM '([^)]*)')"]
    H --> I
    I --> J["Result: vector(384) or halfvec(384)"]
    F --> K["Result: varchar or numeric (Dimensions stored in separate fields)"]
Loading

Last reviewed commit: 73f0244

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes issue #295 where pgvector extension types with dimensions (e.g., vector(384), halfvec(384)) were losing their type modifiers (typmod) during schema inspection. The root cause was that the column type resolution query only returned the base type name (dt.typname) for non-pg_catalog types, without including the typmod information.

Changes:

  • Modified SQL queries to extract typmod from format_type(atttypid, atttypmod) using a POSIX regex pattern and append it to extension type names
  • Applied the fix consistently to both GetColumns and GetColumnsForSchema queries
  • Preserved existing schema qualification logic while adding typmod support for extension types

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
ir/queries/queries.sql Updated column type resolution logic in two queries (GetColumns and GetColumnsForSchema) to extract and preserve typmod for extension types using format_type() and regex extraction
ir/queries/queries.sql.go Generated Go code from the updated SQL queries (auto-generated by sqlc)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Add diff test case with setup.sql, old.sql, new.sql, and expected
outputs for pgvector halfvec(384) column with HNSW index. The test
is automatically skipped in CI since embedded-postgres doesn't
include pgvector. Add skipListRequiresExtension mechanism for tests
requiring third-party extensions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tianzhou tianzhou force-pushed the fix/issue-295-pgvector-typmod branch from 1c910b8 to aab0e24 Compare February 19, 2026 05:21
@tianzhou tianzhou merged commit 5034f4b into main Feb 19, 2026
1 check passed
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.

pgvector typmod lost: vector/halfvec dimensions dropped in plan/apply, causing HNSW index failure ("column does not have dimensions")

1 participant

Comments