Skip to content

fix(datasource-active-record): map inet/cidr/macaddr(8) columns to String - #377

Merged
matthv merged 2 commits into
mainfrom
fix/372-postgres-network-types
Aug 26, 2026
Merged

fix(datasource-active-record): map inet/cidr/macaddr(8) columns to String#377
matthv merged 2 commits into
mainfrom
fix/372-postgres-network-types

Conversation

@matthv

@matthv matthv commented Aug 26, 2026

Copy link
Copy Markdown
Member

What

Postgres network address column types (inet, cidr, macaddr, macaddr8) weren't in the TYPES map in column.rb, so they fell through to the unknown-type fallback. The fallback (String) was already correct, but it also logged a misleading INFO message on every schema generation, once per unmapped column: unknown type 'inet' for field named '...', 'String' type use by default.

Added the four types to TYPES, mirroring the existing Postgres-specific handling for citext/hstore/jsonb.

Why

Fixes #372.

How tested

  • New spec cases in column_spec.rb (one per type) asserting both the String mapping and that the logger is no longer invoked for these types.
  • Full forest_admin_datasource_active_record suite green locally (191 examples, 0 failures)
  • rubocop clean on the changed files

🤖 Generated with Claude Code

Note

Map Postgres inet, cidr, macaddr, and macaddr8 columns to String

Adds inet, cidr, macaddr, and macaddr8 to the TYPES mapping in column.rb so get_column_type returns 'String' for these Postgres types instead of falling into the unknown-type logging path. Adds parameterized tests in column_spec.rb verifying the mapping and that no unknown-type log is emitted.

Changes since #377 opened

  • Removed macaddr8 type mapping from the TYPES constant in ForestAdminDatasourceActiveRecord::Parser::Column and updated the corresponding spec [0995097]

Macroscope summarized c65ba85.

@qltysh

qltysh Bot commented Aug 26, 2026

Copy link
Copy Markdown

Qlty


Coverage Impact

This PR will not change total coverage.

🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@christophebrun-forest

Copy link
Copy Markdown
Member

macaddr8: 'String' is unreachable — #372 is only fixed for 3 of the 4 types

ActiveRecord never produces the :macaddr8 symbol. The type isn't registered anywhere, at either the class or the instance level:

$ grep -rn "macaddr8" activerecord-6.1.7.9/lib/ activerecord-8.1.3.1/lib/
(no match)

Verified empirically by resolving the real Postgres type map (PostgreSQLAdapter.initialize_type_map plus the three instance-level register_class_with_precision calls at postgresql_adapter.rb:758-765), on activerecord 8.1.3.1:

pg name resolved class .type
inet OID::Inet :inet
cidr OID::Cidr :cidr
macaddr OID::Macaddr :macaddr
macaddr8 ActiveModel::Type::Value nil

The path is deterministic: get_oid_typeload_additional_types only maps an OID when its typname is already a registered key (TypeMapInitializer#run: mapped = nodes.extract! { |row| @store.key? row["typname"] }). macaddr8 isn't, so type_map.fetch falls into the block → Type.default_valueValue#type returns nil.

Concrete effect on this branch. For a real macaddr8 column, TYPES.key?(nil) is false, so we still hit the else in column.rb:31-37 and log:

unknown type '' for field named 'device_mac', 'String' type use by default

Confirmed with a throwaway spec run against this branch (it passes):

column = instance_double(ActiveRecord::ConnectionAdapters::SQLite3::Column,
                         name: 'device_mac', type: nil)   # what the PG adapter actually reports
expect(dummy_class.get_column_type(User, column)).to eq 'String'
expect(logger).to have_received(:log).with(
  'Info', "unknown type '' for field named 'device_mac', 'String' type use by default"
)
# => 1 example, 0 failures

So the misleading INFO log survives for macaddr8, and it's now harder to diagnose than before the PR, since the type name renders empty.

Worth noting the reason this slipped through: the new spec injects type: :macaddr8, a value no adapter ever emits, so it validates the map key that was chosen rather than what the adapter reports. All four cases pass with equal confidence even though one of them is wrong. (inet, cidr and macaddr are all correct — I checked them against the real type map, and the citext/hstore/jsonb analogy in the description holds.)

Two ways to close it

(a) Simplest — drop the macaddr8 entry and remove it from the spec's %i[...] array, then note on #372 that ActiveRecord doesn't map this type, so there's nothing the datasource can key off.

(b) More general — fall back to sql_type when the type doesn't resolve. This covers macaddr8 plus every other unregistered Postgres type (tsrange, domain types, extension types):

def get_column_type(model, column)
  return 'Enum' if model.respond_to?(:defined_enums) && model.defined_enums.key?(column.name)

  is_array = column.respond_to?(:array) && column.array == true
  type = TYPES[column.type] || TYPES[sql_type_key(column)]

  unless type
    type = TYPES[:string]
    ForestAdminAgent::Facades::Container.logger.log(
      'Info',
      "unknown type '#{column.type || column.sql_type}' for field named '#{column.name}', " \
      "'#{TYPES[:string]}' type use by default"
    )
  end

  is_array ? [type] : type
end

private

def sql_type_key(column)
  return nil unless column.respond_to?(:sql_type) && column.sql_type

  column.sql_type.delete_suffix('[]').to_sym
end

The delete_suffix('[]') matters: for macaddr8[], sql_type is "macaddr8[]". (inet[] is already fine either way — OID::Array does delegate :type, to: :subtype, so column.type == :inet and this PR correctly yields ['String'].)

Everything else in the PR looks good: no behaviour change beyond the log (both branches already returned 'String'), and the new specs are genuine guards — removing the four TYPES entries makes all four fail on expect(logger).not_to have_received(:log).

@christophebrun-forest christophebrun-forest left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

IMO simple solution : delete macaddr8

matthv added a commit that referenced this pull request Aug 26, 2026
ActiveRecord's Postgres adapter never registers macaddr8: column.type
comes back nil for a real macaddr8 column (verified against the
installed activerecord gem), so TYPES[:macaddr8] could never be hit.
It still fell back to String via the unknown-type branch either way --
same runtime behavior as before this fix, just with a TYPES entry
that falsely implied the case was handled.

Found by @christophebrun-forest in review on #377. inet/cidr/macaddr
are confirmed registered and unaffected.

@christophebrun-forest christophebrun-forest left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

matthv added 2 commits August 26, 2026 15:38
Postgres inet/cidr/macaddr/macaddr8 columns fell through to the
unknown-type fallback, logging a misleading INFO message on every
schema generation even though the String fallback was already
correct. Mirrors the existing citext/hstore/jsonb handling.

Fixes #372
ActiveRecord's Postgres adapter never registers macaddr8: column.type
comes back nil for a real macaddr8 column (verified against the
installed activerecord gem), so TYPES[:macaddr8] could never be hit.
It still fell back to String via the unknown-type branch either way --
same runtime behavior as before this fix, just with a TYPES entry
that falsely implied the case was handled.

Found by @christophebrun-forest in review on #377. inet/cidr/macaddr
are confirmed registered and unaffected.
@matthv
matthv force-pushed the fix/372-postgres-network-types branch from 0995097 to c65ba85 Compare August 26, 2026 13:39
@matthv
matthv merged commit 487e056 into main Aug 26, 2026
56 checks passed
@matthv
matthv deleted the fix/372-postgres-network-types branch August 26, 2026 13:47
forest-bot added a commit that referenced this pull request Aug 26, 2026
## [1.39.4](v1.39.3...v1.39.4) (2026-08-26)

### Bug Fixes

* **datasource-active-record:** map inet/cidr/macaddr(8) columns to String ([#377](#377)) ([487e056](487e056)), closes [#372](#372)
@forest-bot

Copy link
Copy Markdown
Member

🎉 This PR is included in version 1.39.4 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Postgres inet/cidr/macaddr columns fall through to the "unknown type" INFO log; should map to String

3 participants