mirror of
https://github.com/tursodatabase/limbo.git
synced 2025-12-23 08:21:09 +00:00
Merge 'SQLite C API improvements' from Nikita Sivukhin
Some checks are pending
Build and push limbo-sim image / deploy (push) Waiting to run
C compat Tests / test (push) Waiting to run
Dart/Flutter / test (blacksmith-4vcpu-ubuntu-2404) (push) Waiting to run
Dart/Flutter / test (windows-latest) (push) Waiting to run
Dart/Flutter / precompile (blacksmith-4vcpu-ubuntu-2404) (push) Waiting to run
Dart/Flutter / precompile (macOS-latest) (push) Waiting to run
Dart/Flutter / precompile (windows-latest) (push) Waiting to run
Dart/Flutter / publish (push) Waiting to run
Run long fuzz tests and stress test / run-fuzz-tests (push) Waiting to run
Run long fuzz tests and stress test / run-long-fuzz-tests (push) Waiting to run
Run long fuzz tests and stress test / simple-stress-test (push) Waiting to run
Java Tests / test (push) Waiting to run
Build & publish @tursodatabase/database / db-bindings-aarch64-apple-darwin - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / db-bindings-aarch64-unknown-linux-gnu - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / db-bindings-wasm32-wasip1-threads - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / db-bindings-x86_64-pc-windows-msvc - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / db-bindings-x86_64-unknown-linux-gnu - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-wasm32-wasip1-threads - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-aarch64-apple-darwin - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-aarch64-unknown-linux-gnu - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-x86_64-pc-windows-msvc - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-x86_64-unknown-linux-gnu - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / Test DB bindings on Linux-x64-gnu - node@20 (push) Blocked by required conditions
Build & publish @tursodatabase/database / Test DB bindings on browser@20 (push) Blocked by required conditions
Build & publish @tursodatabase/database / Publish (push) Blocked by required conditions
Python / sdist (push) Waiting to run
Python / Release (push) Blocked by required conditions
Python / configure-strategy (push) Waiting to run
Python / test (push) Blocked by required conditions
Python / lint (push) Waiting to run
Python / linux (x86_64) (push) Waiting to run
Python / macos-arm64 (aarch64) (push) Waiting to run
Rust / cargo-fmt-check (push) Waiting to run
Rust / build-native (blacksmith-4vcpu-ubuntu-2404) (push) Waiting to run
Rust / build-native (macos-latest) (push) Waiting to run
Rust / build-native (windows-latest) (push) Waiting to run
Rust / clippy (push) Waiting to run
Rust / simulator (push) Waiting to run
Rust / test-limbo (push) Waiting to run
Rust / test-sqlite (push) Waiting to run
Rust Benchmarks+Nyrkiö / bench (push) Waiting to run
Rust Benchmarks+Nyrkiö / clickbench (push) Waiting to run
Rust Benchmarks+Nyrkiö / tpc-h-criterion (push) Waiting to run
Rust Benchmarks+Nyrkiö / tpc-h (push) Waiting to run
Rust Benchmarks+Nyrkiö / vfs-bench-compile (push) Waiting to run
Some checks are pending
Build and push limbo-sim image / deploy (push) Waiting to run
C compat Tests / test (push) Waiting to run
Dart/Flutter / test (blacksmith-4vcpu-ubuntu-2404) (push) Waiting to run
Dart/Flutter / test (windows-latest) (push) Waiting to run
Dart/Flutter / precompile (blacksmith-4vcpu-ubuntu-2404) (push) Waiting to run
Dart/Flutter / precompile (macOS-latest) (push) Waiting to run
Dart/Flutter / precompile (windows-latest) (push) Waiting to run
Dart/Flutter / publish (push) Waiting to run
Run long fuzz tests and stress test / run-fuzz-tests (push) Waiting to run
Run long fuzz tests and stress test / run-long-fuzz-tests (push) Waiting to run
Run long fuzz tests and stress test / simple-stress-test (push) Waiting to run
Java Tests / test (push) Waiting to run
Build & publish @tursodatabase/database / db-bindings-aarch64-apple-darwin - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / db-bindings-aarch64-unknown-linux-gnu - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / db-bindings-wasm32-wasip1-threads - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / db-bindings-x86_64-pc-windows-msvc - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / db-bindings-x86_64-unknown-linux-gnu - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-wasm32-wasip1-threads - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-aarch64-apple-darwin - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-aarch64-unknown-linux-gnu - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-x86_64-pc-windows-msvc - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / sync-bindings-x86_64-unknown-linux-gnu - node@20 (push) Waiting to run
Build & publish @tursodatabase/database / Test DB bindings on Linux-x64-gnu - node@20 (push) Blocked by required conditions
Build & publish @tursodatabase/database / Test DB bindings on browser@20 (push) Blocked by required conditions
Build & publish @tursodatabase/database / Publish (push) Blocked by required conditions
Python / sdist (push) Waiting to run
Python / Release (push) Blocked by required conditions
Python / configure-strategy (push) Waiting to run
Python / test (push) Blocked by required conditions
Python / lint (push) Waiting to run
Python / linux (x86_64) (push) Waiting to run
Python / macos-arm64 (aarch64) (push) Waiting to run
Rust / cargo-fmt-check (push) Waiting to run
Rust / build-native (blacksmith-4vcpu-ubuntu-2404) (push) Waiting to run
Rust / build-native (macos-latest) (push) Waiting to run
Rust / build-native (windows-latest) (push) Waiting to run
Rust / clippy (push) Waiting to run
Rust / simulator (push) Waiting to run
Rust / test-limbo (push) Waiting to run
Rust / test-sqlite (push) Waiting to run
Rust Benchmarks+Nyrkiö / bench (push) Waiting to run
Rust Benchmarks+Nyrkiö / clickbench (push) Waiting to run
Rust Benchmarks+Nyrkiö / tpc-h-criterion (push) Waiting to run
Rust Benchmarks+Nyrkiö / tpc-h (push) Waiting to run
Rust Benchmarks+Nyrkiö / vfs-bench-compile (push) Waiting to run
This PR adds rich error codes for sqlite3 C bridge layer and also do few minor adjustments: 1. Enable indices by default 2. Return debug logs to the stderr Closes #3999
This commit is contained in:
commit
d2fc52834a
1 changed files with 66 additions and 36 deletions
|
|
@ -14,19 +14,42 @@ macro_rules! stub {
|
|||
};
|
||||
}
|
||||
|
||||
pub const SQLITE_OK: ffi::c_int = 0;
|
||||
pub const SQLITE_ERROR: ffi::c_int = 1;
|
||||
pub const SQLITE_ABORT: ffi::c_int = 4;
|
||||
pub const SQLITE_BUSY: ffi::c_int = 5;
|
||||
pub const SQLITE_NOMEM: ffi::c_int = 7;
|
||||
pub const SQLITE_INTERRUPT: ffi::c_int = 9;
|
||||
pub const SQLITE_NOTFOUND: ffi::c_int = 12;
|
||||
pub const SQLITE_CANTOPEN: ffi::c_int = 14;
|
||||
pub const SQLITE_MISUSE: ffi::c_int = 21;
|
||||
pub const SQLITE_RANGE: ffi::c_int = 25;
|
||||
pub const SQLITE_ROW: ffi::c_int = 100;
|
||||
pub const SQLITE_DONE: ffi::c_int = 101;
|
||||
/* generic error-codes */
|
||||
pub const SQLITE_OK: ffi::c_int = 0; /* Successful result */
|
||||
pub const SQLITE_ERROR: ffi::c_int = 1; /* Generic error */
|
||||
pub const SQLITE_INTERNAL: ffi::c_int = 2; /* Internal logic error in SQLite */
|
||||
pub const SQLITE_PERM: ffi::c_int = 3; /* Access permission denied */
|
||||
pub const SQLITE_ABORT: ffi::c_int = 4; /* Callback routine requested an abort */
|
||||
pub const SQLITE_BUSY: ffi::c_int = 5; /* The database file is locked */
|
||||
pub const SQLITE_LOCKED: ffi::c_int = 6; /* A table in the database is locked */
|
||||
pub const SQLITE_NOMEM: ffi::c_int = 7; /* A malloc() failed */
|
||||
pub const SQLITE_READONLY: ffi::c_int = 8; /* Attempt to write a readonly database */
|
||||
pub const SQLITE_INTERRUPT: ffi::c_int = 9; /* Operation terminated by sqlite3_interrupt()*/
|
||||
pub const SQLITE_IOERR: ffi::c_int = 10; /* Some kind of disk I/O error occurred */
|
||||
pub const SQLITE_CORRUPT: ffi::c_int = 11; /* The database disk image is malformed */
|
||||
pub const SQLITE_NOTFOUND: ffi::c_int = 12; /* Unknown opcode in sqlite3_file_control() */
|
||||
pub const SQLITE_FULL: ffi::c_int = 13; /* Insertion failed because database is full */
|
||||
pub const SQLITE_CANTOPEN: ffi::c_int = 14; /* Unable to open the database file */
|
||||
pub const SQLITE_PROTOCOL: ffi::c_int = 15; /* Database lock protocol error */
|
||||
pub const SQLITE_EMPTY: ffi::c_int = 16; /* Internal use only */
|
||||
pub const SQLITE_SCHEMA: ffi::c_int = 17; /* The database schema changed */
|
||||
pub const SQLITE_TOOBIG: ffi::c_int = 18; /* String or BLOB exceeds size limit */
|
||||
pub const SQLITE_CONSTRAINT: ffi::c_int = 19; /* Abort due to constraint violation */
|
||||
pub const SQLITE_MISMATCH: ffi::c_int = 20; /* Data type mismatch */
|
||||
pub const SQLITE_MISUSE: ffi::c_int = 21; /* Library used incorrectly */
|
||||
pub const SQLITE_NOLFS: ffi::c_int = 22; /* Uses OS features not supported on host */
|
||||
pub const SQLITE_AUTH: ffi::c_int = 23; /* Authorization denied */
|
||||
pub const SQLITE_FORMAT: ffi::c_int = 24; /* Not used */
|
||||
pub const SQLITE_RANGE: ffi::c_int = 25; /* 2nd parameter to sqlite3_bind out of range */
|
||||
pub const SQLITE_NOTADB: ffi::c_int = 26; /* File opened that is not a database file */
|
||||
pub const SQLITE_NOTICE: ffi::c_int = 27; /* Notifications from sqlite3_log() */
|
||||
pub const SQLITE_WARNING: ffi::c_int = 28; /* Warnings from sqlite3_log() */
|
||||
pub const SQLITE_ROW: ffi::c_int = 100; /* sqlite3_step() has another row ready */
|
||||
pub const SQLITE_DONE: ffi::c_int = 101; /* sqlite3_step() has finished executing */
|
||||
|
||||
/* extended error-codes */
|
||||
pub const SQLITE_ABORT_ROLLBACK: ffi::c_int = SQLITE_ABORT | (2 << 8);
|
||||
|
||||
pub const SQLITE_STATE_OPEN: u8 = 0x76;
|
||||
pub const SQLITE_STATE_SICK: u8 = 0xba;
|
||||
pub const SQLITE_STATE_BUSY: u8 = 0x6d;
|
||||
|
|
@ -39,7 +62,6 @@ pub const SQLITE_CHECKPOINT_TRUNCATE: ffi::c_int = 3;
|
|||
pub const SQLITE_INTEGER: ffi::c_int = 1;
|
||||
pub const SQLITE_FLOAT: ffi::c_int = 2;
|
||||
pub const SQLITE_TEXT: ffi::c_int = 3;
|
||||
pub const SQLITE3_TEXT: ffi::c_int = 3;
|
||||
pub const SQLITE_BLOB: ffi::c_int = 4;
|
||||
pub const SQLITE_NULL: ffi::c_int = 5;
|
||||
|
||||
|
|
@ -161,7 +183,7 @@ pub unsafe extern "C" fn sqlite3_open(
|
|||
Err(_) => return SQLITE_CANTOPEN,
|
||||
},
|
||||
};
|
||||
match turso_core::Database::open_file(io.clone(), filename_str, false, false) {
|
||||
match turso_core::Database::open_file(io.clone(), filename_str, false, true) {
|
||||
Ok(db) => {
|
||||
let conn = db.connect().unwrap();
|
||||
let filename = match filename_str {
|
||||
|
|
@ -288,9 +310,10 @@ pub unsafe extern "C" fn sqlite3_prepare_v2(
|
|||
};
|
||||
let stmt = match db.conn.prepare(sql) {
|
||||
Ok(stmt) => stmt,
|
||||
Err(_) => {
|
||||
db.err_code = SQLITE_ERROR;
|
||||
return SQLITE_ERROR;
|
||||
Err(err) => {
|
||||
let code = handle_limbo_err(err, std::ptr::null_mut());
|
||||
db.err_code = code;
|
||||
return code;
|
||||
}
|
||||
};
|
||||
let new_stmt = Box::leak(Box::new(sqlite3_stmt::new(raw_db, stmt)));
|
||||
|
|
@ -344,8 +367,8 @@ pub unsafe extern "C" fn sqlite3_step(stmt: *mut sqlite3_stmt) -> ffi::c_int {
|
|||
let db = &mut *stmt.db;
|
||||
loop {
|
||||
let _db = db.inner.lock().unwrap();
|
||||
if let Ok(result) = stmt.stmt.step() {
|
||||
match result {
|
||||
match stmt.stmt.step() {
|
||||
Ok(result) => match result {
|
||||
turso_core::StepResult::IO => {
|
||||
stmt.stmt.run_once().unwrap();
|
||||
continue;
|
||||
|
|
@ -360,9 +383,8 @@ pub unsafe extern "C" fn sqlite3_step(stmt: *mut sqlite3_stmt) -> ffi::c_int {
|
|||
return SQLITE_ROW;
|
||||
}
|
||||
turso_core::StepResult::Busy => return SQLITE_BUSY,
|
||||
}
|
||||
} else {
|
||||
return SQLITE_ERROR;
|
||||
},
|
||||
Err(err) => return handle_limbo_err(err, std::ptr::null_mut()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -412,11 +434,7 @@ pub unsafe extern "C" fn sqlite3_exec(
|
|||
match db_inner.conn.execute(trimmed) {
|
||||
Ok(_) => continue,
|
||||
Err(e) => {
|
||||
if !err.is_null() {
|
||||
let err_msg = format!("SQL error: {e:?}");
|
||||
*err = CString::new(err_msg).unwrap().into_raw();
|
||||
}
|
||||
return SQLITE_ERROR;
|
||||
return handle_limbo_err(e, err);
|
||||
}
|
||||
}
|
||||
} else if callback.is_none() {
|
||||
|
|
@ -964,7 +982,6 @@ pub unsafe extern "C" fn sqlite3_bind_double(
|
|||
idx: ffi::c_int,
|
||||
val: f64,
|
||||
) -> ffi::c_int {
|
||||
println!("Bind Double Rust");
|
||||
if stmt.is_null() {
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
|
|
@ -1801,7 +1818,6 @@ pub unsafe extern "C" fn sqlite3_wal_checkpoint_v2(
|
|||
SQLITE_OK
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Checkpoint error: {e}");
|
||||
if matches!(e, turso_core::LimboError::Busy) {
|
||||
SQLITE_BUSY
|
||||
} else {
|
||||
|
|
@ -1946,13 +1962,10 @@ pub unsafe extern "C" fn libsql_wal_disable_checkpoint(db: *mut sqlite3) -> ffi:
|
|||
}
|
||||
|
||||
fn sqlite3_safety_check_sick_or_ok(db: &sqlite3Inner) -> bool {
|
||||
match db.e_open_state {
|
||||
SQLITE_STATE_SICK | SQLITE_STATE_OPEN | SQLITE_STATE_BUSY => true,
|
||||
_ => {
|
||||
eprintln!("Invalid database state: {}", db.e_open_state);
|
||||
false
|
||||
}
|
||||
}
|
||||
matches!(
|
||||
db.e_open_state,
|
||||
SQLITE_STATE_SICK | SQLITE_STATE_OPEN | SQLITE_STATE_BUSY
|
||||
)
|
||||
}
|
||||
|
||||
// https://sqlite.org/c3ref/table_column_metadata.html
|
||||
|
|
@ -2096,3 +2109,20 @@ pub unsafe extern "C" fn sqlite3_table_column_metadata(
|
|||
|
||||
rc
|
||||
}
|
||||
|
||||
fn handle_limbo_err(err: LimboError, container: *mut *mut ffi::c_char) -> i32 {
|
||||
if !container.is_null() {
|
||||
let err_msg = format!("{err}");
|
||||
unsafe { *container = CString::new(err_msg).unwrap().into_raw() };
|
||||
}
|
||||
match err {
|
||||
LimboError::Corrupt(..) => SQLITE_CORRUPT,
|
||||
LimboError::NotADB => SQLITE_NOTADB,
|
||||
LimboError::Constraint(_) => SQLITE_CONSTRAINT,
|
||||
LimboError::DatabaseFull(_) => SQLITE_FULL,
|
||||
LimboError::TableLocked => SQLITE_LOCKED,
|
||||
LimboError::ReadOnly => SQLITE_READONLY,
|
||||
LimboError::Busy => SQLITE_BUSY,
|
||||
_ => SQLITE_ERROR,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue