Merge 'core/pragma: Add support for update user_version' from Diego Reis

It also changes the type from u32 to i32 since
sqlite supports negative values

Closes #1559
This commit is contained in:
Jussi Saurio
2025-05-23 17:00:55 +03:00
4 changed files with 35 additions and 9 deletions

View File

@@ -170,7 +170,7 @@ Limbo aims to be fully compatible with SQLite, with opt-in features not supporte
| PRAGMA temp_store_directory | Not Needed | deprecated in SQLite |
| PRAGMA threads | No | |
| PRAGMA trusted_schema | No | |
| PRAGMA user_version | Partial | Only read implemented |
| PRAGMA user_version | Yes | |
| PRAGMA vdbe_addoptrace | No | |
| PRAGMA vdbe_debug | No | |
| PRAGMA vdbe_listing | No | |

View File

@@ -141,7 +141,7 @@ pub struct DatabaseHeader {
text_encoding: u32,
/// The "user version" as read and set by the user_version pragma.
pub user_version: u32,
pub user_version: i32,
/// True (non-zero) for incremental-vacuum mode. False (zero) otherwise.
incremental_vacuum_enabled: u32,
@@ -321,7 +321,7 @@ fn finish_read_database_header(
}
header.vacuum_mode_largest_root_page = u32::from_be_bytes([buf[52], buf[53], buf[54], buf[55]]);
header.text_encoding = u32::from_be_bytes([buf[56], buf[57], buf[58], buf[59]]);
header.user_version = u32::from_be_bytes([buf[60], buf[61], buf[62], buf[63]]);
header.user_version = i32::from_be_bytes([buf[60], buf[61], buf[62], buf[63]]);
header.incremental_vacuum_enabled = u32::from_be_bytes([buf[64], buf[65], buf[66], buf[67]]);
header.application_id = u32::from_be_bytes([buf[68], buf[69], buf[70], buf[71]]);
header.reserved_for_expansion.copy_from_slice(&buf[72..92]);

View File

@@ -142,8 +142,28 @@ fn update_pragma(
Ok(())
}
PragmaName::UserVersion => {
// TODO: Implement updating user_version
todo!("updating user_version not yet implemented")
let version_value = match value {
ast::Expr::Literal(ast::Literal::Numeric(numeric_value)) => {
numeric_value.parse::<i32>()?
}
ast::Expr::Unary(ast::UnaryOperator::Negative, expr) => match *expr {
ast::Expr::Literal(ast::Literal::Numeric(numeric_value)) => {
-numeric_value.parse::<i32>()?
}
_ => bail_parse_error!("Not a valid value"),
},
_ => bail_parse_error!("Not a valid value"),
};
let mut header_guard = header.lock();
// update in-memory
header_guard.user_version = version_value;
// update in disk
pager.write_database_header(&header_guard);
Ok(())
}
PragmaName::SchemaVersion => {
// TODO: Implement updating schema_version
@@ -286,14 +306,15 @@ fn update_cache_size(value: i64, header: Arc<SpinLock<DatabaseHeader>>, pager: R
cache_size_unformatted = MIN_PAGE_CACHE_SIZE as i64;
}
let mut header_guard = header.lock();
// update in-memory header
header.lock().default_page_cache_size = cache_size_unformatted
header_guard.default_page_cache_size = cache_size_unformatted
.try_into()
.unwrap_or_else(|_| panic!("invalid value, too big for a i32 {}", value));
// update in disk
let header_copy = header.lock().clone();
pager.write_database_header(&header_copy);
pager.write_database_header(&header_guard);
// update cache size
pager

View File

@@ -49,4 +49,9 @@ do_execsql_test_on_specific_db "testing/testing_user_version_10.db" pragma-user-
do_execsql_test_on_specific_db ":memory:" pragma-user-version-default {
PRAGMA user_version
} {0}
} {0}
do_execsql_test_on_specific_db ":memory:" pragma-user-version-update {
PRAGMA user_version = 42;
PRAGMA user_version;
} {42}