8000 Bump libsqlite3-sys from 0.28 to 0.36 by ever0de · Pull Request #6472 · RustPython/RustPython · GitHub
[go: up one dir, main page]

Skip to content

Conversation

@ever0de
Copy link
Contributor
@ever0de ever0de commented Dec 23, 2025

Fixes #6471
close #6467
close #6368

Update libsqlite3-sys to version 0.36 and adapt to API changes by
replacing sqlite3_close_v2 with sqlite3_close. The v2 variant is no
longer directly exported in the newer version.

ref

Summary by CodeRabbit

  • Chores
    • Updated SQLite library dependency to version 0.36.
    • Adjusted internal SQLite API calls for improved compatibility with the latest library version.

✏️ Tip: You can customize this high-level summary in your review settings.

Update libsqlite3-sys to version 0.36 and adapt to API changes by
replacing sqlite3_close_v2 with sqlite3_close. The v2 variant is no
longer directly exported in the newer version.

Fixes RustPython#6471
@coderabbitai
Copy link
Contributor
coderabbitai bot commented Dec 23, 2025
📝 Walkthrough

Walkthrough

Updated libsqlite3-sys dependency from 0.28 to 0.36 and adjusted SQLite API usage to maintain compatibility: replaced sqlite3_close_v2 with sqlite3_close and removed explicit type casts from SQLITE_TRACE_STMT usage to align with the new library version's exported symbols.

Changes

Cohort / File(s) Summary
Dependency Update
crates/stdlib/Cargo.toml
Upgraded libsqlite3-sys from 0.28 to 0.36 in conditional target dependencies for non-Android and non-WASM builds
SQLite API Compatibility
crates/stdlib/src/sqlite.rs
Replaced sqlite3_close_v2 with sqlite3_close in extern imports and Drop implementation; removed explicit as u32 casts from SQLITE_TRACE_STMT constant usage in callback registration

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Suggested reviewers

  • youknowone

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Bump libsqlite3-sys from 0.28 to 0.36' directly and accurately summarizes the main change in the PR, which is updating the dependency version.
Linked Issues check ✅ Passed The PR successfully addresses issue #6471 by replacing sqlite3_close_v2 with sqlite3_close in crates/stdlib/src/sqlite.rs to resolve the compilation error caused by the libsqlite3-sys v0.36 API changes.
Out of Scope Changes check ✅ Passed All changes are directly related to the dependency upgrade and API adaptation required by libsqlite3-sys v0.36; no out-of-scope modifications are present.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
Contributor
@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

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec75888 and 6798c26.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • crates/stdlib/Cargo.toml
  • crates/stdlib/src/sqlite.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.rs: Follow the default rustfmt code style by running cargo fmt to format Rust code
Always run clippy to lint Rust code (cargo clippy) before completing tasks and fix any warnings or lints introduced by changes
Follow Rust best practices for error handling and memory management
Use the macro system (pyclass, pymodule, pyfunction, etc.) when implementing Python functionality in Rust

Files:

  • crates/stdlib/src/sqlite.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Run rust tests (ubuntu-latest)
  • GitHub Check: Run snippets and cpython tests (ubuntu-latest)
  • GitHub Check: Run snippets and cpython tests (macos-latest)
  • GitHub Check: Run snippets and cpython tests (windows-latest)
  • GitHub Check: Run rust tests (windows-latest)
  • GitHub Check: Run rust tests (macos-latest)
  • GitHub Check: Check the WASM package and demo
  • GitHub Check: Run snippets and cpython tests on wasm-wasi
  • GitHub Check: Ensure compilation on various targets
  • GitHub Check: Check Rust code with clippy
  • GitHub Check: Run tests under miri
🔇 Additional comments (3)
crates/stdlib/src/sqlite.rs (2)

33-33: LGTM! Import updated to match libsqlite3-sys v0.36 API.

The import correctly switches from sqlite3_close_v2 to sqlite3_close to align with the new library version's exported symbols.


1352-1359: LGTM! Type casts removed as SQLITE_TRACE_STMT now has the correct type.

The explicit as u32 casts are no longer needed because SQLITE_TRACE_STMT is now properly typed as c_uint in libsqlite3-sys v0.36. This improves type safety.

crates/stdlib/Cargo.toml (1)

135-135: The review comment's primary concern is incorrect. Web search confirms that sqlite3_close_v2 was not removed in libsqlite3-sys 0.36.0; the function remains available from the underlying SQLite library (added in SQLite 3.7.14). The code change to use sqlite3_close is a deliberate API choice, not an adaptation to removal.

The version bump from 0.28 to 0.36 is a standard update to the current stable release. v0.36.0 release notes document only additive changes: new bindings, hook-related code improvements, and a bump of the bundled SQLite to version 3.49.2—no breaking API removals.

Likely an incorrect or invalid review comment.

Comment on lines 2662 to 2665
impl Drop for Sqlite {
fn drop(&mut self) {
unsafe { sqlite3_close_v2(self.raw.db) };
unsafe { sqlite3_close(self.raw.db) };
}
Copy link
Contributor
@coderabbitai coderabbitai bot Dec 23, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for the Drop implementation and statement cleanup patterns

echo "=== Current Drop implementation for Sqlite ==="
rg -n -A5 'impl Drop for Sqlite' crates/stdlib/src/sqlite.rs

echo -e "\n=== Finding Statement creation and lifecycle management ==="
rg -n -B3 -A5 'struct SqliteStatement|fn new.*Statement' crates/stdlib/src/sqlite.rs | head -80

echo -e "\n=== Finding drop_db calls and connection closure ==="
rg -n -B2 -A8 'fn drop_db' crates/stdlib/src/sqlite.rs

echo -e "\n=== Checking cursor statement cleanup ==="
rg -n -B3 -A10 'impl Drop for Cursor' crates/stdlib/src/sqlite.rs

echo -e "\n=== Searching for Cursor close methods ==="
rg -n -B2 -A8 'fn close\(' crates/stdlib/src/sqlite.rs | head -80

Repository: RustPython/RustPython

Length of output: 2855


🏁 Script executed:

#!/bin/bash
# Search for Cursor struct definition and statement storage

echo "=== Finding Cursor struct definition ==="
rg -n -B5 -A20 'struct Cursor' crates/stdlib/src/sqlite.rs | head -100

echo -e "\n=== Finding how statements are stored/managed ==="
rg -n -B3 -A3 'description:|\.stmt|self\.stmt' crates/stdlib/src/sqlite.rs | head -100

echo -e "\n=== Finding execute methods that create statements ==="
rg -n -B2 -A15 'fn execute\(' crates/stdlib/src/sqlite.rs | head -150

echo -e "\n=== Search for statement finalization patterns ==="
rg -n 'sqlite3_finalize|finalize_stmt' crates/stdlib/src/sqlite.rs

Repository: RustPython/RustPython

Length of output: 3836


🏁 Script executed:

#!/bin/bash
# Get the complete Cursor.close() implementation
echo "=== Cursor close method complete implementation ==="
sed -n '1822,1860p' crates/stdlib/src/sqlite.rs

echo -e "\n=== Connection.drop_db() and its usage ==="
sed -n '941,950p' crates/stdlib/src/sqlite.rs

echo -e "\n=== Check if statements are cleaned up before drop_db ==="
rg -n -B10 'drop_db' crates/stdlib/src/sqlite.rs | grep -A10 -B10 'close\|drop_db'

echo -e "\n=== Check what Cursor has when close is called ==="
sed -n '1820,1860p' crates/stdlib/src/sqlite.rs

Repository: RustPython/RustPython

Length of output: 4200


🏁 Script executed:

#!/bin/bash
# Find Statement struct definition
echo "=== Finding Statement struct definition ==="
rg -n -B3 -A15 'struct Statement' crates/stdlib/src/sqlite.rs

echo -e "\n=== Check Statement::new implementation ==="
rg -n -B2 -A20 'impl Statement' crates/stdlib/src/sqlite.rs | head -100

echo -e "\n=== Verify if Statement holds connection reference ==="
rg -n 'struct Statement \{' -A20 crates/stdlib/src/sqlite.rs

Repository: RustPython/RustPython

Length of output: 2293


Ensure all cursors are closed before closing the connection, or use sqlite3_close_v2 to defer close until statements finalize.

The change from sqlite3_close_v2 to sqlite3_close introduces a resource leak risk:

  • sqlite3_close returns SQLITE_BUSY if unfinalized statements exist and fails silently in Drop
  • Connection.close() calls drop_db() immediately while active Cursor objects may still hold prepared statements
  • Statements only finalize when their owning Cursor is dropped, which may happen after the connection is dropped

Either:

  1. Ensure statements are explicitly finalized before Connection.close() is called
  2. Revert to sqlite3_close_v2 for more resilient cleanup semantics
  3. Add explicit statement cleanup in drop_db() before closing the connection

Copy link
Member

Choose a reason for hiding this comment

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

@ever0de Is this looking a correct review?

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Contributor Author
@ever0de ever0de Dec 24, 2025

Choose a reason for hiding this comment

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

I created comprehensive tests comparing CPython's behavior with RustPython when closing connections with active cursors. Both implementations behave identically - they successfully close the connection even when cursors remain active, and subsequent cursor operations properly raise ProgrammingError.

Investigation of sqlite3_close vs sqlite3_close_v2:
While CPython does use sqlite3_close_v2() for its deferred cleanup semantics, libsqlite3-sys intentionally removed sqlite3_close_v2 from its API in version 0.29.0 (rusqlite/rusqlite@4390720).

The commit message explicitly states:

Omit API

sqlite3_close_v2 (for gced languages)

The rationale is that sqlite3_close_v2 is specifically designed for garbage-collected languages where destructor order is non-deterministic. In Rust, with its deterministic RAII-based resource management, the v2 variant is unnecessary. The library maintainers deliberately chose to expose only sqlite3_close as the canonical close function for Rust applications.

This means the use of sqlite3_close() in this PR is not only necessary due to API constraints but also aligns with rusqlite's design philosophy.

Why it works safely:
Our implementation is safe because:

  1. The drop_db() method takes ownership via .take(), ensuring clean Drop trait execution
  2. Statement finalization happens through RAII when SqliteStatement is dropped
  3. The existing test suite (including the new tests I created) confirms proper cleanup behavior
  4. Rust's ownership system guarantees deterministic cleanup order, unlike garbage-collected languages

The current implementation matches CPython's observable behavior even though the internal mechanism differs due to library design decisions.

Copy link
Member

Choose a reason for hiding this comment

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

Thank you for confirming!

@youknowone youknowone merged commit 00205aa into RustPython:main Dec 24, 2025
13 checks 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.

Fix compilation error in libsqlite3-sys upgrade (#6467)

2 participants

0