Skip to content

Support TIMESTAMP column writing Ruby Time object in DataChunk#set_value#1124

Merged
suketa merged 3 commits intomainfrom
memory_helper_support_timestamp
Mar 2, 2026
Merged

Support TIMESTAMP column writing Ruby Time object in DataChunk#set_value#1124
suketa merged 3 commits intomainfrom
memory_helper_support_timestamp

Conversation

@suketa
Copy link
Owner

@suketa suketa commented Mar 2, 2026

Summary

Support writing Ruby Time objects to TIMESTAMP columns via DuckDB::DataChunk#set_value.

Changes

  • ext/duckdb/memory_helper.c: Add MemoryHelper.write_timestamp C method that converts a Ruby Time object to a duckdb_timestamp. It calls .getlocal on the input first to extract local-time components, matching the read convention of Converter#_to_time which uses Time.local.
  • lib/duckdb/data_chunk.rb: Add :timestamp case in DataChunk#set_value to call MemoryHelper.write_timestamp.
  • test/duckdb_test/data_chunk_test.rb: Add test_data_chunk_set_value_timestamp to verify round-trip of two Time values through a table function.
  • CHANGELOG.md: Document the new feature.

Example

table_function.bind do |bind_info|
  bind_info.add_result_column('ts', DuckDB::LogicalType::TIMESTAMP)
end

table_function.execute do |_func_info, output|
  output.set_value(0, 0, Time.new(2024, 3, 15, 10, 30, 45))
  output.size = 1
end

Summary by CodeRabbit

  • New Features

    • TIMESTAMP Support: Ruby Time objects can now be written directly to DuckDB TIMESTAMP columns, with correct timezone handling and UTC storage.
  • Tests

    • Added test coverage for TIMESTAMP column write operations to validate correct UTC handling across time values.

- Add MemoryHelper.write_timestamp C method that converts a Ruby Time
  object to duckdb_timestamp using local time components (matching the
  read convention of Converter#_to_time which uses Time.local)
- Add :timestamp case in DataChunk#set_value to call write_timestamp
- Add test_data_chunk_set_value_timestamp to verify round-trip

Co-authored-by: Copilot <[email protected]>
@coderabbitai
Copy link

coderabbitai bot commented Mar 2, 2026

Warning

Rate limit exceeded

@suketa has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 0 minutes and 40 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between fc85387 and 522e735.

📒 Files selected for processing (1)
  • sample/issue922.rb
📝 Walkthrough

Walkthrough

Adds TIMESTAMP write support to the Ruby bindings: a C-level MemoryHelper.write_timestamp that converts Ruby Time to DuckDB timestamp in raw memory, and a :timestamp branch in DataChunk#set_value; tests and changelog entries were added.

Changes

Cohort / File(s) Summary
Changelog
CHANGELOG.md
Added Unreleased notes for TIMESTAMP column writing and MemoryHelper.write_timestamp.
Native extension
ext/duckdb/memory_helper.c
New rbduckdb_memory_helper_write_timestamp singleton method that validates a Time, converts it to DuckDB timestamp, and writes it into provided memory/index.
Ruby binding
lib/duckdb/data_chunk.rb
Added :timestamp handling in DataChunk#set_value that retrieves the data buffer and calls MemoryHelper.write_timestamp.
Tests
test/duckdb_test/data_chunk_test.rb
Added test_data_chunk_set_value_timestamp to exercise TIMESTAMP set_value; note: the test block appears duplicated.
Sample
sample/issue922.rb
Minor namespace syntax change from :: to . when creating a Polars DataFrame (no functional effect).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰
I hop through buffers, nimble and spry,
Ruby Time in paw, I give timestamps a try.
Into DuckDB memory I gently write,
Rows tick true, morning to night.
A tiny hop for code, a joyful byte.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding support for writing Ruby Time objects to TIMESTAMP columns in DataChunk#set_value, which is the primary feature across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch memory_helper_support_timestamp

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
test/duckdb_test/data_chunk_test.rb (1)

376-397: Add one non-UTC timestamp case to harden timezone coverage.

This test is good; adding a non-UTC Time input will better guard the conversion path.

Suggested test strengthening
       time1 = Time.new(2024, 3, 15, 10, 30, 45, '+00:00')
       time2 = Time.new(2000, 1, 1, 0, 0, 0, '+00:00')
+      time3 = Time.new(2024, 3, 15, 10, 30, 45, '+09:00')
@@
           output.set_value(0, 0, time1)
           output.set_value(0, 1, time2)
-          output.size = 2
+          output.set_value(0, 2, time3)
+          output.size = 3
           done = true
         end
       end
@@
-      assert_equal 2, rows.length
+      assert_equal 3, rows.length
       assert_equal time1.utc, rows[0].first.utc
       assert_equal time2.utc, rows[1].first.utc
+      assert_equal time3.utc, rows[2].first.utc
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/duckdb_test/data_chunk_test.rb` around lines 376 - 397, Add a third
timestamp with a non-UTC offset (e.g., Time.new(..., '+05:30')) to the test to
exercise timezone conversion: create a new variable (e.g., time3) alongside
time1/time2, set it into the table_function output in table_function.execute
(use output.set_value for the appropriate row/column index and increment
output.size), register the table function and query test_set_value_timestamp(),
then assert the returned row for that new entry matches time3.utc (use the same
pattern as the existing assertions). Ensure you reference the existing symbols
time1, time2, table_function.execute, output.set_value,
`@conn.register_table_function`, and test_set_value_timestamp to locate where to
insert the new case.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/duckdb_test/data_chunk_test.rb`:
- Around line 376-397: Add a third timestamp with a non-UTC offset (e.g.,
Time.new(..., '+05:30')) to the test to exercise timezone conversion: create a
new variable (e.g., time3) alongside time1/time2, set it into the table_function
output in table_function.execute (use output.set_value for the appropriate
row/column index and increment output.size), register the table function and
query test_set_value_timestamp(), then assert the returned row for that new
entry matches time3.utc (use the same pattern as the existing assertions).
Ensure you reference the existing symbols time1, time2, table_function.execute,
output.set_value, `@conn.register_table_function`, and test_set_value_timestamp to
locate where to insert the new case.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e891455 and 4b8336e.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • ext/duckdb/memory_helper.c
  • lib/duckdb/data_chunk.rb
  • test/duckdb_test/data_chunk_test.rb

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@sample/issue922.rb`:
- Line 38: The code calls the nonexistent symbol polars.dataframe.new which will
raise NameError; replace that call with the correct constant/class constructor
Polars::DataFrame.new(...) (capitalize Polars and use :: to reference the
DataFrame class) so the code invokes the Polars::DataFrame constructor instead
of trying to call undefined methods like polars or dataframe.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b8336e and fc85387.

📒 Files selected for processing (1)
  • sample/issue922.rb

@suketa suketa merged commit a8f18e1 into main Mar 2, 2026
39 of 41 checks passed
@suketa suketa deleted the memory_helper_support_timestamp branch March 2, 2026 11:12
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.

1 participant