Skip to content

Fix: register bigint as an 8-byte integer to fix RangeError on bigint columns - #30

Merged
kou merged 2 commits into
red-data-tools:mainfrom
otegami:fix/duckdb-bigint-range-error
Aug 3, 2026
Merged

Fix: register bigint as an 8-byte integer to fix RangeError on bigint columns#30
kou merged 2 commits into
red-data-tools:mainfrom
otegami:fix/duckdb-bigint-range-error

Conversation

@otegami

@otegami otegami commented Jul 31, 2026

Copy link
Copy Markdown
Member

The CI has failed about DuckDB since 2026-06-21 as follows.

Error: test_bigint_active_record(TestType): ActiveModel::RangeError:
4294967296 is out of range for ActiveModel::Type::Integer with limit 4 bytes

ref: https://github.com/red-data-tools/activerecord-adbc-adapter/actions/runs/27942838514/job/82680163239?pr=29#step:10:1

Cause

DuckDB 1.5.4 started reporting xdbc_type_name. It was nil in DuckDB 1.5.3,
so no cast type was resolved at all.

ref: duckdb/duckdb#23110

So new_column_from_field now resolves a cast type from xdbc_type_name. We
don't override the type map, so that lookup goes like this.

  1. BIGINT matches AbstractAdapter's only integer entry,
    register_class_with_limit m, %r(int)i, Type::Integer.
  2. register_class_with_limit takes the limit from extract_limit, which
    only reads digits inside (...).
  3. BIGINT has no (...), so the limit is nil and Type::Integer falls
    back to DEFAULT_LIMIT = 4.
  4. 4 bytes allows up to 1 << (4 * 8 - 1), so writing 2 ** 32 raises.

PostgreSQL is in the same state for the same reason. Its ADBC driver reports
typ.typname, which is int8 for both bigint and bigserial, and int8
has no (...) either.

SQLite is safe by accident: our DDL emits bigint(8), so step 2 finds the 8.

Fix

Register bigint and int8 as 8 bytes, like PostgreSQLAdapter does for
int8. Both names mean 8 bytes on all three backends. An explicit 'limit:'
still wins, so t.bigint :x, limit: 4 keeps resolving to 4 bytes in SQLite.

@otegami
otegami marked this pull request as draft July 31, 2026 12:26
@otegami otegami changed the title Fix: register bigint as an 8-byte integer to fix RangeError on DuckDB Fix: register bigint as an 8-byte integer to fix RangeError on bigint columns Jul 31, 2026
@otegami
otegami force-pushed the fix/duckdb-bigint-range-error branch from b0a4771 to 5e4456e Compare July 31, 2026 12:48
@otegami
otegami marked this pull request as ready for review July 31, 2026 12:55
Comment thread test/test_type.rb Outdated
Comment on lines +27 to +28
User.create!(bigint: 2 ** 62)
assert_equal(User.new(id: 1, bigint: 2 ** 62),

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.

Why do we need these changes? I think that both of 2 ** 32 and 2 ** 64 are int64 range. (They are out of int32 range.)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I've reverted this change because it was not necessary, as you mentioned.
I changed it because I initially wanted a test value that needed 8 bytes.
But both are out of the int32 range and within the int64 range, so the change was unnecessary.

private
def initialize_type_map(m)
super
m.register_type(/\A(?:bigint|int8)\b/i) do |sql_type|

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.

Could you add a comment why we need this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

fix: 3ae5738 I added the comment here.

otegami added 2 commits August 1, 2026 17:31
The CI has failed about DuckDB since 2026-06-21 as follows.

```
Error: test_bigint_active_record(TestType): ActiveModel::RangeError:
4294967296 is out of range for ActiveModel::Type::Integer with limit 4 bytes
```

ref: https://github.com/red-data-tools/activerecord-adbc-adapter/actions/runs/27942838514/job/82680163239?pr=29#step:10:1

### Cause

DuckDB 1.5.4 started reporting `xdbc_type_name`. It was nil in DuckDB 1.5.3,
so no cast type was resolved at all.

ref: duckdb/duckdb#23110

So `new_column_from_field` now resolves a cast type from `xdbc_type_name`. We
don't override the type map, so that lookup goes like this.

1. `BIGINT` matches AbstractAdapter's only integer entry,
   `register_class_with_limit m, %r(int)i, Type::Integer`.
2. `register_class_with_limit` takes the limit from `extract_limit`, which
   only reads digits inside `(...)`.
3. `BIGINT` has no `(...)`, so the limit is nil and `Type::Integer` falls
   back to `DEFAULT_LIMIT = 4`.
4. 4 bytes allows up to `1 << (4 * 8 - 1)`, so writing `2 ** 32` raises.

PostgreSQL is in the same state for the same reason. Its ADBC driver reports
`typ.typname`, which is `int8` for both `bigint` and `bigserial`, and `int8`
has no `(...)` either.

SQLite is safe by accident: our DDL emits `bigint(8)`, so step 2 finds the 8.

### Fix

Register `bigint` and `int8` as 8 bytes, like PostgreSQLAdapter does for
`int8`. Both names mean 8 bytes on all three backends. An explicit `limit:`
still wins, so `t.bigint :x, limit: 4` keeps resolving to 4 bytes in SQLite.
`\b` keeps PostgreSQL's `int8range` and `_int8` out.
@otegami
otegami force-pushed the fix/duckdb-bigint-range-error branch from 5e4456e to 3ae5738 Compare August 3, 2026 11:06

@otegami otegami left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thank you for reviewing. I've just addressed all of them.

@otegami
otegami requested a review from kou August 3, 2026 11:17
@kou
kou merged commit d79f1de into red-data-tools:main Aug 3, 2026
4 checks passed
@kou

kou commented Aug 3, 2026

Copy link
Copy Markdown
Member

Thanks.

@otegami
otegami deleted the fix/duckdb-bigint-range-error branch August 3, 2026 12:50
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.

2 participants