asg017 / sqlite-regex

A fast regular expression SQLite extension, written in Rust
Apache License 2.0
160 stars 7 forks source link

Override `fts5`? #22

Open xuxiaocheng0201 opened 3 months ago

xuxiaocheng0201 commented 3 months ago

When I was loading this extension, the fts5 function was missing.

Used sqlite3_auto_extension in rusqlite

Dependencies

anyhow = "^1.0"
rusqlite = { version = "~0.31", features = ["bundled"] }
sqlite-regex = "0.2.4-alpha.1"

Code

use std::ffi::{c_char, c_int};

use anyhow::Result;
use rusqlite::Connection;
use rusqlite::ffi::{sqlite3, sqlite3_api_routines, sqlite3_auto_extension, SQLITE_OK};

fn main() -> Result<()> {
    unsafe extern "C" fn regex(db: *mut sqlite3, pz_err_msg: *mut *const c_char, p_api: *const sqlite3_api_routines) -> c_int {
        sqlite_regex::sqlite3_regex_init(db as _, pz_err_msg as _, p_api as _) as _
    }
    unsafe {
        assert_eq!(sqlite3_auto_extension(Some(regex)), SQLITE_OK);
    };
    let connection = Connection::open_in_memory()?;
    connection.prepare("SELECT fts5(?1)")?;
    Ok(())
}

But when I comment out these lines:

    unsafe {
        assert_eq!(sqlite3_auto_extension(Some(regex)), SQLITE_OK);
    };

it works.

Is there any error in my code? I'm curious why, these should be two unrelated extensions.

xuxiaocheng0201 commented 3 months ago

Output

Error: no such function: fts5 in SELECT fts5(?1) at offset 7

Caused by:
    Error code 1: SQL error or missing database

I also tested sqlite-regex = "0.2.3", but the same error.

asg017 commented 3 months ago

Oooh that's not good. I think this has to do with a bug from a previous version of sqlite-regex, where it would accidentally link it's own version of sqlite3 instead of what rusqlite created. I thought it was fixed in 0.2.4-alpha.1.

I'm having trouble reproducing - I ran what you have but it seemed to work fine. A few questions:

Thanks for reporting!

xuxiaocheng0201 commented 3 months ago

I just run cargo clean, but unfortunately it output the same error.

The sqlite_version() is 3.39.4. I searched the source codes, it's in sqlite3ext-sys.

I cloned your two repositories, it works. and the sqlite_version() is 3.45.0

asg017 commented 3 months ago

Ok cool, thanks for the info! So it does appear to be the issue I alluded to earlier - the 3.39.4 version definitely comes from sqlite3ext-sys, which should not be linked to in this case. That linked sqlite3 version also probably doesn't compile in the fts5 extension, which is causing the original error you reported here.

The sqlite-loadable crate is what depends on sqlite3ext-sys. However, when the static feature is enabled, it instead links to libsqlite3-sys. So the goal should be to enable the static feature on sqlite-loadable, which avoids sqlite3ext-sys and won't overwrite the sqlite3 linking.

Could you try something like this in your Cargo.toml?

sqlite-loadable = { version = "0.0.6-alpha.6", features=["static"]}

I tried this locally but ran into some version conflicts. Might need to push a new update to sqlite-regex for a proper fix

xuxiaocheng0201 commented 3 months ago

I encountered the same version conflicts.

error: failed to select a version for `libsqlite3-sys`.
    ... required by package `sqlite-loadable v0.0.6-alpha.6`
    ... which satisfies dependency `sqlite-loadable = "^0.0.6-alpha.6"` (locked to 0.0.6-alpha.6) of package `tester v0.1.0 (D:\Projects\tester)`
versions that meet the requirements `^0.26.0` are: 0.26.0

the package `libsqlite3-sys` links to the native library `sqlite3`, but it conflicts with a previous package which links to `sqlite3` as well:
package `libsqlite3-sys v0.28.0`
    ... which satisfies dependency `libsqlite3-sys = "^0.28.0"` (locked to 0.28.0) of package `rusqlite v0.31.0`
    ... which satisfies dependency `rusqlite = "~0.31"` (locked to 0.31.0) of package `tester v0.1.0 (D:\Projects\tester)`
Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the `links = "sqlite3"` value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.

failed to select a version for `libsqlite3-sys` which could resolve this conflict
xuxiaocheng0201 commented 2 months ago

Hi, I created a PR that may fix the conflicts. I hope you can merge it.